diff --git a/include/BitBoard.h b/include/BitBoard.h index 2f55290..f360b92 100644 --- a/include/BitBoard.h +++ b/include/BitBoard.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "Move.h" class BitBoard @@ -32,15 +33,19 @@ class BitBoard return r[index]; } + static const uint32_t whiteKingSpots = 0x00041041; + static const uint32_t blackKingSpots = 0x82000820; + + // Used for determing board from move + static const uint32_t topCorner = 0xC3C; /* Class member variables */ - const uint32_t m_blackPieces = 0x41C71C3; - const uint32_t m_whitePieces = 0xE3820C38; - const uint32_t m_kings = 0; + 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 */ @@ -68,8 +73,20 @@ class BitBoard int h9() const; int h10() const; - - public: + int const getIndex(uint32_t piece); + + void addJumps(std::vector &moves); + void addNormalMoves(std::vector &moves); + void generateAllJumps(BitBoard board, Move move, uint32_t piece, std::vector &moves); + BitBoard boardMove(BitBoard &board, uint32_t piece, uint32_t moveTo); + std::vector generateImmediateJumps(BitBoard &board, uint32_t piece); + void addNewMove(uint32_t start, uint32_t end, std::vector &moves); + std::string pieceToString(int piece); + +public: + BitBoard(); + BitBoard(uint32_t black, uint32_t white, uint32_t kings); + std::string const player(); std::vector const actions(); BitBoard const result(Move move); diff --git a/include/Move.h b/include/Move.h index 648688d..ad8f7b6 100644 --- a/include/Move.h +++ b/include/Move.h @@ -2,6 +2,7 @@ #define MOVE_H #include +#include class Move { @@ -10,8 +11,13 @@ class Move public: - Move() : moves() {}; - void printMessage(); + Move(); + Move(int start); + void addMove(int move); + void removeLast(); + bool isEmpty(); + int length(); + std::vector getMoves() { return moves; } }; #endif diff --git a/src/BitBoard.cpp b/src/BitBoard.cpp index 423eb0f..199e3cb 100644 --- a/src/BitBoard.cpp +++ b/src/BitBoard.cpp @@ -1,11 +1,16 @@ #include #include #include +#include +#include +#include +#include "Move.h" #include "BitBoard.h" /* Private 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 BitBoard::rotl32 (uint32_t n, unsigned int c) const { const unsigned int mask = (CHAR_BIT*sizeof(n)-1); @@ -22,9 +27,212 @@ uint32_t const BitBoard::rotr32 (uint32_t n, unsigned int c) const return (n>>c) | (n<<( (-c)&mask )); } +// Given a piece represented by a binary value return it's index +int const BitBoard::getIndex(uint32_t piece) +{ + return (int)std::log2(piece); +} + +void BitBoard::addJumps(std::vector &moves) +{ + uint32_t notOcc = ~(m_whitePieces|m_blackPieces); + for (int i = 0; i < 32; ++i) { + // grab the specific piece + uint32_t piece = (m_isBlacksTurn) ? m_blackPieces & 1< &moves) +{ + uint32_t notOcc = ~(m_whitePieces|m_blackPieces); + for (int i = 0; i < 32; ++i) { + uint32_t piece; + if (m_isBlacksTurn) { + piece = m_blackPieces & 1< &moves) +{ + if (move.isEmpty()) move.addMove(getIndex(piece)); // Add start position + std::vector immediateJumps = generateImmediateJumps(board, piece); + if (immediateJumps.size() == 0) { + if (move.length() > 1) moves.push_back(move); // If no more jumps add move to list of moves + } else { + for (uint32_t x : immediateJumps) { + move.addMove(getIndex(x)); + generateAllJumps(boardMove(board, piece, x), move, x, moves); + move.removeLast(); + } + } +} + +BitBoard BitBoard::boardMove(BitBoard &board, uint32_t piece, uint32_t moveTo) +{ + // Constructor needs black, white, and kings locations so just derive those and instantiate new board object + uint32_t white = board.m_whitePieces; + uint32_t black = board.m_blackPieces; + uint32_t kings = board.m_kings; + + // First figure out if a piece has been take + int pieceLoc = getIndex(piece); + int moveLoc = getIndex(moveTo); + if (piece & topCorner) pieceLoc += 32; + if (moveTo & topCorner) moveLoc += 32; + int diff = std::abs((double)pieceLoc - moveLoc); + int avg = ((pieceLoc + moveLoc) / 2); + if (board.m_isBlacksTurn) { + if (diff == 2 || diff == 14) { + white &= ~(1< BitBoard::generateImmediateJumps(BitBoard &board, uint32_t piece) +{ + std::vector moves; + uint32_t notOcc = ~(board.m_whitePieces|board.m_blackPieces); + uint32_t temp; + bool isKing = piece & board.m_kings; + if (m_isBlacksTurn) { + temp = (rotl32(piece, 7) & upLeft) & board.m_whitePieces; + if ((rotl32(temp, 7) & upLeft) & notOcc) + moves.push_back(rotl32(temp, 7)); + temp = (rotl32(piece, 1) & upRight) & board.m_whitePieces; + if ((rotl32(temp, 1) & upRight) & notOcc) + moves.push_back(rotl32(temp, 1)); + if (isKing) { + temp = (rotr32(piece, 7) & downRight) & board.m_whitePieces; + if ((rotr32(temp, 7) & downRight) & notOcc) + moves.push_back(rotr32(temp, 7)); + temp = (rotr32(piece, 1) & downLeft) & board.m_whitePieces; + if ((rotr32(temp, 1) & downLeft) & notOcc) + moves.push_back(rotr32(temp, 1)); + } + } else { + temp = (rotr32(piece, 7) & downRight) & board.m_blackPieces; + if ((rotr32(temp, 7) & downRight) & notOcc) + moves.push_back(rotr32(temp, 7)); + temp = (rotr32(piece, 1) & downLeft) & board.m_blackPieces; + if ((rotr32(temp, 1) & downLeft) & notOcc) + moves.push_back(rotr32(temp, 1)); + if (isKing) { + temp = (rotl32(piece, 7) & upLeft) & board.m_blackPieces; + if ((rotl32(temp, 7) & upLeft) & notOcc) + moves.push_back(rotl32(temp, 7)); + temp = (rotl32(piece, 1) & upRight) & board.m_blackPieces; + if ((rotl32(temp, 1) & upRight) & notOcc) + moves.push_back(rotl32(temp, 1)); + } + } + return moves; +} + +void BitBoard::addNewMove(uint32_t start, uint32_t end, std::vector &moves) +{ + Move newMove(getIndex(start)); + newMove.addMove(getIndex(end)); + moves.push_back(newMove); +} + +std::string BitBoard::pieceToString(int piece) +{ + uint32_t pieceLoc = 1< const BitBoard::actions() +{ + std::vector moves; + addJumps(moves); + if (moves.empty()) { + addNormalMoves(moves); + } + + return moves; +} + +BitBoard const BitBoard::result(Move move) +{ + BitBoard currBoard = *this; + int start{-1}; + for (int x : move.getMoves()) { + if (start == -1) { + start = x; + } else { + currBoard = boardMove(currBoard, 1< #include "Move.h" -void Move::printMessage() +Move::Move() : moves() {}; + +Move::Move(int start) +{ + moves = {start}; +} + +void Move::addMove(int move) +{ + moves.push_back(move); +} + +void Move::removeLast() +{ + moves.pop_back(); +} + +bool Move::isEmpty() +{ + return moves.empty(); +} + int Move::length() { - std::cout << "Here is an example message" << std::endl; + return moves.size(); } diff --git a/src/main.cpp b/src/main.cpp index 2a87151..feead06 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,16 @@ #include +#include +#include +#include "BitBoard.h" +#include "Move.h" int main(int argc, const char * argv[]) { - std::cout << "Hello world!" << std::endl; + BitBoard board(16384, 2097280, 16384); + std::vector moves = board.generateImmediateJumps(16384); + for (Move move : moves) { + for (int x : move.getMoves()) { + std::cout << x << std::endl; + } + } return 0; }