I have created a Snake console game using object-orientated programming methods. This is the first time I have ever used OOP so I just wanted to know if I was using the method correctly as well as hear any other advise I could possibly receive as this is my first time doing this. There are 4 header files and 4 .cpp files used.
Direction.h:
#pragma once
enum class Direction {
STOP = 0, UP, DOWN, LEFT, RIGHT
};
Food.h:
#pragma once
class Food{
private:
int foodX;
int foodY;
public:
Food(int x, int y);
Food();
int posX() { return foodX; };
int posY() { return foodY; };
void Refresh(int x, int y);
};
Food.cpp
#include "Food.h"
Food::Food(int x, int y)
{
foodX = x;
foodY = y;
}
Food::Food()
:foodX{ 2 }, foodY{ 2 }
{
}
void Food::Refresh(int x, int y)
{
foodX = x;
foodY = y;
}
Snake.h
#pragma once
#include "Direction.h"
class Snake{
private:
int headX;
int headY;
int length;
Direction dir;
public:
Snake(int x, int y);
Snake();
int posX() { return headX; };
int posY() { return headY; };
int len() { return length; };
void Update();
void Eat();
void Change_Dir(Direction direction);
};
Snake.cpp
#include "Snake.h"
Snake::Snake()
: headX{ 1 }, headY{ 1 }, length{ 1 }, dir{ Direction::STOP }
{
}
Snake::Snake(int x, int y)
: length{ 1 }, dir{ Direction::STOP }
{
headX = x;
headY = y;
}
void Snake::Update()
{
switch (dir) {
case(Direction::LEFT):
headX--;
break;
case(Direction::RIGHT):
headX++;
break;
case(Direction::UP):
headY--;
break;
case(Direction::DOWN):
headY++;
break;
case(Direction::STOP):
break;
}
}
void Snake::Eat()
{
length++;
}
void Snake::Change_Dir(Direction direction)
{
dir = direction;
}
Game.h
#pragma once
#include "Snake.h"
#include "Food.h"
#include <vector>
class Game {
private:
Snake snake;
Food food;
int board_height;
int board_width;
std::vector<int> Snake_Tail_X;
std::vector<int> Snake_Tail_Y;
void Snake_Tail_Update();
void Board_Colission();
void Snake_Colission();
void Eaten();
void Input_Check();
void Draw();
void Logic();
bool Game_Over;
public:
Game();
bool Game_State() { return Game_Over; };
void Play();
};
Game.cpp
#include "Game.h"
#include <iostream>
#include <conio.h>
Game::Game()
:snake{ 2, 5 }, food{ 5, 5 }, board_height{ 20 }, board_width{ 20 }, Game_Over{ false }, Snake_Tail_X{}, Snake_Tail_Y{}
{
}
void Game::Play()
{
Draw();
Logic();
}
void Game::Draw()
{
int i{ 0 }, j{ 0 }, k{ 0 };
system("cls");
for (i = 0; i < board_height; i++) {
for (j = 0; j < board_width; j++) {
if (j == snake.posX() && i == snake.posY())
std::cout << "O";
else if (j == food.posX() && i == food.posY())
std::cout << "F";
else if (i == 0 || j == 0 || i == board_height - 1 || j == board_width - 1)
std::cout << "#";
else{
bool tail = false;
for (k = 0; k < snake.len() - 1; k++) {
if (Snake_Tail_X[k] == j && Snake_Tail_Y[k] == i) {
std::cout << "o";
tail = true;
}
}
if(tail == false)
std::cout << " ";
}
}
std::cout << std::endl;
}
std::cout << "Score: " << snake.len()-1;
}
void Game::Logic()
{
Input_Check();
Snake_Tail_Update();
snake.Update();
Board_Colission();
Snake_Colission();
Eaten();
}
void Game::Snake_Tail_Update()
{
if (!Snake_Tail_X.empty()) {
int i{ 0 }, tempX{ 0 }, tempY{ 0 }, temp2X{ 0 }, temp2Y{ 0 };
tempX = Snake_Tail_X[0];
tempY = Snake_Tail_Y[0];
Snake_Tail_X[0] = snake.posX();
Snake_Tail_Y[0] = snake.posY();
for (i = 1; i < snake.len()-1; i++) {
temp2X = Snake_Tail_X[i];
temp2Y = Snake_Tail_Y[i];
Snake_Tail_X[i] = tempX;
Snake_Tail_Y[i] = tempY;
tempX = temp2X;
tempY = temp2Y;
}
}
}
void Game::Board_Colission(){
if (snake.posX() == 0 || snake.posX() == board_width-1 || snake.posY() == 0 || snake.posY() == board_height-1) {
Game_Over = true;
}
}
void Game::Snake_Colission()
{
int i{ 0 };
for (i = 0; i < snake.len() - 1; i++) {
if (snake.posX() == Snake_Tail_X[i] && snake.posY() == Snake_Tail_Y[i])
Game_Over = true;
}
}
void Game::Eaten()
{
if (snake.posX() == food.posX() && snake.posY() == food.posY()) {
food.Refresh(rand() % (board_width - 2) + 1, rand() % (board_height - 2) + 1);
snake.Eat();
Snake_Tail_X.push_back(1);
Snake_Tail_Y.push_back(1);
}
}
void Game::Input_Check(){
if (_kbhit()) {
switch(_getch()){
case('a'):
snake.Change_Dir(Direction::LEFT);
break;
case('d'):
snake.Change_Dir(Direction::RIGHT);
break;
case('w'):
snake.Change_Dir(Direction::UP);
break;
case('s'):
snake.Change_Dir(Direction::DOWN);
break;
default:
break;
}
}
}
Main.cpp
#include <iostream>
#include "Game.h"
int main()
{
Game game;
while (!game.Game_State()) {
game.Play();
}
return 0;
}
```