Split into BFS at first and DFS after
This commit is contained in:
		
							parent
							
								
									b8a6a8d195
								
							
						
					
					
						commit
						e6797fa193
					
				| @ -38,25 +38,42 @@ namespace snakeplusplus | ||||
| 
 | ||||
|     // 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) | ||||
|     void AISnake::GetNewPath(const std::vector< std::vector<char> >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries, const int snakeSize) | ||||
|     { | ||||
|         // Search for food
 | ||||
|         if (snakeSize < 160) { | ||||
|             BFS(gameBoard, source, boundaries); | ||||
|         } else { | ||||
|             DFS(gameBoard, source, boundaries); | ||||
|         } | ||||
|         // Create path for food
 | ||||
|         path.push(botPathUnsanitized.top()); | ||||
|         botPathUnsanitized.pop(); | ||||
|         while (!botPathUnsanitized.empty()) { | ||||
|             sf::Vector2f deltaVector = botPathUnsanitized.top() - path.top(); | ||||
|             int delta = abs(deltaVector.x) + abs(deltaVector.y); | ||||
|             if (delta == 1) { | ||||
|                 path.push(botPathUnsanitized.top()); | ||||
|             } | ||||
|             botPathUnsanitized.pop(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void AISnake::BFS(const std::vector< std::vector<char> >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries) { | ||||
|         std::queue<sf::Vector2f> search; | ||||
|         std::stack<sf::Vector2f> botPathUnsanitized; | ||||
|         std::vector<std::vector<bool>> visited(boundaries.y, std::vector<bool> (boundaries.x, false)); | ||||
|         sf::Vector2f currentLocation; | ||||
|         std::array<sf::Vector2f, 4> localLocations; | ||||
|         bool foodFound = false; | ||||
|         search.push(source); | ||||
|         // Search for food
 | ||||
|         while (!search.empty()) { | ||||
|             currentLocation = search.front(); | ||||
|             sf::Vector2f currentLocation = search.front(); | ||||
|             search.pop(); | ||||
|             if (foodFound) { break; } | ||||
|             if (visited.at(currentLocation.y).at(currentLocation.x)) { continue; } | ||||
|             botPathUnsanitized.push(currentLocation); | ||||
|             if (gameBoard.at(currentLocation.y).at(currentLocation.x) == 'X') { | ||||
|                 foodFound = true; | ||||
|             } | ||||
|             botPathUnsanitized.push(currentLocation); | ||||
|             std::array<sf::Vector2f, 4> localLocations; | ||||
|             localLocations.fill(currentLocation); | ||||
|             localLocations[0].y += 1; | ||||
|             localLocations[1].x += 1; | ||||
| @ -84,17 +101,49 @@ namespace snakeplusplus | ||||
|             } | ||||
|             visited.at(currentLocation.y).at(currentLocation.x) = true; | ||||
|         } | ||||
|         // Create path for food
 | ||||
|         path.push(botPathUnsanitized.top()); | ||||
|         botPathUnsanitized.pop(); | ||||
|         while (!botPathUnsanitized.empty()) { | ||||
|             currentLocation = botPathUnsanitized.top(); | ||||
|             sf::Vector2f deltaVector = currentLocation - path.top(); | ||||
|             int delta = abs(deltaVector.x) + abs(deltaVector.y); | ||||
|             if (delta == 1) { | ||||
|                 path.push(botPathUnsanitized.top()); | ||||
|     } | ||||
| 
 | ||||
|     void AISnake::DFS(const std::vector< std::vector<char> >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries) { | ||||
|         std::stack<sf::Vector2f> search; | ||||
|         std::vector<std::vector<bool>> visited(boundaries.y, std::vector<bool> (boundaries.x, false)); | ||||
|         bool foodFound = false; | ||||
|         search.push(source); | ||||
|         while (!search.empty()) { | ||||
|             sf::Vector2f currentLocation = search.top(); | ||||
|             search.pop(); | ||||
|             if (foodFound) { break; } | ||||
|             if (visited.at(currentLocation.y).at(currentLocation.x)) { continue; } | ||||
|             if (gameBoard.at(currentLocation.y).at(currentLocation.x) == 'X') { | ||||
|                 foodFound = true; | ||||
|             } | ||||
|             botPathUnsanitized.pop(); | ||||
|             botPathUnsanitized.push(currentLocation); | ||||
|             std::array<sf::Vector2f, 4> localLocations; | ||||
|             localLocations.fill(currentLocation); | ||||
|             localLocations[0].y += 1; | ||||
|             localLocations[1].x += 1; | ||||
|             localLocations[2].y -= 1; | ||||
|             localLocations[3].x -= 1; | ||||
|             for (auto i : localLocations) {  | ||||
|                 try { | ||||
|                     if (gameBoard.at(i.y).at(i.x) == 'X') { | ||||
|                         botPathUnsanitized.push(i); | ||||
|                         foodFound = true; | ||||
|                     } | ||||
|                 } catch (const std::out_of_range& error) { | ||||
|                     continue; // Out of bounds
 | ||||
|                 } | ||||
|             } | ||||
|             for (sf::Vector2f newLocation : localLocations) { | ||||
|                 try { | ||||
|                     if ((!visited.at(newLocation.y).at(newLocation.x)) | ||||
|                             && (gameBoard.at(newLocation.y).at(newLocation.x) == ' ')) { | ||||
|                         search.push(newLocation); | ||||
|                     } | ||||
|                 } catch (const std::out_of_range& error) { | ||||
|                     continue; // Out of bounds
 | ||||
|                 } | ||||
|             } | ||||
|             visited.at(currentLocation.y).at(currentLocation.x) = true; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -12,8 +12,12 @@ namespace snakeplusplus | ||||
|     public: | ||||
|         std::stack<sf::Vector2f> path; | ||||
|         AISnake(); | ||||
|         void GetNewPath(const std::vector< std::vector<char> >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries); | ||||
|         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); | ||||
|     private: | ||||
|         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); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -121,7 +121,7 @@ namespace snakeplusplus | ||||
|         PlayerDirection controller; | ||||
|         if (isBotControlled) {  | ||||
|             if (bot.path.empty()) {  | ||||
|                 bot.GetNewPath(gameBoard, player.headLocation, GetGameBoundaries());  | ||||
|                 bot.GetNewPath(gameBoard, player.headLocation, GetGameBoundaries(), player.body.size());  | ||||
|             } | ||||
|             controller = bot.GetInput(&player.headLocation);  | ||||
|         } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user