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