Skip to main content
Tweeted twitter.com/StackCodeReview/status/1026755273837473792
edited tags; edited title
Link
200_success
  • 145.7k
  • 22
  • 191
  • 481

How can I make my Snake game code more readable?for Windows text console

Source Link
user176662
user176662

How can I make my Snake game code more readable?

I have started to code Snake in C++. I am finding it hard to make progress on this project because the code is quite messy. How can I improve the structure of my program?

main.cpp:

#include <iostream>
#include "Game.h"

#define FRAMERATE 500

int main(void)
{
    Game game;

    int count = 0;

    while (game.program_is_running)
    {
        game.key_events();

        if (count >= FRAMERATE)
        {
            game.tick();
            count = 0;
        }
        else
            count++;
    }

    std::cout << "\nYou lose.\n";
    std::cin.get();

    return 0;
}

game.h:

#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <vector>

#include "Snake.h"

#define NUMBER_OF_ROWS 25
#define NUMBER_OF_COLUMNS 25

class Game
{
public:

    Game(void);

    void tick(void);
    void key_events(void);

    bool program_is_running;

private:

    char grid[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];

    Snake snake;
    Block apple;

    enum { right = 1, left, down, up };

    bool snake_is_touching_wall(void);
    void display_grid(void);
};

game.cpp:

#include <stdlib.h>
#include "Game.h"

Game::Game(void)
{
    for (int y = 0; y < NUMBER_OF_ROWS; y++)
    {
        for (int x = 0; x < NUMBER_OF_COLUMNS; x++)
        {
            if (y == 0 || y == NUMBER_OF_ROWS - 1)
                grid[y][x] = '#';
            else if (x == 0 || x == NUMBER_OF_COLUMNS - 1)
                grid[y][x] = '#';
            else
                grid[y][x] = ' ';
        }
    }

    apple.x = rand() % 25;
    apple.y = rand() % 25;

    program_is_running = true;
}

void Game::tick(void)
{
    for (int y = 0; y < NUMBER_OF_ROWS; y++)
    {
        for (int x = 0; x < NUMBER_OF_COLUMNS; x++)
        {
            if (y == 0 || y == NUMBER_OF_ROWS - 1)
                grid[y][x] = '#';
            else if (x == 0 || x == NUMBER_OF_COLUMNS - 1)
                grid[y][x] = '#';
            else
                grid[y][x] = ' ';
        }
    }

    std::vector<Block> snake_body = snake.get_body();

    if (snake.direction == right)
    {
        snake.move(0, 1);
    }
    else if (snake.direction == left)
    {
        snake.move(0, -1);
    }
    else if (snake.direction == down)
    {
        snake.move(1, 0);
    }
    else if (snake.direction == up)
    {
        snake.move(-1, 0);
    }

    for (int y = 0; y < NUMBER_OF_ROWS; y++)
    {
        for (int x = 0; x < NUMBER_OF_COLUMNS; x++)
        {
            if (y == apple.y && x == apple.x)
                grid[y][x] = '@';

            for (int i = 0; i < snake_body.size(); i++)
            {
                if (snake_body[i].y == y && snake_body[i].x == x)
                {
                    grid[y][x] = snake.get_symbol();
                }
            }
        }
    }

    display_grid();

    if (snake_is_touching_wall())
    {
        program_is_running = false;
    }
}

void Game::key_events(void)
{
    char c;

    if (_kbhit())
    {
        c = _getch();

        switch (c)
        {
        case 'q':
            program_is_running = false;
            break;

        case 'l':
            if(snake.direction != left)
                snake.direction = right;
            break;

        case 'j':
            if(snake.direction != right)
                snake.direction = left;
            break;

        case 'k':
            if(snake.direction != up)
                snake.direction = down;
            break;

        case 'i':
            if(snake.direction != down)
                snake.direction = up;
            break;
        }
    }
}

bool Game::snake_is_touching_wall(void)
{
    std::vector<Block> snake_body = snake.get_body();

    const int SNAKE_HEAD_X = snake_body[0].x;
    const int SNAKE_HEAD_Y = snake_body[0].y;

    return grid[SNAKE_HEAD_Y][SNAKE_HEAD_X] == '#';
}

void Game::display_grid(void)
{
    system("cls");

    for (int y = 0; y < NUMBER_OF_ROWS; y++)
    {
        for (int x = 0; x < NUMBER_OF_COLUMNS; x++)
        {
            std::cout << grid[y][x] << ' ';
        }

        std::cout << std::endl;
    }
}

snake.h:

#include <vector>

struct Block
{
    int y, x;
};

class Snake
{
public:

    Snake();

    std::vector<Block> get_body();
    char get_symbol(void);

    void add_block(int, int);
    void move(int, int);

    int direction;

private:

    std::vector<Block> body;
    char symbol;
};

snake.cpp:

#include "Snake.h"

Snake::Snake(void)
{
    symbol = 'X';
    direction = 0;
    add_block(12, 12);
}

std::vector<Block> Snake::get_body()
{
    return body;
}

char Snake::get_symbol(void)
{
    return symbol;
}

void Snake::add_block(int y, int x)
{
    Block block;
    block.y = y;
    block.x = x;
    body.push_back(block);
}

void Snake::move(int y, int x)
{
    body[0].y += y;
    body[0].x += x;
}