Игра змейка, созданная с нуля

Я решил сделать игру-змейку своим первым проектом на C ++ (с использованием ООП), и я не следил ни за одним обучающим курсом, пока делал это, теперь я разочарован и мне нужно знать, хороший это код или нет и что можно улучшить в этом?

Заголовочный файл класса карты:

#pragma once
#include <vector>
#include <iostream>
#include "Snake.h"
#include "Wall.h"
#include "Food.h"

class Map
{
public: 
    void display_map(Snake& snake, Wall& wall, Food& food);
};

Исходный файл класса карты:

#include "Map.h"

void Map :: display_map(Snake& snake, Wall& wall, Food& food)
{
    system("cls");
    for (int i = 0; i < wall.get_height(); i++)
    {
        for (int j = 0; j < wall.get_width(); j++)
        {
            vector<int> temp = { j,i };
            int flag = 1;

            {
                for (auto& elm : snake.coor)
                {
                    if (elm[0] == j && elm[1] == i)
                    {
                        for (auto& elm1 : snake.body)
                        {
                            if (elm1.pos == elm)
                            {
                                cout << elm1.symbol;
                                j++;
                            }
                        }
                    }
                }
            }

            if (food.pos[0] == j && food.pos[1] == i)cout << food.symbol;
            else if ((i == 0 || i == wall.get_height() - 1) || (j == 0 || j == wall.get_width() - 2))
            {
                for (int k = 0; k < wall.wall_coor.size(); k++)
                {
                    if (wall.wall_coor[k] == temp)
                    {
                        flag = 0;
                    }

                }

                if (flag == 1)
                    wall.wall_coor.push_back(temp);

                cout << wall.get_symbol();
            }
            else cout << " ";

        }
        cout << endl;
    }

}

Заголовочный файл класса Snake:

#pragma once
#include <vector>
#include <conio.h>

using namespace std;
class Snake
{
//Attributes
public:

    struct Body
    {
        char symbol;
        vector <int> pos;
    };
    vector <vector<int>> coor;
    vector <Body> body;
    int dir = 1;
    
//Behaviors
    void add_to_body(char ch, int x, int y);
    int change_dir();
    
    
//Constructor
    Snake(char ch="X", int x = 40, int y = 10);
};

Исходный файл класса Snake:

#include "Snake.h"

void Snake :: add_to_body(char ch, int x, int y)
{
    Body temp;
    temp.symbol = ch;
    temp.pos = { x,y };
    coor.push_back(temp.pos);
    body.push_back(temp);
}

int Snake :: change_dir()
{
    switch (_getch())
    {
    case 'w':
        dir = 1;
        return dir;
        break;
    case 'a':
        dir = 2;
        return dir;
        break;
    case 's':
        dir = 3;
        return dir;
        break;
    case 'd':
        dir = 4;
        return dir;
        break;
    default:;

    }
}

Snake :: Snake(char ch , int x , int y)
{
    add_to_body(ch, x, y);
    add_to_body('o', x, y + 1);
    add_to_body('o', x, y + 2);
    add_to_body('o', x, y + 3);
    add_to_body('o', x, y + 4);
};

Заголовочный файл класса еды:

#pragma once
#include <vector>
#include <ctime>

using namespace std;

class Food
{
public:
    //Attributes
    char symbol="@";
    vector <int> pos;


    //Behavior
    vector <int> generate_food_x_y_coordinates(int x, int y);


    //Constructor
    Food(char symbol="@", vector<int> position = { 78,4 });

};

Исходный файл класса еды:

#include "Food.h"

vector <int> Food :: generate_food_x_y_coordinates(int x, int y)
{
    srand(time(NULL));
    vector <int> position = {(rand() * 2 % (x-4)) + 2   , (rand() * 2 % (y - 4)) + 2 };
    return position;
}

Food :: Food(char symbol, vector<int> position )
    :symbol{ symbol }, pos{ position } {};

Заголовочный файл класса стены:

#pragma once
#include <vector>

using namespace std;

class Wall
{
    char symbol;
    int width;
    int height;


public:
    vector <vector<int>> wall_coor = { {0,0} };

    int get_width()
    {
        return width;
    }
    int get_height()
    {
        return height;
    }

    char get_symbol()
    {
        return symbol;
    }

    Wall(char wall="https://codereview.stackexchange.com/questions/259332/#", int width = 81, int height = 21)
        :symbol{ wall }, width{ width }, height{ height }{}

};

По какой-то причине я решил обернуть весь класс стены в файл заголовка, потому что в поведении класса не так уж много; только функции получения.

Ну наконец то:

Основная функция (игровая логика):

#include "Map.h"
#include "Snake.h"
#include "Wall.h"
#include "Food.h"

using namespace std;

void main()
{
    bool game_over = false;
    Snake snake ('X' , 78 , 12);
    Wall wall("https://codereview.stackexchange.com/questions/259332/#", 82, 22);
    Food food('@');
    Map map;

    while (!game_over)
    {
        if (_kbhit())
            snake.change_dir();

        switch (snake.dir)
        {
        case 1:

            while (!_kbhit())
            {

                for (int i = snake.coor.size() - 1; i >= 0; i--)
                {
                    if (i - 1 >= 0)
                        snake.coor[i] = snake.coor[i - 1];
                    else if (i == 0)
                        snake.coor[0][1]--;
                }

                for (int j = 0; j < snake.body.size(); j++)
                {
                    snake.body[j].pos = snake.coor[j];
                }

                for (int k = 0; k < wall.wall_coor.size(); k++)
                {
                    if (snake.coor[0] != wall.wall_coor[k])
                    {
                        continue;
                    }
                    else if (snake.coor[0] == wall.wall_coor[k])
                    {
                        game_over = true;
                        break;
                    }
                    break;
                }

                for (int k = 1; k < snake.coor.size(); k++)
                {
                    if (snake.coor[0] != snake.coor[k])
                    {
                        continue;
                    }
                    else if (snake.coor[0] == snake.coor[k])
                    {
                        game_over = true;
                        break;
                    }
                    break;
                }

                if (snake.coor[0] == food.pos)
                {
                    food.pos = food.generate_food_x_y_coordinates(wall.get_width(), wall.get_height() );
                    snake.add_to_body('o', snake.coor.back()[0] , snake.coor.back()[1]);
                }
                else
                {
                    food.pos = food.pos;
                }

                map.display_map(snake, wall, food);
            }

            if (snake.change_dir() == 3)
            {
                snake.dir = 1;
                continue;
            }

            break;

        case 2:
            while (!_kbhit())
            {
                for (int i = snake.coor.size() - 1; i >= 0; i--)
                {
                    if (i - 1 >= 0)
                        snake.coor[i] = snake.coor[i - 1];
                    else if (i == 0)
                        snake.coor[0][0] -= 2;
                }

                for (int j = 0; j < snake.body.size(); j++)
                {
                    snake.body[j].pos = snake.coor[j];
                }

                for (int k = 0; k < wall.wall_coor.size(); k++)
                {
                    if (snake.coor[0] != wall.wall_coor[k])
                    {
                        continue;
                    }
                    else if (snake.coor[0] == wall.wall_coor[k])
                    {
                        game_over = true;
                        break;
                    }
                    break;
                }

                for (int k = 1; k < snake.coor.size(); k++)
                {
                    if (snake.coor[0] != snake.coor[k])
                    {
                        continue;
                    }
                    else if (snake.coor[0] == snake.coor[k])
                    {
                        game_over = true;
                        break;
                    }
                    break;
                }

                if (snake.coor[0] == food.pos)
                {
                    food.pos = food.generate_food_x_y_coordinates(wall.get_width() - 4, wall.get_height() - 4);
                    snake.add_to_body('o', snake.coor.back()[0] , snake.coor.back()[1] );
                }
                else
                {
                    food.pos = food.pos;
                }

                map.display_map(snake, wall, food);
            }

            if (snake.change_dir() == 4)
            {
                snake.dir = 2;
                continue;
            }

            
            break;
        case 3:
            while (!_kbhit())
            {
                for (int i = snake.coor.size() - 1; i >= 0; i--)
                {
                    if (i - 1 >= 0)
                        snake.coor[i] = snake.coor[i - 1];
                    else if (i == 0)
                        snake.coor[i][1]++;
                }
                for (int j = 0; j < snake.body.size(); j++)
                {
                    snake.body[j].pos = snake.coor[j];
                }

                for (int k = 0; k < wall.wall_coor.size(); k++)
                {
                    if (snake.coor[0] != wall.wall_coor[k])
                    {
                        continue;
                    }
                    else if (snake.coor[0] == wall.wall_coor[k])
                    {
                        game_over = true;
                        break;
                    }
                    break;
                }

                for (int k = 1; k < snake.coor.size(); k++)
                {
                    if (snake.coor[0] != snake.coor[k])
                    {
                        continue;
                    }
                    else if (snake.coor[0] == snake.coor[k])
                    {
                        game_over = true;
                        break;
                    }
                    break;
                }

                if (snake.coor[0] == food.pos)
                {
                    food.pos = food.generate_food_x_y_coordinates(wall.get_width() - 4, wall.get_height() - 4);
                    snake.add_to_body('o', snake.coor.back()[0] , snake.coor.back()[1]);
                }
                else
                {
                    food.pos = food.pos;
                }

                map.display_map(snake, wall, food);
            }



            if (snake.change_dir() == 1)
            {
                snake.dir = 3;
                continue;
            }

            break;

        case 4:

            while (!_kbhit())
            {
                for (int i = snake.coor.size() - 1; i >= 0; i--)
                {
                    if (i - 1 >= 0)
                        snake.coor[i] = snake.coor[i - 1];
                    else if (i == 0)
                    {
                        snake.coor[i][0] += 2;
                    }
                }

                for (int j = 0; j < snake.body.size(); j++)
                {
                    snake.body[j].pos = snake.coor[j];
                }

                for (int k = 0; k < wall.wall_coor.size(); k++)
                {
                    if (snake.coor[0] != wall.wall_coor[k])
                    {
                        continue;
                    }
                    else if (snake.coor[0] == wall.wall_coor[k])
                    {
                        game_over = true;
                        break;
                    }
                    break;
                }

                for (int k = 1; k < snake.coor.size(); k++)
                {
                    if (snake.coor[0] != snake.coor[k])
                    {
                        continue;
                    }
                    else if (snake.coor[0] == snake.coor[k])
                    {
                        game_over = true;
                        break;
                    }
                    break;
                }

                if (snake.coor[0] == food.pos)
                {
                    food.pos = food.generate_food_x_y_coordinates(wall.get_width() - 4, wall.get_height() - 4);
                    snake.add_to_body('o',snake.coor.back()[0]  , snake.coor.back()[1] );
                }
                else
                {
                    food.pos = food.pos;
                }

                map.display_map(snake, wall, food);
            }

            if (snake.change_dir() == 2)
            {
                snake.dir = 4;
            }

            break;
    }
        
    }
    
    system("pause");
}

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *