繁体   English   中英

蛇游戏在第二个水果后崩溃

[英]Snake game crashes after second fruit

我需要使用列表制作一个 Snake 游戏,我认为我已经完成了很多,但无论出于何种原因,游戏总是在拾取第二个水果时崩溃。 没有游戏结束或任何事情,它只是在生成第三个节点后冻结。 我已经尝试将程序更改为以不同的方式工作,但到目前为止还没有成功。 欢迎任何建议。

这是主要代码:

#include <iostream>
#include "doubleLinked.cpp"
#include <conio.h>
#include <stdlib.h>
using namespace std;

bool GameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
snake s;

enum eDirection
{
    STOP = 0,
    UP,
    DOWN,
    RIGHT,
    LEFT
};
eDirection dir;

void setUp();
void Input();
void Logic();
void Draw();
bool findSegment(segment *front, int x, int y);
void update(int coordX, int coordY, segment *dl);
void DrawEnd();

int main()
{

    setUp();
    while (!GameOver)
    {
        Draw();
        Input();
        Logic();
        update(x, y, s.front);
        usleep(100000);
    }
    DrawEnd();

    return 0;
}

//Sets initial parameters
void setUp()
{
    GameOver = false;
    dir = STOP;
    x = width / 2;
    y = height / 2;
    fruitX = rand() % width;
    fruitY = rand() % height;
    pushBack(T(x, y), &s);
    score = 0;
}

//Gets input from user
void Input()
{
    if (_kbhit())
    {
        switch (_getche())
        {
        case 'a':
            if (dir != RIGHT)
            {
                dir = LEFT;
            }
            break;
        case 'd':
            if (dir != LEFT)
            {
                dir = RIGHT;
            }
            break;
        case 'w':
            if (dir != DOWN)
            {
                dir = UP;
            }
            break;
        case 's':
            if (dir != UP)
            {
                dir = DOWN;
            }
            break;
        case 'f':
            GameOver = true;
            break;
        }
    }
}

//Draws matrix, snake and fruit
void Draw()
{
    system("clear");            //("cls") for windows
    for (int i = 0; i < width + 2; i++) 
        cout << "*";
    cout << endl;
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++) 
        {
            if (j == 0)
                cout << "*";
            if (i == s.front->info.coordinateY && j == s.front->info.coordinateX)
                cout << "O"; //head
            else if (i == fruitY && j == fruitX)
                cout << "^"; //fruit
            else
            {
                bool isSegment;
               
                if (s.front->next)
                {
                    isSegment = findSegment(s.front->next, j, i);
                }
                if (isSegment)
                {
                    cout << "o";//body part
                }
                else
                {
                    cout << " ";
                }
            }

            if (j == width - 1)
                cout << "*";
        }
        cout << endl;
    }
    for (int i = 0; i < width + 2; i++) 
        cout << "*";
    cout << endl;
    cout << "Score: " << score << endl;

//Coordinates for testing
    cout << s.front->info.coordinateX << endl;
    cout << s.front->info.coordinateY << endl;
    if (s.front->next)
    {
        cout << s.front->next->info.coordinateX << endl;
        cout << s.front->next->info.coordinateY << endl;
        if (s.front->next->next)
        {
            cout << s.front->next->next->info.coordinateX << endl;
            cout << s.front->next->next->info.coordinateY;
        }
    }
}

void Logic()
{

    switch (dir) //Updates current head coordinates
    {
    case LEFT:
        x--;
        break;
    case RIGHT:
        x++;
        break;
    case UP:
        y--;
        break;
    case DOWN:
        y++;
        break;
    default:
        break;
    }
//Collisions
    if (x > width || x < 0 || y > height || y < 0)
        GameOver = true; //Se finaliza el juego si topa en una pared :v

    if (s.front->next)
    {
        segment *currentpart = s.front->next;
        while (currentpart->next)
        {
            if (currentpart->info.coordinateX == x && currentpart->info.coordinateY == y)
                GameOver = true;
        }
    }

//Snake picks up fruit and a segment is added
    if (x == fruitX && y == fruitY)
    {
        score += 20; 
        fruitX = rand() % width;
        fruitY = rand() % height;
        int lastx = s.back->info.coordinateX;
        int lasty = s.back->info.coordinateY;
        pushBack(T(lastx, lasty), &s);
    }
}

//True if there's a segment in the coordinates
bool findSegment(segment *front, int x, int y)
{
    if (front->info.coordinateX == x && front->info.coordinateY == y)
    {
        return 1;
    }
    else if (front->next)
    {
        return findSegment(front->next, x, y);
    }
    else
    {
        return 0;
    }
}

//Updates coordinates for all segments
void update(int coordX, int coordY, segment *dl)
{

    int prevX = dl->info.coordinateX;
    int prevY = dl->info.coordinateY;
    dl->info.coordinateX = coordX;
    dl->info.coordinateY = coordY;
    if (dl->next)
    {
        update(prevX, prevY, dl->next);
    }
}

//Game over screen
void DrawEnd()
{

    system("clear"); //cls en windows
    cout << "##############################" << endl;
    cout << "#                            #" << endl;
    cout << "#   ####  ####  #####  ###   #" << endl;
    cout << "#   #  #  #  #  # # #  #     #" << endl;
    cout << "#   #     ####  # # #  ###   #" << endl;
    cout << "#   # ##  #  #  # # #  #     #" << endl;
    cout << "#   #  #  #  #  # # #  #     #" << endl;
    cout << "#   ####  #  #  # # #  ###   #" << endl;
    cout << "#                            #" << endl;
    cout << "#   ####  #   #  ###  ####   #" << endl;
    cout << "#   #  #  #   #  #    #  #   #" << endl;
    cout << "#   #  #  ## ##  ###  ####   #" << endl;
    cout << "#   #  #   # #   #    # #    #" << endl;
    cout << "#   #  #   ###   #    # ##   #" << endl;
    cout << "#   ####    #    ###  #  #   #" << endl;
    cout << "#                            #" << endl;
    cout << "##############################" << endl;
    cout << "Puntaje: " << score << endl;
    cin.get();
}

我正在使用的双链表的代码

#include <iostream>
using namespace std;

typedef struct segmentInfo
{
    int coordinateX;
    int coordinateY;

    segmentInfo() {}
    segmentInfo(int _coordinateX, char _coordinateY) : coordinateX(_coordinateX), coordinateY(_coordinateY) {}

} T;

// Struct with ref to next and prev segments
struct segment
{
    T info;
    segment *prev, *next;
};

// Struct with front and back elements
struct snake
{
    segment *front, *back;

    snake()
    {
        front = back = NULL;
    }
};


void pushBack(T info, snake *dl)
{
    segment *n = new segment;
    n->info = info;
    n->next = NULL;

    // Same as push front
    if (!dl->front)
    {
        dl->front = dl->back = n;
        n->prev = n->next = NULL;

        return;
    }

  
    n->prev = dl->back;
    dl->back->next = n;
    dl->back = n;
}

这将是学习如何使用调试器的一个很好的理由。 我在调试器下运行了你的代码,它把我带到了问题所在。 这几乎就像一个巨大的红色荧光笔在说“这是问题所在”。

提示:查看 function Logic()中的while循环。 循环的每次迭代意味着什么?

答案:您缺少currentpart = currentpart->next;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM