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
 |     // Gets a new path for the bot to follow
 | ||||||
|     // Uses DFS algorithm
 |     // 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::queue<sf::Vector2f> search; | ||||||
|         std::stack<sf::Vector2f> botPathUnsanitized; |  | ||||||
|         std::vector<std::vector<bool>> visited(boundaries.y, std::vector<bool> (boundaries.x, false)); |         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; |         bool foodFound = false; | ||||||
|         search.push(source); |         search.push(source); | ||||||
|         // Search for food
 |  | ||||||
|         while (!search.empty()) { |         while (!search.empty()) { | ||||||
|             currentLocation = search.front(); |             sf::Vector2f currentLocation = search.front(); | ||||||
|             search.pop(); |             search.pop(); | ||||||
|             if (foodFound) { break; } |             if (foodFound) { break; } | ||||||
|             if (visited.at(currentLocation.y).at(currentLocation.x)) { continue; } |             if (visited.at(currentLocation.y).at(currentLocation.x)) { continue; } | ||||||
|             botPathUnsanitized.push(currentLocation); |  | ||||||
|             if (gameBoard.at(currentLocation.y).at(currentLocation.x) == 'X') { |             if (gameBoard.at(currentLocation.y).at(currentLocation.x) == 'X') { | ||||||
|                 foodFound = true; |                 foodFound = true; | ||||||
|             } |             } | ||||||
|  |             botPathUnsanitized.push(currentLocation); | ||||||
|  |             std::array<sf::Vector2f, 4> localLocations; | ||||||
|             localLocations.fill(currentLocation); |             localLocations.fill(currentLocation); | ||||||
|             localLocations[0].y += 1; |             localLocations[0].y += 1; | ||||||
|             localLocations[1].x += 1; |             localLocations[1].x += 1; | ||||||
| @ -84,17 +101,49 @@ namespace snakeplusplus | |||||||
|             } |             } | ||||||
|             visited.at(currentLocation.y).at(currentLocation.x) = true; |             visited.at(currentLocation.y).at(currentLocation.x) = true; | ||||||
|         } |         } | ||||||
|         // Create path for food
 |     } | ||||||
|         path.push(botPathUnsanitized.top()); | 
 | ||||||
|         botPathUnsanitized.pop(); |     void AISnake::DFS(const std::vector< std::vector<char> >& gameBoard, const sf::Vector2f& source, const sf::Vector2f& boundaries) { | ||||||
|         while (!botPathUnsanitized.empty()) { |         std::stack<sf::Vector2f> search; | ||||||
|             currentLocation = botPathUnsanitized.top(); |         std::vector<std::vector<bool>> visited(boundaries.y, std::vector<bool> (boundaries.x, false)); | ||||||
|             sf::Vector2f deltaVector = currentLocation - path.top(); |         bool foodFound = false; | ||||||
|             int delta = abs(deltaVector.x) + abs(deltaVector.y); |         search.push(source); | ||||||
|             if (delta == 1) { |         while (!search.empty()) { | ||||||
|                 path.push(botPathUnsanitized.top()); |             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: |     public: | ||||||
|         std::stack<sf::Vector2f> path; |         std::stack<sf::Vector2f> path; | ||||||
|         AISnake(); |         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); |         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; |         PlayerDirection controller; | ||||||
|         if (isBotControlled) {  |         if (isBotControlled) {  | ||||||
|             if (bot.path.empty()) {  |             if (bot.path.empty()) {  | ||||||
|                 bot.GetNewPath(gameBoard, player.headLocation, GetGameBoundaries());  |                 bot.GetNewPath(gameBoard, player.headLocation, GetGameBoundaries(), player.body.size());  | ||||||
|             } |             } | ||||||
|             controller = bot.GetInput(&player.headLocation);  |             controller = bot.GetInput(&player.headLocation);  | ||||||
|         } |         } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user