Skip to content

Move generation #1

Merged
merged 10 commits into from
Apr 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions include/BitBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <cstdint>
#include <string>
#include <vector>
#include <string>
#include "Move.h"

class BitBoard
Expand Down Expand Up @@ -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 */

Expand Down Expand Up @@ -68,8 +73,20 @@ class BitBoard
int h9() const;
int h10() const;


public:
int const getIndex(uint32_t piece);

void addJumps(std::vector<Move> &moves);
void addNormalMoves(std::vector<Move> &moves);
void generateAllJumps(BitBoard board, Move move, uint32_t piece, std::vector<Move> &moves);
BitBoard boardMove(BitBoard &board, uint32_t piece, uint32_t moveTo);
std::vector<uint32_t> generateImmediateJumps(BitBoard &board, uint32_t piece);
void addNewMove(uint32_t start, uint32_t end, std::vector<Move> &moves);
std::string pieceToString(int piece);

public:
BitBoard();
BitBoard(uint32_t black, uint32_t white, uint32_t kings);

std::string const player();
std::vector<Move> const actions();
BitBoard const result(Move move);
Expand Down
10 changes: 8 additions & 2 deletions include/Move.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define MOVE_H

#include <vector>
#include <cstdint>

class Move
{
Expand All @@ -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<int> getMoves() { return moves; }
};

#endif
210 changes: 209 additions & 1 deletion src/BitBoard.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
#include <cstdint>
#include <limits.h>
#include <string>
#include <vector>
#include <cmath>
#include <iostream>
#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);
Expand All @@ -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<Move> &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<<i : m_whitePieces & 1<<i;
if (piece) {
generateAllJumps(*this, Move(), piece, moves);
}
}
}

void BitBoard::addNormalMoves(std::vector<Move> &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<<i;
if (rotl32(piece, 7) & notOcc & upLeft)
addNewMove(piece, rotl32(piece, 7), moves);
if (rotl32(piece, 1) & notOcc & upRight)
addNewMove(piece, rotl32(piece, 1), moves);
if (piece & m_kings) {
if (rotr32(piece, 7) & notOcc & downRight)
addNewMove(piece, rotr32(piece, 7), moves);
if (rotr32(piece, 1) & notOcc & downLeft)
addNewMove(piece, rotr32(piece, 1), moves);
}
} else {
piece = m_whitePieces & 1<<i;
if (rotr32(piece, 7) & notOcc & downRight)
addNewMove(piece, rotr32(piece, 7), moves);
if (rotr32(piece, 1) & notOcc & downLeft)
addNewMove(piece, rotr32(piece, 1), moves);
if (piece & m_kings) {
if (rotl32(piece, 7) & notOcc & upLeft)
addNewMove(piece, rotl32(piece, 7), moves);
if (rotl32(piece, 1) & notOcc & upRight)
addNewMove(piece, rotl32(piece, 1), moves);
}
}
}
}

void BitBoard::generateAllJumps(BitBoard board, Move move, uint32_t piece, std::vector<Move> &moves)
{
if (move.isEmpty()) move.addMove(getIndex(piece)); // Add start position
std::vector<uint32_t> 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<<avg);
}
black = (black | moveTo) & ~piece;
kings = kings | (black & blackKingSpots);
} else {
if (diff == 2 || diff == 14) black = black & ~(1<<avg);
white = (white | moveTo) & ~piece;
kings = kings | (white & whiteKingSpots);
}

if (piece & kings) kings = moveTo | (kings & ~piece);

return BitBoard(black, white, kings);
}

std::vector<uint32_t> BitBoard::generateImmediateJumps(BitBoard &board, uint32_t piece)
{
std::vector<uint32_t> 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<Move> &moves)
{
Move newMove(getIndex(start));
newMove.addMove(getIndex(end));
moves.push_back(newMove);
}

std::string BitBoard::pieceToString(int piece)
{
uint32_t pieceLoc = 1<<piece;
if (pieceLoc & m_blackPieces)
return (pieceLoc & m_kings) ? "B" : "b";
if (pieceLoc & m_whitePieces)
return (pieceLoc & m_kings) ? "W" : "w";
return "-";
}

/* Public functions */

BitBoard::BitBoard() {};

BitBoard::BitBoard(uint32_t black, uint32_t white, uint32_t kings) :
m_blackPieces(black), m_whitePieces(white), m_kings(kings)
{
m_isBlacksTurn = true;
}

std::string const BitBoard::player()
{
return m_isBlacksTurn ? "black" : "white";
}

std::vector<Move> const BitBoard::actions()
{
std::vector<Move> 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<<start, 1<<x);
start = x;
}
}

currBoard.m_isBlacksTurn = !m_isBlacksTurn;
return currBoard;
}

void const BitBoard::printState()
{
std::cout<<"-"<<pieceToString(11)<<"-"<<pieceToString(5)<<"-"<<pieceToString(31)<<"-"<<pieceToString(25)<<std::endl;
std::cout<<pieceToString(10)<<"-"<<pieceToString(4)<<"-"<<pieceToString(30)<<"-"<<pieceToString(24)<<"-"<<std::endl;
std::cout<<"-"<<pieceToString(3)<<"-"<<pieceToString(29)<<"-"<<pieceToString(23)<<"-"<<pieceToString(17)<<std::endl;
std::cout<<pieceToString(2)<<"-"<<pieceToString(28)<<"-"<<pieceToString(22)<<"-"<<pieceToString(16)<<"-"<<std::endl;
std::cout<<"-"<<pieceToString(27)<<"-"<<pieceToString(21)<<"-"<<pieceToString(15)<<"-"<<pieceToString(9)<<std::endl;
std::cout<<pieceToString(26)<<"-"<<pieceToString(20)<<"-"<<pieceToString(14)<<"-"<<pieceToString(8)<<"-"<<std::endl;
std::cout<<"-"<<pieceToString(19)<<"-"<<pieceToString(13)<<"-"<<pieceToString(7)<<"-"<<pieceToString(1)<<std::endl;
std::cout<<pieceToString(18)<<"-"<<pieceToString(12)<<"-"<<pieceToString(6)<<"-"<<pieceToString(0)<<"-"<<std::endl;
}

25 changes: 23 additions & 2 deletions src/Move.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
#include <iostream>
#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();
}
12 changes: 11 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
#include <iostream>
#include <cstdint>
#include <vector>
#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<Move> moves = board.generateImmediateJumps(16384);
for (Move move : moves) {
for (int x : move.getMoves()) {
std::cout << x << std::endl;
}
}
return 0;
}