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. 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()
. What is meant to happen on each iteration of the loop?
Answer: You're missing currentpart = currentpart->next;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.