diff --git a/include/BitBoard.h b/include/BitBoard.h index b888961..600f017 100644 --- a/include/BitBoard.h +++ b/include/BitBoard.h @@ -16,7 +16,15 @@ typedef std::vector> vmup; class BitBoard { -private: + + /* Class member variables */ + uint32_t m_blackPieces = 0x41C71C3; + uint32_t m_whitePieces = 0xE3820C38; + uint32_t m_kings = 0; + + bool m_isBlacksTurn = true; + + public: /* Static bit masks */ // Used to determine whether a move from that direction is valid @@ -36,24 +44,16 @@ class BitBoard 0x10410004, 0x20820008, 0x41104010, - 0x82100820}; + 0x82000820}; return r[index]; } - static const uint32_t whiteKingSpots = 0x00041041; - static const uint32_t blackKingSpots = 0x82000820; + static const uint32_t whiteKingSpots = 0x00041041; // rowMask(0) + static const uint32_t blackKingSpots = 0x82000820; // rowMask(7) // Used for determing board from move static const uint32_t topCorner = 0xC3C; - /* Class member variables */ - uint32_t m_blackPieces = 0x41C71C3; - uint32_t m_whitePieces = 0xE3820C38; - uint32_t m_kings = 0; - - bool m_isBlacksTurn = true; - - // static constexpr uint32_t rowMask[8]; /* Class member functions */ // These are basic 32 bit rotation functions @@ -61,25 +61,7 @@ class BitBoard uint32_t rotl32 (uint32_t n, unsigned int c) const; uint32_t rotr32 (uint32_t n, unsigned int c) const; - const uint32_t playerPieces() const; - - const int count(uint32_t i) const; - - // Heuristic functions - int evalScore; - void evalHueristics(); - - int h1() const; - int h2() const; - int h3() const; - int h4() const; - int h5() const; - int h6() const; - int h7() const; - int h8() const; - int h9() const; - int h10() const; - + private: int getIndex(uint32_t piece) const; void addJumps(vmup &moves) const; @@ -96,10 +78,15 @@ class BitBoard BitBoard(uint32_t black, uint32_t white, uint32_t kings); BitBoard(const BitBoard &board); + uint32_t getBlackPieces() { return m_blackPieces; }; + uint32_t getWhitePieces() { return m_whitePieces; }; + uint32_t getKings () { return m_kings; }; + bool getIsBlacksTurn() { return m_isBlacksTurn; }; + std::string player() const; vmup actions() const; bup result(mup &move) const; - double utility(std::string player) const; + double utility() const; void printState() const; }; diff --git a/include/MinimaxSearch.h b/include/MinimaxSearch.h index 98177b1..845bc1f 100644 --- a/include/MinimaxSearch.h +++ b/include/MinimaxSearch.h @@ -6,23 +6,25 @@ #include #include "Move.h" #include "BitBoard.h" +#include "Heuristic.hpp" typedef std::unique_ptr mup; class MinimaxSearch { private: - static const int maxDepth = 9; + static const int maxDepth = 1; + Heuristic heuristic; - double minValue(std::unique_ptr &board, int currentDepth) const; - double maxValue(std::unique_ptr &board, int currentDepth) const; - double alphaBeta(std::unique_ptr &board, double alpha, double beta, int depth) const; + double minValue(std::unique_ptr &board, int currentDepth); + double maxValue(std::unique_ptr &board, int currentDepth); + double alphaBeta(std::unique_ptr &board, double alpha, double beta, int depth); public: - Move minimaxDecisionStack(const BitBoard &board) const; - mup minimaxDecision(std::unique_ptr &board) const; - + mup minimaxDecision(std::unique_ptr &board); + MinimaxSearch(Heuristic& h): heuristic(h){}; + MinimaxSearch() {}; }; #endif diff --git a/src/BitBoard.cpp b/src/BitBoard.cpp index 6eac6bc..f525cbf 100644 --- a/src/BitBoard.cpp +++ b/src/BitBoard.cpp @@ -7,6 +7,7 @@ #include #include "Move.h" #include "BitBoard.h" +#include "Heuristic.hpp" typedef std::unique_ptr bup; typedef std::unique_ptr mup; @@ -248,15 +249,18 @@ bup BitBoard::result(mup &move) const return result; } -double BitBoard::utility(std::string player) const +double BitBoard::utility() const { - if (m_isBlacksTurn) { +// std::cout << h.evalHeuristics(m_blackPieces, m_whitePieces, m_kingPieces); +/* if (m_isBlacksTurn) { std::bitset<32> bits (m_blackPieces); return 12 - bits.count(); } std::bitset<32> bits (m_whitePieces); return bits.count() - 12; +*/ + return 0;// return heuristic.evaluate(m_blackPieces, m_whitePieces, m_kingPieces); } void BitBoard::printState() const diff --git a/src/MinimaxSearch.cpp b/src/MinimaxSearch.cpp index 9a39789..b2ffda6 100644 --- a/src/MinimaxSearch.cpp +++ b/src/MinimaxSearch.cpp @@ -12,9 +12,9 @@ typedef std::unique_ptr mup; /* Private Functions */ -double MinimaxSearch::minValue(bup &board, int currentDepth) const +double MinimaxSearch::minValue(bup &board, int currentDepth) { - if (currentDepth == maxDepth) return board->utility(board->player()); + if (currentDepth == maxDepth) return heuristic.evaluate(board); double v = std::numeric_limits::max(); for (mup &move : board->actions()) { bup result = board->result(move); @@ -23,9 +23,9 @@ double MinimaxSearch::minValue(bup &board, int currentDepth) const return v; } -double MinimaxSearch::maxValue(bup &board, int currentDepth) const +double MinimaxSearch::maxValue(bup &board, int currentDepth) { - if (currentDepth == maxDepth) return board->utility(board->player()); + if (currentDepth == maxDepth) return heuristic.evaluate(board); double v = std::numeric_limits::lowest(); for (mup &move : board->actions()) { bup result = board->result(move); @@ -34,10 +34,9 @@ double MinimaxSearch::maxValue(bup &board, int currentDepth) const return v; } -double MinimaxSearch::alphaBeta(bup &board, double alpha, double beta, int depth) const +double MinimaxSearch::alphaBeta(bup &board, double alpha, double beta, int depth) { - if (depth == maxDepth) return board->utility(board->player()); - + if (depth == maxDepth) return heuristic.evaluate(board); // black is max player here double v; @@ -63,7 +62,7 @@ double MinimaxSearch::alphaBeta(bup &board, double alpha, double beta, int depth } /* Public Functions */ -mup MinimaxSearch::minimaxDecision(bup &board) const +mup MinimaxSearch::minimaxDecision(bup &board) { mup bestMove; double bestMoveValue{0.0}; diff --git a/src/heuristics.cpp b/src/heuristics.cpp deleted file mode 100644 index 95f813c..0000000 --- a/src/heuristics.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include -#include "BitBoard.h" - -/* Heuristic Functions */ - -// counts number of setbits -const int BitBoard::count(uint32_t i) const{ - int cnt; - while(i){ - cnt += i & 1; - i >>= 1; - } - return cnt; - -} - -// current players pieces -uint32_t const BitBoard::playerPieces() const { - return m_isBlacksTurn ? m_blackPieces : m_whitePieces; -} - -void BitBoard::evalHueristics(){ - evalScore = h1() + h2() + h3() + h4() + h5() + h6() + h7() + h8() + h9() + h10(); -} - -// Number of pawns -int BitBoard::h1() const -{ - return count(playerPieces() & ~m_kings); -} - -// Number of kings -int BitBoard::h2() const -{ - return count(playerPieces() & m_kings); -} - -// Number of safe pawns -int BitBoard::h3() const -{ - return count(playerPieces() & ~m_kings & edgeLoc); -} - -// Number of safe kings -int BitBoard::h4() const -{ - return count(playerPieces() & m_kings & edgeLoc); -} - -// Aggregated distance of pawns to promotion line -int BitBoard::h5() const -{ - int aggrDistance = 0; - if(m_isBlacksTurn) - for(int i=0; i<7; i++) - aggrDistance += (7-i)*count(m_blackPieces & m_kings & rowMask(i)); - else - for(int i=1; i<8; i++) - aggrDistance += i*count(m_whitePieces & m_kings & rowMask(i)); - - return aggrDistance; -} - -// Number of defender pieces, closest two rows on players side -int BitBoard::h6() const -{ - if(m_isBlacksTurn) - return count(m_blackPieces & (rowMask(0) | rowMask(1))); - else - return count(m_whitePieces & (rowMask(6) | rowMask(7))); -} - -// Number of attacking pawns, position in upper three most rows, opponents side -int BitBoard::h7() const -{ - if(m_isBlacksTurn) - return count(m_blackPieces & ~m_kings & ( rowMask(7) | rowMask(6) | rowMask(5))); - else - return count(m_whitePieces & ~m_kings & ( rowMask(2) | rowMask(1) | rowMask(0))); -} - -// Number of unoccupied fields on promotion line -int BitBoard::h8() const -{ - if(m_isBlacksTurn) - return count( (m_blackPieces | m_whitePieces) & rowMask(7)); - else - return count( (m_blackPieces | m_whitePieces) & rowMask(0)); -} - -// Number of moveable pawns -int BitBoard::h9() const -{ - uint32_t accumP; - uint32_t emptyPos = ~(m_blackPieces | m_whitePieces); - - if(m_isBlacksTurn) - { - accumP |= rotr32(rotr32(m_blackPieces & ~m_kings & downLeft, 1) & emptyPos, -1); - accumP |= rotl32(rotl32(m_blackPieces & ~m_kings & downRight, 1) & emptyPos, -1); - - } - else - { - accumP |= rotr32(rotr32(m_whitePieces & ~m_kings & upRight, -1) & emptyPos, 1); - accumP |= rotl32(rotl32(m_whitePieces & ~m_kings & upLeft, -1) & emptyPos, 1); - } - return count(accumP); -} - -// Number of moveable kings -int BitBoard::h10() const -{ - uint32_t accumK; - uint32_t kings; - uint32_t emptyPos = ~(m_blackPieces | m_whitePieces); - if(m_isBlacksTurn) - { - kings = m_blackPieces & m_kings; - accumK |= rotr32(rotr32(kings & downLeft, 1) & emptyPos, -1); - accumK |= rotl32(rotl32(kings & downRight, 1) & emptyPos, -1); - accumK |= rotr32(rotr32(kings & upRight, -1) & emptyPos, 1); - accumK |= rotl32(rotl32(kings & upLeft, -1) & emptyPos, 1); - } - else { - kings = m_whitePieces & m_kings; - accumK |= rotr32(rotr32(kings & downLeft, 1) & emptyPos, -1); - accumK |= rotl32(rotl32(kings & downRight, 1) & emptyPos, -1); - accumK |= rotr32(rotr32(kings & upRight, -1) & emptyPos, 1); - accumK |= rotl32(rotl32(kings & upLeft, -1) & emptyPos, 1); - } - return count(accumK); -} - - diff --git a/src/main.cpp b/src/main.cpp index d269c62..86c238c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,7 @@ int main(int argc, const char * argv[]) { std::unique_ptr board (new BitBoard); MinimaxSearch searchDriver; - for (int i = 0; i < 20; ++i) { + for (int i = 0; i < 100; ++i) { board->printState(); std::unique_ptr bestMove = searchDriver.minimaxDecision(board); board = board->result(bestMove);