Witam wszystkich serdecznie. Napisałem swój pierwszy mały projekt orientowany obiektowo. Jest to popularna gra snake. Krótki opis gry:
- losuje nam położenie głowy węża na planszy
- losuje nam położenie muchy na planszy
- chodzimy w 4 kierunkach głową węża
- gdy zjemy muchę rośniemy
- gdy urośniemy możemy poruszać się tylko w 3 kierunkach bo wąż nie chodzi w tył
- gdy wejdziemy na ścianę lub zjemy sami siebie umieramy i kończymy grę
Grę napisałem na podstawie dwóch klas:
- Wall - obrazuje planszę gry
- Snake - obrazuje węża. Dodatkowo ta klasa dziedziczy w sposób protected po klasie Wall.
Chciałbym prosić o opinię i konstruktywną krytykę mojego kodu.
#include <iostream>
#include <cstdio>
#include <conio.h>
#include "Wall.h"
#include "Snake.h"
using namespace std;
int main()
{
Wall wall;
Snake snake;
snake.go();
wall.~Wall();
cout << "KONIRC GRY" << endl;
getch();
return 0;
}
#ifndef WALL_H
#define WALL_H
class Wall
{
public:
Wall();
~Wall();
protected:
bool play;
static const unsigned int SIZE = 20; //map size
char tab[SIZE][SIZE]; //map
char vac; //empty space
char brick; //edge of the map
void draw(); //draws current state on the map
private:
};
#endif // WALL_H
#include "Wall.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
Wall::Wall()
{
play = true; //game started
brick = '#'; //wall
vac = ' '; //empty space
//first line
for(unsigned int i=0; i<SIZE; i++)
tab[0][i] = brick;
//center empty
for(unsigned int i=1; i<SIZE-1; i++)
for(unsigned int j=1; j<SIZE-1; j++)
tab[i][j] = vac;
//first and last element of line(1 to SIZE-1)
for(unsigned int i=1; i<SIZE-1; i++)
{
tab[i][0] = brick;
tab[i][SIZE-1] = brick;
}
//last line
for(unsigned int i=0; i<SIZE; i++)
tab[SIZE-1][i] = brick;
}
Wall::~Wall()
{
system("cls");
}
void Wall::draw() //draws current state on the map
{
for(unsigned int i=0; i<SIZE; i++)
{
for(unsigned int j=0; j<SIZE; j++)
cout << tab[i][j];
cout << endl;
}
}
#ifndef SNAKE_H
#define SNAKE_H
#include "Wall.h"
class Snake :protected Wall
{
public:
void go();
Snake();
protected:
private:
char rep; //reptile - snake
char fly;
unsigned int x; //x-coordinate of the head snake
unsigned int y; //y-coordinate of the head snake
static const unsigned int S = 99999;
unsigned int tab_x[S]; //a table x-coordinate for storing previous positions of head snake
unsigned int tab_y[S]; //a table y-coordinate for storing previous positions of head snake
unsigned int length; //length of snake
unsigned int counter; //counter of snake movements
void random(char check, char Assign);
void crawl(char dir);
char select_direction_4();
char select_direction_3(int one, int two, int there);
void check();
void get_fly();
};
#endif // SNAKE_H
#include "Snake.h"
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <conio.h>
Snake::Snake()
{
srand(time(NULL));
length= 1 ;
counter = 0;
rep = 'o';
fly = '*';
int how_many = Wall::SIZE-2;
x = (rand()%how_many)+1; //random x-coordinate head of snake
y = (rand()%how_many)+1; //random y-coordinate head of snake
Wall::tab[x][y] = rep;
tab_x[0] = x;
tab_y[0] = y;
get_fly(); //random fly
Wall::draw();
}
void Snake::go()
{
char dire; //stores the direction of the previous movement
int one, two, there; //help variables
while(play and length == 1) //the possibility of moving in 4 directions
{
dire = select_direction_4();
crawl(dire); //make a move
}
while(play) //the possibility of moving in 3 directions, because the snake is not backward
{
switch(dire) //change possible directions
{
case 72: //up
{
one = 72;
two = 75;
there = 77;
break;
}
case 80: //down
{
one = 80;
two = 75;
there = 77;
break;
}
case 75: //up
{
one = 72;
two = 75;
there = 80;
break;
}
case 77: //up
{
one = 72;
two = 80;
there = 77;
break;
}
}
dire = select_direction_3(one, two, there);
crawl(dire); //make a move
}
}
void Snake::crawl(char dir)
{
switch(dir)
{
case 72: //up
{
x--;
break;
}
case 80: //down
{
x++;
break;
}
case 75: //left
{
y--;
break;
}
case 77: //rigth
{
y++;
break;
}
}
check(); //check if terminate a game
if(!play) return;
counter++;
tab_x[counter] = x;
tab_y[counter] = y;
bool random_fly = false;
if(Wall::tab[x][y] == fly) //if you eat a fly
{
length++;
random_fly = true;
}
Wall::tab[x][y] = rep;
//The following lines serve to clean the end of snake
int index = counter-length;
int xx = tab_x[index];
int yy = tab_y[index];
Wall::tab[xx][yy] = Wall::vac;
/////////////////////////////////////////////////////
if(random_fly) //if you eat a fly
get_fly();
system("cls");
Wall::draw();
}
char Snake::select_direction_4()
{
char dir;
do
{
dir = getch();
}
while(dir != 72 and dir != 80 and dir != 75 and dir != 77);
return dir;
}
char Snake::select_direction_3(int one, int two, int there)
{
char dir;
do
{
dir = getch();
}
while(dir != one and dir != two and dir != there);
return dir;
}
void Snake::check() //check if terminate a game
{
if(tab[x][y] == brick or tab[x][y] == rep)
play=false;
}
void Snake::get_fly() //random a fly
{
srand(time(NULL));
int how_many = Wall::SIZE-2;
int x_fly, y_fly;
do
{
x_fly = (rand()%how_many)+1;
y_fly = (rand()%how_many)+1;
}
while(Wall::tab[x_fly][y_fly] != vac);
Wall::tab[x_fly][y_fly] = fly;
}