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