Sunteți pe pagina 1din 5

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

S-ar putea să vă placă și