From c71b1d6982cb67056e466084c37a0031104e55ee Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Thu, 10 Aug 2023 18:47:40 -0500 Subject: [PATCH 1/9] Added ability to play again --- src/gamestate.cpp | 3 ++- src/playerinterface.cpp | 2 +- src/snake.cpp | 5 +++++ src/snake.hpp | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 51a5470..dee0df1 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -31,6 +31,8 @@ namespace snakeplusplus if (isGameOver) { graphics.CheckContinue(); + player.Reset(); + PrepareGameBoard(); isGameOver = 0; } UpdatePlayerSpeed(); @@ -69,7 +71,6 @@ namespace snakeplusplus player.Pop(); } catch (const std::out_of_range& error) { isGameOver = true; // Snake ran into edge - exit(0); } } diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index 8e297d4..c2465ce 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -66,7 +66,7 @@ namespace snakeplusplus textPosition.y = textPosition.y / 2; sf::Font font; font.loadFromFile("Arial.ttf"); - sf::Text gameOverText("Game Over", font); + sf::Text gameOverText("Game Over\nPress 'Enter' to play again", font); gameOverText.setPosition(textPosition); gameWindow.draw(gameOverText); gameWindow.display(); diff --git a/src/snake.cpp b/src/snake.cpp index 8de60c0..9871cb5 100755 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -14,6 +14,11 @@ namespace snakeplusplus body.pop(); } + void Snake::Reset(void) + { + while (!body.empty()) Pop(); + } + Food::Food(void) { generator.seed(std::random_device{}()); diff --git a/src/snake.hpp b/src/snake.hpp index 3ed81ea..01392cf 100755 --- a/src/snake.hpp +++ b/src/snake.hpp @@ -17,6 +17,7 @@ namespace snakeplusplus sf::Vector2f speed; std::queue body; void Pop(void); + void Reset(void); }; struct Food From d83f271adfb9b63eb86cc39bce0f0861143b7f33 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Mon, 14 Aug 2023 17:39:04 -0500 Subject: [PATCH 2/9] Fixed snake keeping movement on reset --- src/gamestate.cpp | 3 +-- src/gamestate.hpp | 1 - src/playerinterface.cpp | 17 ++++++----------- src/playerinterface.hpp | 9 +-------- src/snake.cpp | 2 ++ 5 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index dee0df1..2201ad8 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -110,8 +110,7 @@ namespace snakeplusplus void GameEngine::UpdatePlayerSpeed(void) { - PlayerDirection input = controls.GetPlayerInput(); - switch (input) { + switch (GetPlayerInput()) { case kUp: player.speed.x = 0; player.speed.y = -1; diff --git a/src/gamestate.hpp b/src/gamestate.hpp index 238aa4b..19ce5e1 100755 --- a/src/gamestate.hpp +++ b/src/gamestate.hpp @@ -17,7 +17,6 @@ namespace snakeplusplus sf::Vector2f GetGameBoundaries(void); private: std::vector< std::vector > gameBoard; - PlayerInput controls; PlayerOutput graphics; Snake player; Food playerFood; diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index c2465ce..f5ea26d 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -5,22 +5,17 @@ namespace snakeplusplus { - PlayerInput::PlayerInput(void) - { - lastPlayerInput = kNone; - } - - PlayerDirection PlayerInput::GetPlayerInput(void) + PlayerDirection GetPlayerInput(void) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) - lastPlayerInput = kLeft; + return kLeft; if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) - lastPlayerInput = kUp; + return kUp; if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) - lastPlayerInput = kDown; + return kDown; if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) - lastPlayerInput = kRight; - return lastPlayerInput; + return kRight; + return kNone; } bool PlayerOutput::IsOpen(void) diff --git a/src/playerinterface.hpp b/src/playerinterface.hpp index f4267ca..26e12f5 100755 --- a/src/playerinterface.hpp +++ b/src/playerinterface.hpp @@ -8,14 +8,7 @@ const int kGridSize = 25; namespace snakeplusplus { - class PlayerInput - { - public: - PlayerInput(void); - PlayerDirection GetPlayerInput(void); - private: - PlayerDirection lastPlayerInput; - }; + PlayerDirection GetPlayerInput(void); class PlayerOutput { diff --git a/src/snake.cpp b/src/snake.cpp index 9871cb5..c0dec4b 100755 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -17,6 +17,8 @@ namespace snakeplusplus void Snake::Reset(void) { while (!body.empty()) Pop(); + speed.x = 0; + speed.y = 0; } Food::Food(void) From 35244daa02b32c9d7901ec8b2fbcfb8e4dff3a47 Mon Sep 17 00:00:00 2001 From: Trimutex Date: Fri, 18 Aug 2023 16:42:54 -0500 Subject: [PATCH 3/9] Removed unnecessary standard libraries --- src/gamestate.cpp | 3 --- src/gamestate.hpp | 1 - src/playerinterface.cpp | 2 -- src/snake.cpp | 2 -- src/snake.hpp | 2 -- 5 files changed, 10 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 2201ad8..74aa232 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -1,8 +1,5 @@ // GameState.cpp -#include -#include #include -#include #include #include "common.hpp" #include "playerinterface.hpp" diff --git a/src/gamestate.hpp b/src/gamestate.hpp index 19ce5e1..91b2af1 100755 --- a/src/gamestate.hpp +++ b/src/gamestate.hpp @@ -2,7 +2,6 @@ #ifndef GAMESTATE_HPP #define GAMESTATE_HPP -#include #include #include "snake.hpp" #include "playerinterface.hpp" diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index f5ea26d..2c95059 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -1,7 +1,5 @@ #include "playerinterface.hpp" #include -#include -#include namespace snakeplusplus { diff --git a/src/snake.cpp b/src/snake.cpp index c0dec4b..5586724 100755 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -1,6 +1,4 @@ // Snake.cpp -#include -#include #include #include #include diff --git a/src/snake.hpp b/src/snake.hpp index 01392cf..6508e3f 100755 --- a/src/snake.hpp +++ b/src/snake.hpp @@ -3,10 +3,8 @@ #define SNAKE_HPP #include -#include #include #include -#include namespace snakeplusplus { From c57fbc714c6904eeafbf0a9a46b1c615700c716b Mon Sep 17 00:00:00 2001 From: Trimutex Date: Fri, 18 Aug 2023 17:51:58 -0500 Subject: [PATCH 4/9] Cleaned up some naming and added WASD controls --- src/gamestate.cpp | 23 ++++++++++++----------- src/gamestate.hpp | 6 +++--- src/main.cpp | 2 +- src/playerinterface.cpp | 13 +++++++++---- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 74aa232..e53b81c 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -12,26 +12,27 @@ namespace snakeplusplus return; } - void GameEngine::StartGame() + void GameEngine::Start() { - //ApplySettings(); PrepareGameBoard(); graphics.StartGameWindow(); - GameLoop(); + Loop(); return; } - void GameEngine::GameLoop(void) + void GameEngine::Reset() + { + graphics.CheckContinue(); + player.Reset(); + PrepareGameBoard(); + isGameOver = 0; + } + + void GameEngine::Loop(void) { while (graphics.IsOpen()) { - if (isGameOver) - { - graphics.CheckContinue(); - player.Reset(); - PrepareGameBoard(); - isGameOver = 0; - } + if (isGameOver) {Reset();} UpdatePlayerSpeed(); PlaceNewSnakePart(MovePlayer()); RegenerateFood(); diff --git a/src/gamestate.hpp b/src/gamestate.hpp index 91b2af1..29763a4 100755 --- a/src/gamestate.hpp +++ b/src/gamestate.hpp @@ -12,17 +12,17 @@ namespace snakeplusplus { public: GameEngine(); - void StartGame(void); + void Start(void); + void Reset(void); sf::Vector2f GetGameBoundaries(void); private: std::vector< std::vector > gameBoard; PlayerOutput graphics; Snake player; Food playerFood; - bool useSFML = 1; bool isGameOver = 0; void DisplayEndScreen(void); - void GameLoop(void); + void Loop(void); sf::Vector2f MovePlayer(void); void PlaceNewSnakePart(sf::Vector2f location); void RegenerateFood(void); diff --git a/src/main.cpp b/src/main.cpp index 854534f..0bf1900 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,5 +3,5 @@ int main(void) { snakeplusplus::GameEngine game; - game.StartGame(); + game.Start(); } diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index 2c95059..d981553 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -1,17 +1,22 @@ #include "playerinterface.hpp" #include +#include namespace snakeplusplus { PlayerDirection GetPlayerInput(void) { - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) + || sf::Keyboard::isKeyPressed(sf::Keyboard::A)) return kLeft; - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) + || sf::Keyboard::isKeyPressed(sf::Keyboard::W)) return kUp; - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) + || sf::Keyboard::isKeyPressed(sf::Keyboard::S)) return kDown; - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right) + || sf::Keyboard::isKeyPressed(sf::Keyboard::D)) return kRight; return kNone; } From 709cf26f99913c01e3f82c2677a1dde99c406ec4 Mon Sep 17 00:00:00 2001 From: Trimutex Date: Fri, 18 Aug 2023 18:09:09 -0500 Subject: [PATCH 5/9] Fixed code consistency issues --- src/gamestate.cpp | 6 ++++-- src/main.cpp | 1 + src/playerinterface.cpp | 8 ++++---- src/snake.cpp | 4 ++++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index e53b81c..c79cb77 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -26,6 +26,7 @@ namespace snakeplusplus player.Reset(); PrepareGameBoard(); isGameOver = 0; + return; } void GameEngine::Loop(void) @@ -60,7 +61,7 @@ namespace snakeplusplus { char* locationState; locationState = &gameBoard.at(location.y).at(location.x); - if (*locationState == 'O' && player.body.size() > 1) + if (*locationState == 'O' && (player.body.size() > 1)) isGameOver = true; // Game should end (Snake touching snake) *locationState = 'O'; player.body.push(locationState); @@ -70,6 +71,7 @@ namespace snakeplusplus } catch (const std::out_of_range& error) { isGameOver = true; // Snake ran into edge } + return; } // Generates new food until not colliding with player @@ -77,7 +79,6 @@ namespace snakeplusplus { sf::Vector2f newLocation = playerFood.location; bool isUpdated = false; - // Keep making new food until generating a valid spot while (gameBoard.at(newLocation.y).at(newLocation.x) == 'O') { isUpdated = true; @@ -128,5 +129,6 @@ namespace snakeplusplus default: break; } + return; } } diff --git a/src/main.cpp b/src/main.cpp index 0bf1900..2d529fb 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,4 +4,5 @@ int main(void) { snakeplusplus::GameEngine game; game.Start(); + return 0; } diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index d981553..2978179 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -45,8 +45,8 @@ namespace snakeplusplus while (true) { gameWindow.pollEvent(event); - if ((event.type == sf::Event::Closed) || - (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))) + if ((event.type == sf::Event::Closed) + || (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))) { gameWindow.close(); return; @@ -114,8 +114,8 @@ namespace snakeplusplus sf::Event event; while (gameWindow.pollEvent(event)) { - if ((event.type == sf::Event::Closed) || - (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))) + if ((event.type == sf::Event::Closed) + || (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))) gameWindow.close(); } } diff --git a/src/snake.cpp b/src/snake.cpp index 5586724..d1908e4 100755 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -10,6 +10,7 @@ namespace snakeplusplus { *(body.front()) = ' '; body.pop(); + return; } void Snake::Reset(void) @@ -17,11 +18,13 @@ namespace snakeplusplus while (!body.empty()) Pop(); speed.x = 0; speed.y = 0; + return; } Food::Food(void) { generator.seed(std::random_device{}()); + return; } // Returns a new food object for the snakeFood @@ -29,6 +32,7 @@ namespace snakeplusplus { location.x = GenerateRandomNumber(boundaries.x); location.y = GenerateRandomNumber(boundaries.y); + return; } // Returns a newly generated number From 441c52ab0f6eb04624553448eef135063b30675d Mon Sep 17 00:00:00 2001 From: Trimutex Date: Fri, 18 Aug 2023 18:15:21 -0500 Subject: [PATCH 6/9] Added random generation on start --- src/gamestate.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index c79cb77..51d4e99 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -100,10 +100,9 @@ namespace snakeplusplus char* locationState = &gameBoard.at(player.headLocation.y).at(player.headLocation.x); player.body.push(locationState); *player.body.front() = 'O'; - playerFood.location.x = 2; - playerFood.location.y = 2; - playerFood.food = &gameBoard.at(2).at(2); - *playerFood.food = 'X'; + playerFood.GenerateNewFood(GetGameBoundaries()); + sf::Vector2f newLocation = playerFood.location; + gameBoard.at(newLocation.y).at(newLocation.x) = 'X'; return; } From d7982b200ff2a1cd0e4acd604ace06b4429052c6 Mon Sep 17 00:00:00 2001 From: Trimutex Date: Fri, 18 Aug 2023 19:09:57 -0500 Subject: [PATCH 7/9] Separated generation into common file --- src/CMakeLists.txt | 1 + src/common.cpp | 21 +++++++++++++++++++++ src/common.hpp | 21 ++++++++++++++------- src/gamestate.cpp | 1 + src/snake.cpp | 22 ++++------------------ src/snake.hpp | 5 ----- 6 files changed, 41 insertions(+), 30 deletions(-) create mode 100755 src/common.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 02db7fb..04900db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ add_executable(snakeplusplus ./gamestate.cpp ./snake.cpp ./playerinterface.cpp + ./common.cpp ) target_include_directories(snakeplusplus PUBLIC ${CMAKE_CURRENT_LIST_DIR}) diff --git a/src/common.cpp b/src/common.cpp new file mode 100755 index 0000000..62088ee --- /dev/null +++ b/src/common.cpp @@ -0,0 +1,21 @@ +// common.cpp +#include +#include "common.hpp" + +namespace snakeplusplus +{ + std::default_random_engine generator; + void InitializeGenerator(void) + { + generator.seed(std::random_device{}()); + } + + // Returns a newly generated number + int GenerateRandomNumber(int generationLimit) + { + int generatedNumber; + std::uniform_int_distribution<> distribution(0, generationLimit - 1); + generatedNumber = distribution(snakeplusplus::generator); + return generatedNumber; + } +} diff --git a/src/common.hpp b/src/common.hpp index ef440c9..82f60e2 100755 --- a/src/common.hpp +++ b/src/common.hpp @@ -1,13 +1,20 @@ #ifndef COMMON_HPP #define COMMON_HPP -enum PlayerDirection +namespace snakeplusplus { - kNone = 0, - kLeft = 1, - kUp = 2, - kDown = 3, - kRight = 4 -}; + void InitializeGenerator(void); + int GenerateRandomNumber(int generationLimit); + + enum PlayerDirection + { + kNone = 0, + kLeft = 1, + kUp = 2, + kDown = 3, + kRight = 4 + }; + +} #endif diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 51d4e99..14b3ec9 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -9,6 +9,7 @@ namespace snakeplusplus { GameEngine::GameEngine() { + snakeplusplus::InitializeGenerator(); return; } diff --git a/src/snake.cpp b/src/snake.cpp index d1908e4..f6c635b 100755 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -1,11 +1,12 @@ // Snake.cpp #include -#include #include +#include "common.hpp" #include "snake.hpp" namespace snakeplusplus { + void Snake::Pop(void) { *(body.front()) = ' '; @@ -21,26 +22,11 @@ namespace snakeplusplus return; } - Food::Food(void) - { - generator.seed(std::random_device{}()); - return; - } - // Returns a new food object for the snakeFood void Food::GenerateNewFood(sf::Vector2f boundaries) { - location.x = GenerateRandomNumber(boundaries.x); - location.y = GenerateRandomNumber(boundaries.y); + location.x = snakeplusplus::GenerateRandomNumber(boundaries.x); + location.y = snakeplusplus::GenerateRandomNumber(boundaries.y); return; } - - // Returns a newly generated number - int Food::GenerateRandomNumber(int generationLimit) - { - int generatedNumber; - std::uniform_int_distribution<> distribution(0, generationLimit - 1); - generatedNumber = distribution(generator); - return generatedNumber; - } } diff --git a/src/snake.hpp b/src/snake.hpp index 6508e3f..80cec53 100755 --- a/src/snake.hpp +++ b/src/snake.hpp @@ -4,7 +4,6 @@ #include #include -#include namespace snakeplusplus { @@ -21,13 +20,9 @@ namespace snakeplusplus struct Food { public: - Food(void); sf::Vector2f location; char* food; void GenerateNewFood(sf::Vector2f boundaries); - private: - std::default_random_engine generator; - int GenerateRandomNumber(int generationLimit); }; } From 49182ce07d676a41ad0e82f652224560e8a4e6dd Mon Sep 17 00:00:00 2001 From: Trimutex Date: Fri, 18 Aug 2023 19:51:15 -0500 Subject: [PATCH 8/9] Snake now randomly starts as well --- src/gamestate.cpp | 22 ++++++++++++++-------- src/snake.cpp | 1 - 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 14b3ec9..8394f78 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -96,14 +96,20 @@ namespace snakeplusplus gameBoard.clear(); sf::Vector2f boardDimensions = GetGameBoundaries(); gameBoard.resize(boardDimensions.y, std::vector (boardDimensions.x, ' ')); - player.headLocation.x = 4; - player.headLocation.y = 5; - char* locationState = &gameBoard.at(player.headLocation.y).at(player.headLocation.x); - player.body.push(locationState); - *player.body.front() = 'O'; - playerFood.GenerateNewFood(GetGameBoundaries()); - sf::Vector2f newLocation = playerFood.location; - gameBoard.at(newLocation.y).at(newLocation.x) = 'X'; + // Snake setup + { + player.headLocation.x = GenerateRandomNumber(boardDimensions.x); + player.headLocation.y = GenerateRandomNumber(boardDimensions.y); + char* locationState = &gameBoard.at(player.headLocation.y).at(player.headLocation.x); + player.body.push(locationState); + *locationState = 'O'; + } + // Food setup + { + playerFood.GenerateNewFood(boardDimensions); + sf::Vector2f newLocation = playerFood.location; + gameBoard.at(newLocation.y).at(newLocation.x) = 'X'; + } return; } diff --git a/src/snake.cpp b/src/snake.cpp index f6c635b..4dfc7f4 100755 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -6,7 +6,6 @@ namespace snakeplusplus { - void Snake::Pop(void) { *(body.front()) = ' '; From 71dfa043a99549a1c1679668799ff0fbca74c98e Mon Sep 17 00:00:00 2001 From: Trimutex Date: Fri, 18 Aug 2023 22:36:47 -0500 Subject: [PATCH 9/9] Fixed snake not showing on start --- src/gamestate.cpp | 2 ++ src/playerinterface.cpp | 11 ++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 8394f78..67941f4 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -1,6 +1,7 @@ // GameState.cpp #include #include +#include #include "common.hpp" #include "playerinterface.hpp" #include "gamestate.hpp" @@ -58,6 +59,7 @@ namespace snakeplusplus void GameEngine::PlaceNewSnakePart(sf::Vector2f location) { + if (!player.speed.x && !player.speed.y) { return; } try { char* locationState; diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index 2978179..d63706c 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -74,25 +74,22 @@ namespace snakeplusplus void PlayerOutput::DisplayGameState(std::vector< std::vector >& gameBoard) { CheckWindowEvents(); - sf::Vector2f location; char* letterOnBoard; for (float y = 0; y < gameBoundaries.y; y++) { for (float x = 0; x < gameBoundaries.x; x++) { - location.x = x; - location.y = y; - letterOnBoard = &gameBoard.at(location.y).at(location.x); + letterOnBoard = &gameBoard.at(y).at(x); switch (*letterOnBoard) { case 'O': - DrawSnake(location); + DrawSnake(sf::Vector2f(x, y)); break; case 'X': - DrawFood(location); + DrawFood(sf::Vector2f(x,y)); break; default: - DrawEmpty(location); + DrawEmpty(sf::Vector2f(x,y)); break; } }