diff --git a/include/BitBoard.h b/include/BitBoard.h index 1d1b9dc..637a901 100644 --- a/include/BitBoard.h +++ b/include/BitBoard.h @@ -12,31 +12,59 @@ class BitBoard /* Static bit masks */ // Used to determine whether a move from that direction is valid - static const uint32_t upRight = 0xFBFBEBBA; - static const uint32_t upLeft = 0xFDF9EDBC; - static const uint32_t downRight = 0x79FBF3DB; - static const uint32_t downLeft = 0x7DFDF5DD; + static const uint32_t upRight = 0xFBFBEBBA; + static const uint32_t upLeft = 0xFDF9EDBC; + static const uint32_t downRight = 0x79FBF3DB; + static const uint32_t downLeft = 0x7DFDF5DD; + + // Edge locations, all 4 sides + static const uint32_t edgeLoc = 0x86061E67; + + /* Class member variables */ + const uint32_t m_blackPieces = 0x41C71C3; + const uint32_t m_whitePieces = 0xE3820C38; + const uint32_t m_kings = 0; + + bool m_isBlacksTurn = true; - /* Class member variables */ - const uint32_t m_blackPieces = 0x41C71C3; - const uint32_t m_whitePieces = 0xE3820C38; - const uint32_t m_kings = 0; + static const uint32_t rowMask(int index){ + static const uint32_t r [] = { 0x00041041, + 0x00082082, + 0x04104100, + 0x08208200, + 0x10410004, + 0x20820008, + 0x41104010, + 0x82100820}; + return r[index]; + } - bool m_isBlacksTurn = true; - - /* Class member functions */ - - // These are basic 32 bit rotation functions - // Details here: http://stackoverflow.com/questions/776508/best-practices-for-circular-shift-rotate-operations-in-c - uint32_t const rotl32 (uint32_t n, unsigned int c); - uint32_t const rotr32 (uint32_t n, unsigned int c); - -public: - - std::string const player(); - std::vector const actions(); - BitBoard const result(Move move); - void const printState(); + // static constexpr uint32_t rowMask[8]; + /* Class member functions */ + + // These are basic 32 bit rotation functions + // Details here: http://stackoverflow.com/questions/776508/best-practices-for-circular-shift-rotate-operations-in-c + uint32_t const rotl32 (uint32_t n, unsigned int c); + uint32_t const rotr32 (uint32_t n, unsigned int c); + + uint32_t const playerPieces(); + + int count(uint32_t i); + // Heuristic functions + int h1(); + int h2(); + int h3(); + int h4(); + int h5(); + int h6(); + int h7(); + int h8(); + + public: + std::string const player(); + std::vector const actions(); + BitBoard const result(Move move); + void const printState(); }; #endif diff --git a/src/BitBoard.cpp b/src/BitBoard.cpp index 590bb26..0390baa 100644 --- a/src/BitBoard.cpp +++ b/src/BitBoard.cpp @@ -5,6 +5,7 @@ /* Private Functions */ + uint32_t const BitBoard::rotl32 (uint32_t n, unsigned int c) { const unsigned int mask = (CHAR_BIT*sizeof(n)-1); diff --git a/src/heuristics.cpp b/src/heuristics.cpp index 14ea28a..038623d 100644 --- a/src/heuristics.cpp +++ b/src/heuristics.cpp @@ -6,8 +6,8 @@ /* Heuristic Functions */ // counts number of setbits -int const count(uint32_t i){ - unt cnt; +int BitBoard::count(uint32_t i){ + int cnt; while(i){ cnt += i & 1; i >>= 1; @@ -18,90 +18,74 @@ int const count(uint32_t i){ // current players pieces uint32_t const BitBoard::playerPieces(){ - return misBLacksTurn ? m_blackPieces : m_whitePieces; + return m_isBlacksTurn ? m_blackPieces : m_whitePieces; } // Number of pawns -int const BitBoard::h1() +int BitBoard::h1() { return count(playerPieces() & ~m_kings); } // Number of kings -int const BitBoard::h2() +int BitBoard::h2() { return count(playerPieces() & m_kings); } // Number of safe pawns -int const BitBoard::h3() +int BitBoard::h3() { return count(playerPieces() & ~m_kings & edgeLoc); } // Number of safe kings -int const BitBoard::h4() +int BitBoard::h4() { return count(playerPieces() & m_kings & edgeLoc); } // Aggregated distance of pawns to promotion line -int const BitBoard::h5() +int BitBoard::h5() { int aggrDistance = 0; if(m_isBlacksTurn) - for(int i=0, i<7; i++) - aggrDistance += (7-i)*count(m_blackPieces & m_kings & rowMask[i]); + 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]); + 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 const BitBoard::h6() +int BitBoard::h6() { if(m_isBlacksTurn) - return count(m_blackPieces & (rowMask[0] | rowMask[1])); + return count(m_blackPieces & (rowMask(0) | rowMask(1))); else - return count(m_whitePieces & (rowMask[6] | rowMask[7])); + return count(m_whitePieces & (rowMask(6) | rowMask(7))); } // Number of attacking pawns, position in upper three most rows, opponents side -int const BitBoard::h7() +int BitBoard::h7() { if(m_isBlacksTurn) - return count(m_blackPieces & ~m_kings & ( rowMask[7] | rowMask[6] | rowMask[5])); + 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])); + return count(m_whitePieces & ~m_kings & ( rowMask(2) | rowMask(1) | rowMask(0))); } // Number of unoccupied fields on promotion line -int const BitBoard::h8() +int BitBoard::h8() { if(m_isBlacksTurn) - return count( (m_blackPieces | m_whitePieces) & rowMask[7]); + return count( (m_blackPieces | m_whitePieces) & rowMask(7)); else - return count( (m_blackPieces | m_whitePieces) & rowMask[0]); + return count( (m_blackPieces | m_whitePieces) & rowMask(0)); } -uint32_t const BitBoard::rotl32 (uint32_t n, unsigned int c) -{ - const unsigned int mask = (CHAR_BIT*sizeof(n)-1); - - c &= mask; // avoid undef behaviour with NDEBUG. 0 overhead for most types / compilers - return (n<>( (-c)&mask )); -} - -uint32_t const BitBoard::rotr32 (uint32_t n, unsigned int c) -{ - const unsigned int mask = (CHAR_BIT*sizeof(n)-1); - - c &= mask; // avoid undef behaviour with NDEBUG. 0 overhead for most types / compilers - return (n>>c) | (n<<( (-c)&mask )); -} -