From 05f78d67fd8a5afbc2ebae24e28ccdf5fa6a2d07 Mon Sep 17 00:00:00 2001 From: Trimutex Date: Thu, 1 Feb 2024 12:50:10 -0600 Subject: [PATCH 1/4] Add iterative approach to deciding DFS and BFS --- src/botinterface.cpp | 10 ++++++ src/botinterface.hpp | 3 +- src/gamestate.cpp | 68 ++++++++++++++++++++++++----------------- src/gamestate.hpp | 5 +++ src/playerinterface.hpp | 2 +- 5 files changed, 58 insertions(+), 30 deletions(-) diff --git a/src/botinterface.cpp b/src/botinterface.cpp index 4712adf..15bfbba 100755 --- a/src/botinterface.cpp +++ b/src/botinterface.cpp @@ -2,6 +2,7 @@ #include "common.hpp" #include #include +#include #include #include #include @@ -42,6 +43,15 @@ namespace snakeplusplus return; } + void AISnake::AdjustProbability(double amount) + { + probabilityBFS += amount; + if (probabilityBFS > 1.0) { probabilityBFS = 1.0; } + if (probabilityBFS < 0.0) { probabilityBFS = 0.0; } + std::cout << "[Info - AISnake] New BFS probability: " << probabilityBFS << std::endl; + return; + } + // Gets a new path for the bot to follow // Uses DFS algorithm void AISnake::GetNewPath(const std::vector< std::vector >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries, const int snakeSize) diff --git a/src/botinterface.hpp b/src/botinterface.hpp index 8bbbfb0..7bf29b7 100755 --- a/src/botinterface.hpp +++ b/src/botinterface.hpp @@ -15,8 +15,9 @@ namespace snakeplusplus void GetNewPath(const std::vector< std::vector >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries, const int snakeSize); PlayerDirection GetInput(const sf::Vector2f* source); void UpdateProbability(int snakeSize); + void AdjustProbability(double amount); private: - double probabilityBFS = 1.000; + double probabilityBFS = 0.500; std::stack botPathUnsanitized; void BFS(const std::vector< std::vector >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries); void DFS(const std::vector< std::vector >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries); diff --git a/src/gamestate.cpp b/src/gamestate.cpp index d5f3ee1..debbcbb 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -1,4 +1,5 @@ // GameState.cpp +#include #include #include #include "botinterface.hpp" @@ -24,16 +25,29 @@ namespace snakeplusplus void GameEngine::Reset() { - graphics.CheckContinue(isBotControlled); + AddIteration(); player.Reset(); - if (isBotControlled) { - while (!bot.path.empty()) { bot.path.pop(); } - } + if (isBotControlled) { while (!bot.path.empty()) { bot.path.pop(); } } PrepareGameBoard(); isGameOver = false; return; } + void GameEngine::AddIteration(void) + { + graphics.CheckContinue(isBotControlled); + if (player.body.size() > 40) + { + UpdateAverage(); + double adjustmentAmount = 0.002; + if (average > player.body.size()) { bot.AdjustProbability(adjustmentAmount); } + else { bot.AdjustProbability(-adjustmentAmount); } + } + std::cout << "[Info - GameEngine] Current average: " << average << std::endl; + std::cout << "[Info - GameEngine] Previous iteration size: " << player.body.size() << std::endl; + + } + void GameEngine::Loop(void) { int currentScore = 0; @@ -44,34 +58,30 @@ namespace snakeplusplus PlaceNewSnakePart(MovePlayer()); RegenerateFood(); currentScore = player.body.size() * 100; - bot.UpdateProbability(player.body.size()); - graphics.DisplayGameState(gameBoard, currentScore); + //bot.UpdateProbability(player.body.size()); + //graphics.DisplayGameState(gameBoard, currentScore); } return; } sf::Vector2f GameEngine::MovePlayer(void) { - sf::Vector2f newHeadPosition; - newHeadPosition.x = player.headLocation.x + player.speed.x; - newHeadPosition.y = player.headLocation.y + player.speed.y; - return newHeadPosition; + return sf::Vector2f(player.headLocation.x + player.speed.x, player.headLocation.y + player.speed.y); } + sf::Vector2f GameEngine::GetGameBoundaries(void) { return graphics.gameBoundaries; } - void GameEngine::PlaceNewSnakePart(sf::Vector2f location) - { + void GameEngine::PlaceNewSnakePart(sf::Vector2f location) { if (!player.speed.x && !player.speed.y) { return; } - try - { - char* locationState; - locationState = &gameBoard.at(location.y).at(location.x); - if (*locationState == 'O' && (player.body.size() > 1)) + try { + char* locationState = &gameBoard.at(location.y).at(location.x); + if (*locationState == 'O' && (player.body.size() > 1)) { isGameOver = true; // Game should end (Snake touching snake) + } *locationState = 'O'; player.body.push(locationState); player.headLocation = location; @@ -83,23 +93,20 @@ namespace snakeplusplus return; } + // Generates new food until not colliding with player - void GameEngine::RegenerateFood(void) + void GameEngine::RegenerateFood() { - sf::Vector2f newLocation = playerFood.location; - bool isUpdated = false; - while (gameBoard.at(newLocation.y).at(newLocation.x) == 'O') - { - isUpdated = true; + // Generate a new food location if the current one is occupied + while (gameBoard.at(playerFood.location.y).at(playerFood.location.x) == 'O') { playerFood.GenerateNewFood(GetGameBoundaries()); - newLocation = playerFood.location; } - if (isUpdated) { - gameBoard.at(newLocation.y).at(newLocation.x) = 'X'; - } - return; + + // Update the game board with the new food location + gameBoard.at(playerFood.location.y).at(playerFood.location.x) = 'X'; } + void GameEngine::PrepareGameBoard(void) { gameBoard.clear(); @@ -155,4 +162,9 @@ namespace snakeplusplus } return; } + void GameEngine::UpdateAverage() { + totalLength += player.body.size(); + amountPlayed += 1; + average = (double)totalLength / amountPlayed; + } } diff --git a/src/gamestate.hpp b/src/gamestate.hpp index 19d8350..e71949d 100755 --- a/src/gamestate.hpp +++ b/src/gamestate.hpp @@ -17,6 +17,7 @@ namespace snakeplusplus GameEngine(); void Start(void); void Reset(void); + void AddIteration(void); sf::Vector2f GetGameBoundaries(void); private: std::vector< std::vector > gameBoard; @@ -33,6 +34,10 @@ namespace snakeplusplus void RegenerateFood(void); void PrepareGameBoard(void); void UpdatePlayerSpeed(); + void UpdateAverage(); + int totalLength = 0; + int amountPlayed = 0; + double average = 0; }; } diff --git a/src/playerinterface.hpp b/src/playerinterface.hpp index 9098822..eb0a210 100755 --- a/src/playerinterface.hpp +++ b/src/playerinterface.hpp @@ -31,7 +31,7 @@ namespace snakeplusplus sf::RectangleShape drawObject; sf::Event event; bool isWindowAlive; - sf::Time delay = sf::milliseconds(10); + sf::Time delay = sf::milliseconds(1); }; } -- 2.45.3 From b18ce8997074e1ab7aca68b01aafa893e1d4f69b Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Mon, 20 May 2024 01:05:59 -0500 Subject: [PATCH 2/4] bot: added ability to skip display delay between specific generations --- src/gamestate.cpp | 3 ++- src/playerinterface.cpp | 7 +++++++ src/playerinterface.hpp | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index debbcbb..98840d0 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -30,6 +30,7 @@ namespace snakeplusplus if (isBotControlled) { while (!bot.path.empty()) { bot.path.pop(); } } PrepareGameBoard(); isGameOver = false; + graphics.SetShowGame((amountPlayed + 1) % 50 == 0); return; } @@ -59,7 +60,7 @@ namespace snakeplusplus RegenerateFood(); currentScore = player.body.size() * 100; //bot.UpdateProbability(player.body.size()); - //graphics.DisplayGameState(gameBoard, currentScore); + graphics.DisplayGameState(gameBoard, currentScore); } return; } diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index 55a7ca3..ff5c26a 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -87,6 +87,7 @@ namespace snakeplusplus void PlayerOutput::DisplayGameState(std::vector< std::vector >& gameBoard, int score) { CheckWindowEvents(); + if (delay == sf::milliseconds(0)) { return; } char* letterOnBoard; for (float y = 0; y < gameBoundaries.y; y++) { @@ -120,6 +121,12 @@ namespace snakeplusplus return; } + void PlayerOutput::SetShowGame(bool isShowing) { + if (isShowing) { delay = sf::milliseconds(2); } + else { delay = sf::milliseconds(0); } + return; + } + void PlayerOutput::CheckWindowEvents(void) { while (gameWindow.pollEvent(event)) diff --git a/src/playerinterface.hpp b/src/playerinterface.hpp index eb0a210..5f5fb3a 100755 --- a/src/playerinterface.hpp +++ b/src/playerinterface.hpp @@ -20,6 +20,7 @@ namespace snakeplusplus void DisplayGameState(std::vector< std::vector >& gameBoard, int score); void DisplayScore(int score); void StartGameWindow(void); + void SetShowGame(bool isShowing); private: void CheckWindowEvents(void); void DisplayEndScreen(void); -- 2.45.3 From 22da054dab6eddb6aa85972105db8d6da6fcc08a Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Mon, 20 May 2024 01:20:05 -0500 Subject: [PATCH 3/4] controls: added adjusting game speed with - and + --- src/playerinterface.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index ff5c26a..fe4a5f4 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -134,6 +134,14 @@ namespace snakeplusplus if ((event.type == sf::Event::Closed) || (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))) gameWindow.close(); + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Equal)) { + if (delay > sf::milliseconds(16)) { continue; } + delay += sf::milliseconds(1); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Hyphen)) { + if (delay == sf::milliseconds(0)) { continue; } + delay -= sf::milliseconds(1); + } } } -- 2.45.3 From 03e2bf2748472a995bfc997f4fd4f011f5950c6d Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Fri, 2 Aug 2024 19:33:45 -0500 Subject: [PATCH 4/4] git: update gitignore for cmake stuff --- .gitignore | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index c90802d..99352dd 100755 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,19 @@ *.json *.ps1 +# ---> CMake +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps +build + # Extras .vs* -build -bin \ No newline at end of file -- 2.45.3