[英]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.