Skip to content

Commit

Permalink
Merge pull request #1 from mbluemer/move-generation
Browse files Browse the repository at this point in the history
Move generation
  • Loading branch information
mbluemer committed Apr 18, 2017
2 parents 69a5717 + 6554080 commit 4a63697
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 12 deletions.
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;
}

0 comments on commit 4a63697

Please sign in to comment.