C++ Snake Game I Made in Class

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 5
At a glance
Powered by AI
The document describes a C++ implementation of a snake game including how the snake and board are represented, how the snake moves and grows by eating apples, and different conditions that end the game.

The snake game is represented using a 2D array (map) to store the state of each position on the board. Empty spaces are 0, apples are -1, and each segment of the snake is represented by a positive integer.

The snake moves by changing the x and y coordinates of its head based on the direction. Its body segments are shifted forward by incrementing their values in the map. When it eats an apple, its length increases by adding a new head segment.

// Snake game

#include <iostream>
#include <windows.h>
#include <math.h>

#define BOARD_SIZE_X 35
#define BOARD_SIZE_Y 20
#define GOAL_LEN 50
#define GAME_SPEED 500

using namespace std;

int debug =0; // debug var should be global

class Snake {
public:
Snake();
~Snake();

void Start(void);

private:
inline void Generate(void);

inline void Read(void);


inline void Move(void);
inline void Check(int,int);

inline void Draw(void);

char heading;
int len;
int x,y;
int **map;
};

/*
map decryption:
0 - empty space
(-1) - apple
1 - snake head
2,3,4.. - snake body
*/

////////////////////////////////////

Snake::Snake() {
heading = 'N';
len = 5;
x = (int)round((float)BOARD_SIZE_X/2);
y = (int)round((float)BOARD_SIZE_Y/2);

map = new int*[BOARD_SIZE_X];


for (int i=0;i<BOARD_SIZE_X;i++) {
map[i] = new int[BOARD_SIZE_Y];
};

int i; // to avoid generation inside loop


for (int j=0;j<BOARD_SIZE_Y;j++) {
for (i=0;i<BOARD_SIZE_X;i++) {
map[i][j] = 0;
}
};

map[x][y]=1; // head
};

Snake::~Snake() {
for (int i=0;i<BOARD_SIZE_Y;i++) {
delete[] map[i];
};
delete[] map;
};

////////////////////////////////////

void Snake::Start(void) {
this->Generate();
while (true) {
Sleep(GAME_SPEED);
this->Read();
this->Move();
this->Draw();
};
};

////

void Snake::Generate(void) {
int temp = rand() % (BOARD_SIZE_X * BOARD_SIZE_Y);
map[temp %BOARD_SIZE_X][(int)floor((float)(BOARD_SIZE_X*BOARD_SIZE_Y)/temp)]
= -1; // new apple
};

////

void Snake::Read(void) {
if (GetAsyncKeyState(38)) { //VK_UP
heading = 'N';
}
else if (GetAsyncKeyState(40)) { //VK_DOWN
heading = 'S';
}
else if (GetAsyncKeyState(37)) { //VK_LEFT
heading = 'W';
}
else if (GetAsyncKeyState(39)) { //VK_RIGHT
heading = 'E';
};
};

////

void Snake::Move(void) {
int i;
for (int j=0;j<BOARD_SIZE_Y;j++) {
for (i=0;i<BOARD_SIZE_X;i++) {
if (map[i][j]==len) {
map[i][j]=0;
}
else if (map[i][j]>0) {
map[i][j]+=1;
};
};
};

if (heading == 'N') { // faster execution than switchers


y-=1;
}
else if (heading == 'S') {
y+=1;
}
else if (heading == 'W') {
x-=1;
}
else if (heading == 'E') {
x+=1;
}
else throw 101;

Snake::Check(x,y);
};

////

void Snake::Check(int a, int b) {


if (x<0 or y<0 or x>=BOARD_SIZE_X or y>=BOARD_SIZE_Y) throw 203;

if (map[a][b]==-1) {
map[a][b]= 1;
this->len+=1;
if (this->len>GOAL_LEN-1) throw 201;
this->Generate();
} else if (map[a][b]>0) {
throw 202;
} else map[a][b]=1;
};

////

void Snake::Draw(void) {
system("cls");
if (debug==1) {
cout << "Snake's head position is (" << x << "," << y << ") and is
heading " << heading << endl;
};

cout << "Your Snake\'s size is " << this->len << " of " << GOAL_LEN << ".
Reach length of " << GOAL_LEN << " to win."<< endl;
for (int i=0;i<BOARD_SIZE_X+2;i++) {
cout << "=";
};
cout << endl;
int i;
for (int j=0;j<BOARD_SIZE_Y;j++) {
cout << "|";
for (i=0;i<BOARD_SIZE_X;i++) {
if (map[i][j]== -1) {
cout << "A";
}
else if (map[i][j]== 0) {
cout << " ";
}
else if (map[i][j]== 1) {
cout << "X";
}
else {
cout << "O";
};
};
cout << "|" <<endl;
};

for (int i=0;i<BOARD_SIZE_X+2;i++) {


cout << "=";
};
cout << endl;
};

////////////////////////////////////

int main(int argc, char** argv) {


if ((argc !=1 and argc != 2) or (argc == 2 and argv[1][0]!= 'd')) {
cout << "You can start game without parameters or by adding \"d\" tag
to start debug mode" << endl;
return 0;
};

if (argc == 2 and argv[1][0]== 'd') {


debug=1;
};

Snake someSnake;
try {
someSnake.Start();

}
catch (int e) {
switch (e) {
case 101:
cout << "Error! Unknown direction." << endl;
break;

case 201:
cout << "Congratulation! You've reached size of 100!";
break;
case 202:
cout << "You've lost! Never bite yourself..";
break;
case 203:
cout << "You've lost! You hit the wall..";
break;

default:
cout << "Unknown Error! Program execution stoped." << endl;
break;
};
};
return 0;
};

You might also like