From 05f78d67fd8a5afbc2ebae24e28ccdf5fa6a2d07 Mon Sep 17 00:00:00 2001 From: Trimutex Date: Thu, 1 Feb 2024 12:50:10 -0600 Subject: [PATCH] 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); }; }