diff --git a/CMakeLists.txt b/CMakeLists.txt index 2be36482..56e1cbde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") find_package(SDL2 REQUIRED) include_directories(${SDL2_INCLUDE_DIRS} src) -add_executable(SnakeGame src/main.cpp src/game.cpp src/controller.cpp src/renderer.cpp src/snake.cpp) +add_executable(SnakeGame src/player.cpp src/main.cpp src/game.cpp src/controller.cpp src/renderer.cpp src/snake.cpp) string(STRIP ${SDL2_LIBRARIES} SDL2_LIBRARIES) -target_link_libraries(SnakeGame ${SDL2_LIBRARIES}) +target_link_libraries(SnakeGame ${SDL2_LIBRARIES} SDL2_image) diff --git a/README.md b/README.md index a3f6ebae..dbd94bf7 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,29 @@ In this project, you can build your own C++ application or extend this Snake gam 3. Compile: `cmake .. && make` 4. Run it: `./SnakeGame`. +## New features +* Enter player's name at the beginning and stored player's data, including name and score, in the file scoreboard.txt +* Pause game when pressing ESC button, after that select 1 of 2 options: resume or exit + +## Satified Requirements +1. Loop, Functions, I/O +* The project demonstrates an understanding of C++ functions and control structures. + * The project code is clearly organized into functions: All the added methods is written as functions +* The project reads data from a file and process the data, or the program writes data to a file. + * Project handles player's data and stores at in file scoreboard.txt +* The project accepts user input and processes the input. + * User enters player's name. +2. Object Oriented Programming +* The project uses Object Oriented Programming techniques. + * Class Player represents for player object +* Classes use appropriate access specifiers for class members. + * Create some set/get functions. For example: SetGameState(), GetCurrentState() +* Class constructors utilize member initialization lists. + * In class Player's constructor, initialize player name + * In renderer.cpp:40, initialize sdl_texture +3. Memory Management +* The project makes use of references in function declarations. + * In controller.cpp:15, pass game's reference to HandleInput() ## CC Attribution-ShareAlike 4.0 International diff --git a/pause_menu.png b/pause_menu.png new file mode 100644 index 00000000..cccda90a Binary files /dev/null and b/pause_menu.png differ diff --git a/src/controller.cpp b/src/controller.cpp index facba5b5..3f05e3c9 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -2,40 +2,67 @@ #include #include "SDL.h" #include "snake.h" +#include "game.h" void Controller::ChangeDirection(Snake &snake, Snake::Direction input, - Snake::Direction opposite) const { - if (snake.direction != opposite || snake.size == 1) snake.direction = input; - return; + Snake::Direction opposite) const +{ + if (snake.direction != opposite || snake.size == 1) + snake.direction = input; + return; } -void Controller::HandleInput(bool &running, Snake &snake) const { - SDL_Event e; - while (SDL_PollEvent(&e)) { - if (e.type == SDL_QUIT) { - running = false; - } else if (e.type == SDL_KEYDOWN) { - switch (e.key.keysym.sym) { - case SDLK_UP: - ChangeDirection(snake, Snake::Direction::kUp, - Snake::Direction::kDown); - break; - - case SDLK_DOWN: - ChangeDirection(snake, Snake::Direction::kDown, - Snake::Direction::kUp); - break; - - case SDLK_LEFT: - ChangeDirection(snake, Snake::Direction::kLeft, - Snake::Direction::kRight); - break; - - case SDLK_RIGHT: - ChangeDirection(snake, Snake::Direction::kRight, - Snake::Direction::kLeft); - break; - } +void Controller::HandleInput(Game &game, Snake &snake) const +{ + SDL_Event e; + while (SDL_PollEvent(&e)) + { + if (e.type == SDL_QUIT) + { + game.SetGameState(STOPPED); + } + else if (e.type == SDL_KEYDOWN) + { + switch (e.key.keysym.sym) + { + case SDLK_UP: + ChangeDirection(snake, Snake::Direction::kUp, + Snake::Direction::kDown); + break; + + case SDLK_DOWN: + ChangeDirection(snake, Snake::Direction::kDown, + Snake::Direction::kUp); + break; + + case SDLK_LEFT: + ChangeDirection(snake, Snake::Direction::kLeft, + Snake::Direction::kRight); + break; + + case SDLK_RIGHT: + ChangeDirection(snake, Snake::Direction::kRight, + Snake::Direction::kLeft); + break; + + case SDLK_ESCAPE: + game.SetGameState(PAUSED); + break; + + case SDLK_1: + if (PAUSED == game.GetCurrentState()) + { + game.SetGameState(RUNNING); + } + break; + + case SDLK_2: + if (PAUSED == game.GetCurrentState()) + { + game.SetGameState(STOPPED); + } + break; + } + } } - } } \ No newline at end of file diff --git a/src/controller.h b/src/controller.h index 2b5309cf..8d323812 100644 --- a/src/controller.h +++ b/src/controller.h @@ -3,13 +3,16 @@ #include "snake.h" -class Controller { - public: - void HandleInput(bool &running, Snake &snake) const; +class Game; - private: - void ChangeDirection(Snake &snake, Snake::Direction input, - Snake::Direction opposite) const; +class Controller +{ +public: + void HandleInput(Game &game, Snake &snake) const; + +private: + void ChangeDirection(Snake &snake, Snake::Direction input, + Snake::Direction opposite) const; }; #endif \ No newline at end of file diff --git a/src/game.cpp b/src/game.cpp index cc7d60f9..2ec53152 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -6,82 +6,116 @@ Game::Game(std::size_t grid_width, std::size_t grid_height) : snake(grid_width, grid_height), engine(dev()), random_w(0, static_cast(grid_width - 1)), - random_h(0, static_cast(grid_height - 1)) { - PlaceFood(); + random_h(0, static_cast(grid_height - 1)) +{ + PlaceFood(); } void Game::Run(Controller const &controller, Renderer &renderer, - std::size_t target_frame_duration) { - Uint32 title_timestamp = SDL_GetTicks(); - Uint32 frame_start; - Uint32 frame_end; - Uint32 frame_duration; - int frame_count = 0; - bool running = true; - - while (running) { - frame_start = SDL_GetTicks(); - - // Input, Update, Render - the main game loop. - controller.HandleInput(running, snake); - Update(); - renderer.Render(snake, food); - - frame_end = SDL_GetTicks(); - - // Keep track of how long each loop through the input/update/render cycle - // takes. - frame_count++; - frame_duration = frame_end - frame_start; - - // After every second, update the window title. - if (frame_end - title_timestamp >= 1000) { - renderer.UpdateWindowTitle(score, frame_count); - frame_count = 0; - title_timestamp = frame_end; - } + std::size_t target_frame_duration) +{ + Uint32 title_timestamp = SDL_GetTicks(); + Uint32 frame_start; + Uint32 frame_end; + Uint32 frame_duration; + int frame_count = 0; + + while ((state_ == RUNNING) || (state_ == PAUSED)) + { + frame_start = SDL_GetTicks(); + + // Input, Update, Render - the main game loop. + controller.HandleInput(*this, snake); + + // Display the pause menu + if (state_ == PAUSED) + { + renderer.UpdatePauseMenu(); + continue; + } + + Update(); + renderer.Render(snake, food); + + frame_end = SDL_GetTicks(); + + // Keep track of how long each loop through the input/update/render cycle + // takes. + frame_count++; + frame_duration = frame_end - frame_start; - // If the time for this frame is too small (i.e. frame_duration is - // smaller than the target ms_per_frame), delay the loop to - // achieve the correct frame rate. - if (frame_duration < target_frame_duration) { - SDL_Delay(target_frame_duration - frame_duration); + // After every second, update the window title. + if (frame_end - title_timestamp >= 1000) + { + renderer.UpdateWindowTitle(score, frame_count); + frame_count = 0; + title_timestamp = frame_end; + } + + // If the time for this frame is too small (i.e. frame_duration is + // smaller than the target ms_per_frame), delay the loop to + // achieve the correct frame rate. + if (frame_duration < target_frame_duration) + { + SDL_Delay(target_frame_duration - frame_duration); + } } - } } -void Game::PlaceFood() { - int x, y; - while (true) { - x = random_w(engine); - y = random_h(engine); - // Check that the location is not occupied by a snake item before placing - // food. - if (!snake.SnakeCell(x, y)) { - food.x = x; - food.y = y; - return; +void Game::PlaceFood() +{ + int x, y; + while (true) + { + x = random_w(engine); + y = random_h(engine); + // Check that the location is not occupied by a snake item before placing + // food. + if (!snake.SnakeCell(x, y)) + { + food.x = x; + food.y = y; + return; + } } - } } -void Game::Update() { - if (!snake.alive) return; +void Game::Update() +{ + if (!snake.alive) + return; - snake.Update(); + snake.Update(); - int new_x = static_cast(snake.head_x); - int new_y = static_cast(snake.head_y); + int new_x = static_cast(snake.head_x); + int new_y = static_cast(snake.head_y); - // Check if there's food over here - if (food.x == new_x && food.y == new_y) { - score++; - PlaceFood(); - // Grow snake and increase speed. - snake.GrowBody(); - snake.speed += 0.02; - } + // Check if there's food over here + if (food.x == new_x && food.y == new_y) + { + score++; + PlaceFood(); + // Grow snake and increase speed. + snake.GrowBody(); + snake.speed += 0.02; + } +} + +Game::~Game() +{ + player.SetScore(score); + player.SaveToScoreBoard(); } int Game::GetScore() const { return score; } -int Game::GetSize() const { return snake.size; } \ No newline at end of file +int Game::GetSize() const { return snake.size; } + +void Game::SetGameState(GameState newState) +{ + state_ = newState; +} + +GameState Game::GetCurrentState() +{ + return state_; +} \ No newline at end of file diff --git a/src/game.h b/src/game.h index 75554afe..a9d4daa2 100644 --- a/src/game.h +++ b/src/game.h @@ -6,28 +6,41 @@ #include "controller.h" #include "renderer.h" #include "snake.h" +#include "player.h" -class Game { - public: - Game(std::size_t grid_width, std::size_t grid_height); - void Run(Controller const &controller, Renderer &renderer, - std::size_t target_frame_duration); - int GetScore() const; - int GetSize() const; +typedef enum gameState { + STOPPED = 0, + RUNNING, + PAUSED, +} GameState; - private: - Snake snake; - SDL_Point food; +class Game +{ +public: + Game(std::size_t grid_width, std::size_t grid_height); + ~Game(); + void Run(Controller const &controller, Renderer &renderer, + std::size_t target_frame_duration); + int GetScore() const; + int GetSize() const; + void SetGameState(GameState newState); + GameState GetCurrentState(); - std::random_device dev; - std::mt19937 engine; - std::uniform_int_distribution random_w; - std::uniform_int_distribution random_h; +private: + Snake snake; + Player player; + SDL_Point food; - int score{0}; + std::random_device dev; + std::mt19937 engine; + std::uniform_int_distribution random_w; + std::uniform_int_distribution random_h; - void PlaceFood(); - void Update(); + int score{0}; + GameState state_{RUNNING}; + + void PlaceFood(); + void Update(); }; #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 01aaa03f..99a12a34 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,20 +3,21 @@ #include "game.h" #include "renderer.h" -int main() { - constexpr std::size_t kFramesPerSecond{60}; - constexpr std::size_t kMsPerFrame{1000 / kFramesPerSecond}; - constexpr std::size_t kScreenWidth{640}; - constexpr std::size_t kScreenHeight{640}; - constexpr std::size_t kGridWidth{32}; - constexpr std::size_t kGridHeight{32}; +int main() +{ + constexpr std::size_t kFramesPerSecond{60}; + constexpr std::size_t kMsPerFrame{1000 / kFramesPerSecond}; + constexpr std::size_t kScreenWidth{640}; + constexpr std::size_t kScreenHeight{640}; + constexpr std::size_t kGridWidth{32}; + constexpr std::size_t kGridHeight{32}; - Renderer renderer(kScreenWidth, kScreenHeight, kGridWidth, kGridHeight); - Controller controller; - Game game(kGridWidth, kGridHeight); - game.Run(controller, renderer, kMsPerFrame); - std::cout << "Game has terminated successfully!\n"; - std::cout << "Score: " << game.GetScore() << "\n"; - std::cout << "Size: " << game.GetSize() << "\n"; - return 0; + Renderer renderer(kScreenWidth, kScreenHeight, kGridWidth, kGridHeight); + Controller controller; + Game game(kGridWidth, kGridHeight); + game.Run(controller, renderer, kMsPerFrame); + std::cout << "Game has terminated successfully!\n"; + std::cout << "Score: " << game.GetScore() << "\n"; + std::cout << "Size: " << game.GetSize() << "\n"; + return 0; } \ No newline at end of file diff --git a/src/player.cpp b/src/player.cpp new file mode 100644 index 00000000..32cd31ee --- /dev/null +++ b/src/player.cpp @@ -0,0 +1,26 @@ +#include "player.h" +#include + +Player::Player() +{ + std::cout << "Enter the player name within 20 characters:\n"; + std::cin >> name; + name = name.substr(0, MAX_NAME_LEN); +} + +void Player::SetScore(int point) +{ + score = point; +} + +void Player::SaveToScoreBoard() +{ + std::ofstream file; + file.open("../scoreboard.txt", std::ios::app); + if (file.is_open()) + { + file << name << "\t" << score << std::endl; + } + + file.close(); +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 00000000..384be2c3 --- /dev/null +++ b/src/player.h @@ -0,0 +1,20 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include +#include + +#define MAX_NAME_LEN 20 + +class Player +{ +public: + Player(); + void SetScore(int point); + void SaveToScoreBoard(); +private: + std::string name{MAX_NAME_LEN, '\0'}; + int score{0}; +}; + +#endif /* PLAYER_H */ \ No newline at end of file diff --git a/src/renderer.cpp b/src/renderer.cpp index 1ca1c9f7..390809bd 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -8,74 +8,97 @@ Renderer::Renderer(const std::size_t screen_width, : screen_width(screen_width), screen_height(screen_height), grid_width(grid_width), - grid_height(grid_height) { - // Initialize SDL - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - std::cerr << "SDL could not initialize.\n"; - std::cerr << "SDL_Error: " << SDL_GetError() << "\n"; - } + grid_height(grid_height) +{ + // Initialize SDL + if (SDL_Init(SDL_INIT_VIDEO) < 0) + { + std::cerr << "SDL could not initialize.\n"; + std::cerr << "SDL_Error: " << SDL_GetError() << "\n"; + } - // Create Window - sdl_window = SDL_CreateWindow("Snake Game", SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, screen_width, - screen_height, SDL_WINDOW_SHOWN); + // Create Window + sdl_window = SDL_CreateWindow("Snake Game", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, screen_width, + screen_height, SDL_WINDOW_SHOWN); - if (nullptr == sdl_window) { - std::cerr << "Window could not be created.\n"; - std::cerr << " SDL_Error: " << SDL_GetError() << "\n"; - } + if (nullptr == sdl_window) + { + std::cerr << "Window could not be created.\n"; + std::cerr << " SDL_Error: " << SDL_GetError() << "\n"; + } - // Create renderer - sdl_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED); - if (nullptr == sdl_renderer) { - std::cerr << "Renderer could not be created.\n"; - std::cerr << "SDL_Error: " << SDL_GetError() << "\n"; - } + // Create renderer + sdl_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED); + if (nullptr == sdl_renderer) + { + std::cerr << "Renderer could not be created.\n"; + std::cerr << "SDL_Error: " << SDL_GetError() << "\n"; + } + + IMG_Init(IMG_INIT_PNG); + sdl_texture = IMG_LoadTexture(sdl_renderer, "../pause_menu.png"); } -Renderer::~Renderer() { - SDL_DestroyWindow(sdl_window); - SDL_Quit(); +Renderer::~Renderer() +{ + SDL_DestroyWindow(sdl_window); + SDL_DestroyTexture(sdl_texture); + IMG_Quit(); + SDL_DestroyRenderer(sdl_renderer); + SDL_Quit(); } -void Renderer::Render(Snake const snake, SDL_Point const &food) { - SDL_Rect block; - block.w = screen_width / grid_width; - block.h = screen_height / grid_height; +void Renderer::Render(Snake const snake, SDL_Point const &food) +{ + SDL_Rect block; + block.w = screen_width / grid_width; + block.h = screen_height / grid_height; + + // Clear screen + SDL_SetRenderDrawColor(sdl_renderer, 0x1E, 0x1E, 0x1E, 0xFF); + SDL_RenderClear(sdl_renderer); - // Clear screen - SDL_SetRenderDrawColor(sdl_renderer, 0x1E, 0x1E, 0x1E, 0xFF); - SDL_RenderClear(sdl_renderer); + // Render food + SDL_SetRenderDrawColor(sdl_renderer, 0xFF, 0xCC, 0x00, 0xFF); + block.x = food.x * block.w; + block.y = food.y * block.h; + SDL_RenderFillRect(sdl_renderer, &block); - // Render food - SDL_SetRenderDrawColor(sdl_renderer, 0xFF, 0xCC, 0x00, 0xFF); - block.x = food.x * block.w; - block.y = food.y * block.h; - SDL_RenderFillRect(sdl_renderer, &block); + // Render snake's body + SDL_SetRenderDrawColor(sdl_renderer, 0xFF, 0xFF, 0xFF, 0xFF); + for (SDL_Point const &point : snake.body) + { + block.x = point.x * block.w; + block.y = point.y * block.h; + SDL_RenderFillRect(sdl_renderer, &block); + } - // Render snake's body - SDL_SetRenderDrawColor(sdl_renderer, 0xFF, 0xFF, 0xFF, 0xFF); - for (SDL_Point const &point : snake.body) { - block.x = point.x * block.w; - block.y = point.y * block.h; + // Render snake's head + block.x = static_cast(snake.head_x) * block.w; + block.y = static_cast(snake.head_y) * block.h; + if (snake.alive) + { + SDL_SetRenderDrawColor(sdl_renderer, 0x00, 0x7A, 0xCC, 0xFF); + } + else + { + SDL_SetRenderDrawColor(sdl_renderer, 0xFF, 0x00, 0x00, 0xFF); + } SDL_RenderFillRect(sdl_renderer, &block); - } - // Render snake's head - block.x = static_cast(snake.head_x) * block.w; - block.y = static_cast(snake.head_y) * block.h; - if (snake.alive) { - SDL_SetRenderDrawColor(sdl_renderer, 0x00, 0x7A, 0xCC, 0xFF); - } else { - SDL_SetRenderDrawColor(sdl_renderer, 0xFF, 0x00, 0x00, 0xFF); - } - SDL_RenderFillRect(sdl_renderer, &block); + // Update Screen + SDL_RenderPresent(sdl_renderer); +} - // Update Screen - SDL_RenderPresent(sdl_renderer); +void Renderer::UpdateWindowTitle(int score, int fps) +{ + std::string title{"Snake Score: " + std::to_string(score) + " FPS: " + std::to_string(fps)}; + SDL_SetWindowTitle(sdl_window, title.c_str()); } -void Renderer::UpdateWindowTitle(int score, int fps) { - std::string title{"Snake Score: " + std::to_string(score) + " FPS: " + std::to_string(fps)}; - SDL_SetWindowTitle(sdl_window, title.c_str()); +void Renderer::UpdatePauseMenu() +{ + SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); + SDL_RenderPresent(sdl_renderer); } diff --git a/src/renderer.h b/src/renderer.h index fd28db2e..d84a9d88 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -3,25 +3,29 @@ #include #include "SDL.h" +#include "SDL_image.h" #include "snake.h" -class Renderer { - public: - Renderer(const std::size_t screen_width, const std::size_t screen_height, - const std::size_t grid_width, const std::size_t grid_height); - ~Renderer(); +class Renderer +{ +public: + Renderer(const std::size_t screen_width, const std::size_t screen_height, + const std::size_t grid_width, const std::size_t grid_height); + ~Renderer(); - void Render(Snake const snake, SDL_Point const &food); - void UpdateWindowTitle(int score, int fps); + void Render(Snake const snake, SDL_Point const &food); + void UpdateWindowTitle(int score, int fps); + void UpdatePauseMenu(); - private: - SDL_Window *sdl_window; - SDL_Renderer *sdl_renderer; +private: + SDL_Window *sdl_window; + SDL_Renderer *sdl_renderer; + SDL_Texture *sdl_texture; - const std::size_t screen_width; - const std::size_t screen_height; - const std::size_t grid_width; - const std::size_t grid_height; + const std::size_t screen_width; + const std::size_t screen_height; + const std::size_t grid_width; + const std::size_t grid_height; }; #endif \ No newline at end of file diff --git a/src/snake.cpp b/src/snake.cpp index b7f3c1bc..882be902 100644 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -2,78 +2,92 @@ #include #include -void Snake::Update() { - SDL_Point prev_cell{ - static_cast(head_x), - static_cast( - head_y)}; // We first capture the head's cell before updating. - UpdateHead(); - SDL_Point current_cell{ - static_cast(head_x), - static_cast(head_y)}; // Capture the head's cell after updating. +void Snake::Update() +{ + SDL_Point prev_cell{ + static_cast(head_x), + static_cast( + head_y)}; // We first capture the head's cell before updating. + UpdateHead(); + SDL_Point current_cell{ + static_cast(head_x), + static_cast(head_y)}; // Capture the head's cell after updating. - // Update all of the body vector items if the snake head has moved to a new - // cell. - if (current_cell.x != prev_cell.x || current_cell.y != prev_cell.y) { - UpdateBody(current_cell, prev_cell); - } + // Update all of the body vector items if the snake head has moved to a new + // cell. + if (current_cell.x != prev_cell.x || current_cell.y != prev_cell.y) + { + UpdateBody(current_cell, prev_cell); + } } -void Snake::UpdateHead() { - switch (direction) { +void Snake::UpdateHead() +{ + switch (direction) + { case Direction::kUp: - head_y -= speed; - break; + head_y -= speed; + break; case Direction::kDown: - head_y += speed; - break; + head_y += speed; + break; case Direction::kLeft: - head_x -= speed; - break; + head_x -= speed; + break; case Direction::kRight: - head_x += speed; - break; - } + head_x += speed; + break; + } - // Wrap the Snake around to the beginning if going off of the screen. - head_x = fmod(head_x + grid_width, grid_width); - head_y = fmod(head_y + grid_height, grid_height); + // Wrap the Snake around to the beginning if going off of the screen. + head_x = fmod(head_x + grid_width, grid_width); + head_y = fmod(head_y + grid_height, grid_height); } -void Snake::UpdateBody(SDL_Point ¤t_head_cell, SDL_Point &prev_head_cell) { - // Add previous head location to vector - body.push_back(prev_head_cell); +void Snake::UpdateBody(SDL_Point ¤t_head_cell, SDL_Point &prev_head_cell) +{ + // Add previous head location to vector + body.push_back(prev_head_cell); - if (!growing) { - // Remove the tail from the vector. - body.erase(body.begin()); - } else { - growing = false; - size++; - } + if (!growing) + { + // Remove the tail from the vector. + body.erase(body.begin()); + } + else + { + growing = false; + size++; + } - // Check if the snake has died. - for (auto const &item : body) { - if (current_head_cell.x == item.x && current_head_cell.y == item.y) { - alive = false; + // Check if the snake has died. + for (auto const &item : body) + { + if (current_head_cell.x == item.x && current_head_cell.y == item.y) + { + alive = false; + } } - } } void Snake::GrowBody() { growing = true; } // Inefficient method to check if cell is occupied by snake. -bool Snake::SnakeCell(int x, int y) { - if (x == static_cast(head_x) && y == static_cast(head_y)) { - return true; - } - for (auto const &item : body) { - if (x == item.x && y == item.y) { - return true; +bool Snake::SnakeCell(int x, int y) +{ + if (x == static_cast(head_x) && y == static_cast(head_y)) + { + return true; + } + for (auto const &item : body) + { + if (x == item.x && y == item.y) + { + return true; + } } - } - return false; + return false; } \ No newline at end of file diff --git a/src/snake.h b/src/snake.h index 8dce0d99..2b0998d3 100644 --- a/src/snake.h +++ b/src/snake.h @@ -4,37 +4,44 @@ #include #include "SDL.h" -class Snake { - public: - enum class Direction { kUp, kDown, kLeft, kRight }; - - Snake(int grid_width, int grid_height) - : grid_width(grid_width), - grid_height(grid_height), - head_x(grid_width / 2), - head_y(grid_height / 2) {} - - void Update(); - - void GrowBody(); - bool SnakeCell(int x, int y); - - Direction direction = Direction::kUp; - - float speed{0.1f}; - int size{1}; - bool alive{true}; - float head_x; - float head_y; - std::vector body; - - private: - void UpdateHead(); - void UpdateBody(SDL_Point ¤t_cell, SDL_Point &prev_cell); - - bool growing{false}; - int grid_width; - int grid_height; +class Snake +{ +public: + enum class Direction + { + kUp, + kDown, + kLeft, + kRight + }; + + Snake(int grid_width, int grid_height) + : grid_width(grid_width), + grid_height(grid_height), + head_x(grid_width / 2), + head_y(grid_height / 2) {} + + void Update(); + + void GrowBody(); + bool SnakeCell(int x, int y); + + Direction direction = Direction::kUp; + + float speed{0.1f}; + int size{1}; + bool alive{true}; + float head_x; + float head_y; + std::vector body; + +private: + void UpdateHead(); + void UpdateBody(SDL_Point ¤t_cell, SDL_Point &prev_cell); + + bool growing{false}; + int grid_width; + int grid_height; }; #endif \ No newline at end of file