简体   繁体   English

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

[英]Snake game crashes after second fruit

I need to make a Snake game using lists and I think I have it pretty much done, but for whatever reason the game always crashes upon picking up the second fruit.我需要使用列表制作一个 Snake 游戏,我认为我已经完成了很多,但无论出于何种原因,游戏总是在拾取第二个水果时崩溃。 No game over or anything, it justs freezes after generating the third node.没有游戏结束或任何事情,它只是在生成第三个节点后冻结。 I already tried changing the program to work in different ways but no succes so far.我已经尝试将程序更改为以不同的方式工作,但到目前为止还没有成功。 Any suggestions are welcomed.欢迎任何建议。

Here's the main code:这是主要代码:

#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();
}

And the code for the double linked list i'm using我正在使用的双链表的代码

#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;
}

This would be a great reason to learn how to use a debugger.这将是学习如何使用调试器的一个很好的理由。 I ran your code under a debugger, and it took me exactly to where the problem is.我在调试器下运行了你的代码,它把我带到了问题所在。 It was almost like a giant red highlighter saying "HERE IS THE PROBLEM".这几乎就像一个巨大的红色荧光笔在说“这是问题所在”。

Hint: look at your while loop in the function Logic() .提示:查看 function Logic()中的while循环。 What is meant to happen on each iteration of the loop?循环的每次迭代意味着什么?

Answer: You're missing currentpart = currentpart->next;答案:您缺少currentpart = currentpart->next;

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

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