Add iterative approach to deciding DFS and BFS
This commit is contained in:
		
							parent
							
								
									1498110048
								
							
						
					
					
						commit
						05f78d67fd
					
				| @ -2,6 +2,7 @@ | ||||
| #include "common.hpp" | ||||
| #include <array> | ||||
| #include <cstdlib> | ||||
| #include <iostream> | ||||
| #include <queue> | ||||
| #include <stdexcept> | ||||
| #include <SFML/System/Vector2.hpp> | ||||
| @ -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<char> >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries, const int snakeSize) | ||||
|  | ||||
| @ -15,8 +15,9 @@ namespace snakeplusplus | ||||
|         void GetNewPath(const std::vector< std::vector<char> >& 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<sf::Vector2f> botPathUnsanitized; | ||||
|         void BFS(const std::vector< std::vector<char> >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries); | ||||
|         void DFS(const std::vector< std::vector<char> >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries); | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| // GameState.cpp
 | ||||
| #include <iostream> | ||||
| #include <stdexcept> | ||||
| #include <SFML/Graphics.hpp> | ||||
| #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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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<char> > 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; | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user