Skip to content

Commit

Permalink
Refactor Code and Implement Parallelizm to DekuBot
Browse files Browse the repository at this point in the history
  • Loading branch information
TheCongaGuy committed Apr 16, 2023
1 parent 3cda869 commit be603fd
Show file tree
Hide file tree
Showing 11 changed files with 640 additions and 544 deletions.
6 changes: 6 additions & 0 deletions Deku Bot (Win32)/Deku Bot/Deku Bot.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>SFML-2.5.1\include</AdditionalIncludeDirectories>
<OpenMPSupport>true</OpenMPSupport>
<AdditionalOptions>/openmp %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -94,6 +96,7 @@
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>SFML-2.5.1\include</AdditionalIncludeDirectories>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -112,6 +115,7 @@
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -130,6 +134,7 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>SFML-2.5.1\include</AdditionalIncludeDirectories>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -149,6 +154,7 @@
<ItemGroup>
<ClInclude Include="DekuBot.hpp" />
<ClInclude Include="GameBoard.hpp" />
<ClInclude Include="Helper.h" />
<ClInclude Include="Sprite.h" />
<ClInclude Include="Test.hpp" />
</ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions Deku Bot (Win32)/Deku Bot/Deku Bot.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
<ClInclude Include="Sprite.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Helper.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="Image Assets\Bishop.png">
Expand Down
24 changes: 15 additions & 9 deletions Deku Bot (Win32)/Deku Bot/DekuBot.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#pragma once

#include <chrono>
#include <iomanip>
#include <thread>
#include <omp.h>

#include "GameBoard.hpp"
#include <time.h>

// Deku Chess Bot
class DekuBot
{
public:
// Explicit Constructor takes a reference to an existing game board and the AI's color (1 -> White | -1 -> Black)
DekuBot(GameBoard* board, const int color);
DekuBot(GameBoard& board, const int color);

// Makes a move on the chess board
// Takes the maximum ammount of time in minutes the AI is allowed to search
Expand All @@ -17,23 +21,25 @@ class DekuBot
private:
// ----- Data Members ----- \\
// Reference to a game board
// Pointer to the live game board
GameBoard* currentGame;

// Color assigned to the AI
// (1 -> White | -1 -> Black)
int aiColor;

// Maximum ammount of time specified by the user for each move in milliseconds
float maxSearchTime;
int maxSearchTime;

// ----- Methods ----- \\
// Search the tree Breadth First
// Returns the best move after a given amount of time
std::pair<coordinates, coordinates> breadthFirstSearch(std::vector<std::pair<coordinates, coordinates>>& moves, clock_t startTime);
// Runs a minimax algorithm using iterative deepening
// Takes a vector of moves (pair of coordinates)
// Returns the best move after a given amount of time (pair of coordinates)
std::pair<coordinates, coordinates> breadthFirstSearch(std::vector<std::pair<coordinates, coordinates>>& moves);

// Recursively find the best possible outcome for a move
// Returns an integer
int miniMaxMove(GameBoard& nextGame, int alpha, int beta, int currentDepth, clock_t startTime);
// Takes a game board state, an alpha and beta value, the current depth of search, and the specified time to stop searching
// Returns an integer representing the fitness of that move
int miniMaxMove(GameBoard& nextGame, int alpha, int beta, int currentDepth, std::chrono::steady_clock::time_point endTime);
};
31 changes: 17 additions & 14 deletions Deku Bot (Win32)/Deku Bot/GameBoard.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/Graphics.hpp> // External Graphics Library
#include <map>
#include <vector>

Expand All @@ -11,7 +11,6 @@ typedef __int8 piece;
typedef std::pair<unsigned int, unsigned int> coordinates;

// Holds information about the current game state
// Inherit from sf::Drawable to allow drawing to screen
class GameBoard
{
public:
Expand All @@ -25,31 +24,30 @@ class GameBoard
// Copy Constructor
GameBoard(const GameBoard& rhs);

// Performs a move on the board
// Performs a move to the board
// Takes two coordinates; the location of the piece to be moved and a final position
// Returns true if move was made, false otherwise
bool MovePiece(const coordinates initial, const coordinates final);

// Ranks the board for a given color
// 1 -> White | -1 -> Black
// Returns an integer representing it's fitness
// Takes the color to favor: 1 -> White | -1 -> Black
// Returns an integer representing that color's fitness
int RankBoard(const int color) const;

// Finds all possible moves for a given color (1 for white, -1 for black)
// Returns a vector of pairs of coordinates (pair<int, int>)
// Returns a vector of moves (pairs of coordinates)
// pair.first -> initial position | pair.second -> final position
std::vector<std::pair<coordinates, coordinates>> FindMoves(int color) const;

// Checks if black is in check
// Returns true if black is in check
bool isBlackInCheck() const
{ return blackInCheck; }

// Checks if white is in check
// Returns true if white is in check
bool isWhiteInCheck() const
{ return whiteInCheck; }

// Returns who may move
// True -> White | False -> Black
// Returns true if it is white's turn
bool whosTurn() const
{ return whiteTurn; }

Expand All @@ -74,13 +72,16 @@ class GameBoard
// Flags if a player is in check
bool blackInCheck, whiteInCheck;

// Flag if draw has been reached
bool draw;

// Flag controls which player may move
bool whiteTurn;

// Integer tracks how many moves have passed since a pawn move or capture.
int movesSinceCapture;

// Integers hold how many pieces each side has
// Integers hold how many pieces each color has
int blackPieces, whitePieces;

// Holds a copy of the previous board position
Expand All @@ -91,11 +92,13 @@ class GameBoard
// Evaluates the current board and updates pieces / flags
void EvaluateBoard();

// Checks if a given pair of coordinates are within the bounds of the game board
// Checks if a pair of coordinates are within the bounds of a chess board
// Takes an x coordinate and a y coordinate
// Returns true if x, y pair reside inside the game board
bool InBounds(const unsigned int xCoord, const unsigned int yCoord) const
{ return xCoord < 8 && yCoord < 8; }

// KEY OF VALUES
/* ----- KEY OF VALUES ----- */
// + -> White
// - -> Black
//
Expand All @@ -109,7 +112,7 @@ class GameBoard
// 8. King
// 9. Castleable King

// Chess Special Rules
/* ----- Chess Special Rules ----- */
// Castling - King moves two tiles towards rook if both have line of sight, and neither has moved.
// Rook jumps over king to the first tile king moved over.
//
Expand Down
66 changes: 66 additions & 0 deletions Deku Bot (Win32)/Deku Bot/Helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once
#include <iostream>

// Gets the color of the AI from the user
// Returns an integer; 1 -> White | -1 -> Black
int getUserColor()
{
// Catches user input
std::string input;
char flagSelection;

// Prompt the user for a color
std::cout << "AI Color (w/b): " << std::endl;
std::cin >> input;

// Convert first character to lowercase
flagSelection = input[0];
flagSelection = std::tolower(flagSelection);

// Check for invalid input
while (flagSelection != 'w' && flagSelection != 'b')
{
// Prompt the user again
std::cout << "Invalid Input; Please Enter 'w' or 'b': ";
std::cin >> input;

// Convert first character to lowercase
flagSelection = input[0];
flagSelection = std::tolower(flagSelection);
}

// Return the appropriate flag
return (flagSelection == 'b') ? -1 : 1;
}

// Gets the maximum ammount of time the AI is allowed to search for from the user
// Returns a float representing a time duration in minutes
float getSearchTime()
{
// Prompt the user for a duration
std::string input;
std::cout << "How long may the AI search in minutes? (Negative numbers allow for no limit): ";
std::cin >> input;

// Convert the input to a float
float inputTime = std::stof(input);

// Check if user chose a dangerous duration
if (inputTime < 0)
{
// Confirm the user's choice
std::cout << "WARNING: You have selected no limit to the search time. This may have unknown concequences " << std::endl
<< "regarding the application, results, or total time spent computing. If you would like to cap" << std::endl
<< "the search, please enter a positive integer now." << std::endl;

// Prompt the user again
std::cin >> input;
inputTime = std::stof(input);

// Set the input time to a maximum number
if (inputTime < 0)
inputTime = INT32_MAX / 60000;
}

return inputTime;
}
30 changes: 15 additions & 15 deletions Deku Bot (Win32)/Deku Bot/Sprite.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/Graphics.hpp> // External Graphics Library

#include "GameBoard.hpp"

// Struct draws sprites to the screen
Expand All @@ -9,8 +10,10 @@ struct sprites : public sf::Drawable
// Explicit constructor takes a reference to a GameBoard
sprites(GameBoard& board)
{
// Set the reference
referenceBoard = &board;

// Fill the icon array with textures
for (int i = 0; i < 6; i++)
pieceIcons[i] = new sf::Texture;

Expand All @@ -34,41 +37,32 @@ struct sprites : public sf::Drawable
delete pieceIcons[i];
}

// Pointer to an existing game board
GameBoard* referenceBoard;

// Stores the icons for chess pieces in memory
sf::Texture* pieceIcons[6];

// Method to draw items to the window
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
// Texture object to load to
sf::Texture piece;
// Holds new position
int newX, newY;

// Calculate the width for a tile
int tileWidth = target.getSize().x / 8;

// Holds new position
int newX, newY;

// Draw background
for (int x = 0; x < 8; x++)
for (int y = 0; y < 8; y++)
{
// Tile to draw with
sf::RectangleShape backGround;

// Strech Tile to fill board
backGround.setSize(sf::Vector2f((float)tileWidth, (float)tileWidth));

// Calculate new position
newX = x * tileWidth;
newY = y * tileWidth;

// Shift tile to correct position
backGround.setPosition(sf::Vector2f((float)newX, (float)newY));

// Strech Tile to fill board
backGround.setSize(sf::Vector2f((float)tileWidth, (float)tileWidth));

// Color tile
if ((x + y) % 2 == 0)
backGround.setFillColor(sf::Color(250, 250, 250));
Expand Down Expand Up @@ -168,4 +162,10 @@ struct sprites : public sf::Drawable
}
}
}

// Pointer to an existing game board
GameBoard* referenceBoard;

// Stores the icons for chess pieces in memory
sf::Texture* pieceIcons[6];
};
9 changes: 8 additions & 1 deletion Deku Bot (Win32)/Deku Bot/Test.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once

#include <fstream>
#include <string>

#include "GameBoard.hpp"
#include "DekuBot.hpp"
#include "Sprite.h"
Expand Down Expand Up @@ -30,4 +33,8 @@ void testMoveMethod();
void AIGame();

// Tests the AI with certain board configurations
void AISituations();
void AISituations();

// Times Each Board Method and writes the results to a log
// Additionally logs info on what resources are being used
void timeTest();
Loading

0 comments on commit be603fd

Please sign in to comment.