Created
April 12, 2012 09:54
-
-
Save crisu83/2366059 to your computer and use it in GitHub Desktop.
OgreChess Position.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Game constants. | |
#define A_FILE 0x0101010101010101 | |
#define B_FILE 0x202020202020202 | |
#define C_FILE 0x404040404040404 | |
#define D_FILE 0x808080808080808 | |
#define E_FILE 0x1010101010101010 | |
#define F_FILE 0x2020202020202020 | |
#define G_FILE 0x4040404040404040 | |
#define H_FILE 0x8080808080808080 | |
#define FIRST_RANK 0x00000000000000FF | |
#define EIGHT_RANK 0xFF00000000000000 | |
#define THIRD_RANK 0x0000000000FF0000 | |
#define SIXTH_RANK 0x0000FF0000000000 | |
#define D1C1B1_MASK 0x000000000000000E | |
#define F1G1_MASK 0x0000000000000060 | |
#define F8G8_MASK 0x6000000000000000 | |
#define D8C8B8_MASK 0xE00000000000000 | |
#define A1_MASK 0x0000000000000001 | |
#define H1_MASK 0x0000000010000000 | |
#define A8_MASK 0x0100000000000000 | |
#define H8_MASK 0x8000000000000000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
Position::Position(void) | |
: mTurn(0) | |
{ | |
} | |
Position::~Position(void) | |
{ | |
} | |
void Position::setup(void) | |
{ | |
} | |
/** | |
Returns all legal moves in the current situation. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
std::vector<std::vector<UI64>> Position::genLegalMoves(UI64 bitboards[]) | |
{ | |
int count = 0; | |
std::vector<UI64> tmp; | |
UI64 pieces, current, moves; | |
mMoves.clear(); | |
// White player moves. | |
if (mTurn == WHITE) | |
{ | |
if (whiteChecked(bitboards)) | |
{ | |
// White player is checked. | |
pieces = bitboards[W_PAWN]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = wBlockCheck(current, pawnMoves(current, bitboards[EMPTYSQUARES], bitboards, WHITE), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_KNIGHT]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = wBlockCheck(current, knightMoves(current, bitboards[W_PIECES]), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_BISHOP]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = wBlockCheck(current, bishopMoves(current, bitboards[EMPTYSQUARES], bitboards[W_PIECES]), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_ROOK]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = wBlockCheck(current, rookMoves(current, bitboards[EMPTYSQUARES], bitboards[W_PIECES]), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_QUEEN]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = wBlockCheck(current, queenMoves(current, bitboards[EMPTYSQUARES], bitboards[W_PIECES]), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
moves = wEscapeMoves(bitboards); | |
addMoves(bitboards[W_KING], moves); | |
} | |
else | |
{ | |
// White player is not checked. | |
if ((bitboards[CASTLING] & A1_MASK) && !(D1C1B1_MASK & ~bitboards[EMPTYSQUARES]) && !(D1C1B1_MASK & bAttacks(bitboards))) | |
{ | |
tmp.insert(tmp.end(), bitboards[W_KING]); | |
tmp.insert(tmp.end(), bitboards[W_KING] >> 2); | |
mMoves.insert(mMoves.end(), tmp); | |
} | |
if ((bitboards[CASTLING] & H1_MASK) && !(F1G1_MASK & ~bitboards[EMPTYSQUARES]) && !(F1G1_MASK & bAttacks(bitboards))) | |
{ | |
tmp.insert(tmp.end(), bitboards[W_KING]); | |
tmp.insert(tmp.end(), bitboards[W_KING] << 2); | |
mMoves.insert(mMoves.end(), tmp); | |
} | |
pieces = bitboards[W_PAWN]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = pawnMoves(current, bitboards[EMPTYSQUARES], bitboards, WHITE); | |
moves = wPiecePinned(current, bitboards) ? wPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_KNIGHT]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = knightMoves(current, bitboards[W_PIECES]); | |
moves = wPiecePinned(current, bitboards) ? wPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_BISHOP]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = bishopMoves(current, bitboards[EMPTYSQUARES], bitboards[W_PIECES]); | |
moves = wPiecePinned(current, bitboards) ? wPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_ROOK]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = rookMoves(current, bitboards[EMPTYSQUARES], bitboards[W_PIECES]); | |
moves = wPiecePinned(current, bitboards) ? wPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_QUEEN]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = queenMoves(current, bitboards[EMPTYSQUARES], bitboards[W_PIECES]); | |
moves = wPiecePinned(current, bitboards) ? wPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
moves = kingMoves(bitboards[W_KING], bitboards[W_PIECES], bitboards); | |
addMoves(bitboards[W_KING], moves); | |
} | |
} | |
// Black player moves. | |
else | |
{ | |
if (blackChecked(bitboards)) | |
{ | |
// Black player is checked. | |
pieces = bitboards[B_PAWN]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = bBlockCheck(current, pawnMoves(current, bitboards[EMPTYSQUARES], bitboards, BLACK), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[B_KNIGHT]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = bBlockCheck(current, knightMoves(current, bitboards[B_PIECES]), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[B_BISHOP]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = bBlockCheck(current, bishopMoves(current, bitboards[EMPTYSQUARES], bitboards[B_PIECES]), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[B_ROOK]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = bBlockCheck(current, rookMoves(current, bitboards[EMPTYSQUARES], bitboards[B_PIECES]), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[B_QUEEN]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = bBlockCheck(current, queenMoves(current, bitboards[EMPTYSQUARES], bitboards[B_PIECES]), bitboards); | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
moves = bEscapeMoves(bitboards); | |
addMoves(bitboards[B_KING], moves); | |
} | |
else | |
{ | |
// Black player is not checked. | |
if ((bitboards[CASTLING] & A8_MASK) && !(D8C8B8_MASK & ~bitboards[EMPTYSQUARES]) && !(D8C8B8_MASK & wAttacks(bitboards))) | |
{ | |
tmp.insert(tmp.end(), bitboards[B_KING]); | |
tmp.insert(tmp.end(), bitboards[B_KING] >> 2); | |
mMoves.insert(mMoves.end(), tmp); | |
} | |
if ((bitboards[CASTLING] & H8_MASK) && !(F8G8_MASK & ~bitboards[EMPTYSQUARES]) && !(F8G8_MASK & wAttacks(bitboards))) | |
{ | |
tmp.insert(tmp.end(), bitboards[B_KING]); | |
tmp.insert(tmp.end(), bitboards[B_KING] << 2); | |
mMoves.insert(mMoves.end(), tmp); | |
} | |
pieces = bitboards[B_PAWN]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = pawnMoves(current, bitboards[EMPTYSQUARES], bitboards, BLACK); | |
moves = bPiecePinned(current, bitboards) ? bPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_KNIGHT]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = knightMoves(current, bitboards[B_PIECES]); | |
moves = bPiecePinned(current, bitboards) ? bPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_BISHOP]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = bishopMoves(current, bitboards[EMPTYSQUARES], bitboards[B_PIECES]); | |
moves = bPiecePinned(current, bitboards) ? bPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_ROOK]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = rookMoves(current, bitboards[EMPTYSQUARES], bitboards[B_PIECES]); | |
moves = bPiecePinned(current, bitboards) ? bPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
pieces = bitboards[W_QUEEN]; | |
while (pieces != 0) | |
{ | |
current = pieces & -pieces; | |
moves = queenMoves(current, bitboards[EMPTYSQUARES], bitboards[B_PIECES]); | |
moves = bPiecePinned(current, bitboards) ? bPinnedMoves(current, moves, bitboards) : moves; | |
addMoves(current, moves); | |
pieces &= pieces - 1; | |
} | |
moves = kingMoves(bitboards[B_KING], bitboards[B_PIECES], bitboards); | |
addMoves(bitboards[B_KING], moves); | |
} | |
} | |
return mMoves; | |
} | |
/** | |
Returns whether the white player is checked. | |
@return The result. | |
*/ | |
bool Position::whiteChecked(UI64 bitboards[]) | |
{ | |
return (bAttacks(bitboards) & bitboards[W_KING]) != 0; | |
} | |
/** | |
Returns whether the black player is checked. | |
@return The result. | |
*/ | |
bool Position::blackChecked(UI64 bitboards[]) | |
{ | |
return (wAttacks(bitboards) & bitboards[B_KING]) != 0; | |
} | |
/** | |
Evaluates the game situation. | |
@param bitboards The bitboards. | |
@return The result. | |
*/ | |
double Position::evaluate(UI64 bitboards[]) | |
{ | |
int wKingCount, wQueenCount, wRookCount, wBishopCount, wKnightCount, wPawnCount; | |
int wMoveCount, wDoublePawnCount, wIsolatedCount; | |
int bKingCount, bQueenCount, bRookCount, bBishopCount, bKnightCount, bPawnCount; | |
int bMoveCount, bDoublePawnCount, bIsolatedCount; | |
double material, mobility, doubled, isolated; | |
UI64 isolatedWest, isolatedEast; | |
wKingCount = 1; | |
wQueenCount = itemCount(bitboards[W_QUEEN]); | |
wRookCount = itemCount(bitboards[W_ROOK]); | |
wBishopCount = itemCount(bitboards[W_BISHOP]); | |
wKnightCount = itemCount(bitboards[W_KNIGHT]); | |
wPawnCount = itemCount(bitboards[W_PAWN]); | |
bKingCount = 1; | |
bQueenCount = itemCount(bitboards[B_QUEEN]); | |
bRookCount = itemCount(bitboards[B_ROOK]); | |
bBishopCount = itemCount(bitboards[B_BISHOP]); | |
bKnightCount = itemCount(bitboards[B_KNIGHT]); | |
bPawnCount = itemCount(bitboards[B_PAWN]); | |
// Material balance | |
material = 1000 * (wKingCount - bKingCount) | |
+ 9 * (wQueenCount - bQueenCount) | |
+ 5 * (wRookCount - bRookCount) | |
+ 3.25 * (wBishopCount - bBishopCount) | |
+ 3.00 * (wKnightCount - bKnightCount) | |
+ 1 * (wPawnCount - bPawnCount); | |
// Mobility | |
wMoveCount = itemCount(wMoves(bitboards)); | |
bMoveCount = itemCount(bMoves(bitboards)); | |
mobility = wMoveCount - bMoveCount; | |
// Double pawns | |
wDoublePawnCount = doublePawnCount(bitboards[W_PAWN]); | |
bDoublePawnCount = doublePawnCount(bitboards[B_PAWN]); | |
doubled = wDoublePawnCount - bDoublePawnCount; | |
// Isolated pawns | |
isolatedWest = bitboards[W_PAWN] & ~(fillNorth(bitboards[W_PAWN]) | fillSouth(bitboards[W_PAWN])) >> 1; | |
isolatedEast = bitboards[W_PAWN] & ~(fillNorth(bitboards[W_PAWN]) | fillSouth(bitboards[W_PAWN])) << 1; | |
wIsolatedCount = itemCount(isolatedWest & isolatedEast); | |
isolatedWest = bitboards[W_PAWN] & ~(fillNorth(bitboards[B_PAWN]) | fillSouth(bitboards[B_PAWN])) >> 1; | |
isolatedEast = bitboards[W_PAWN] & ~(fillNorth(bitboards[B_PAWN]) | fillSouth(bitboards[B_PAWN])) << 1; | |
bIsolatedCount = itemCount(isolatedWest & isolatedEast); | |
isolated = wIsolatedCount - bIsolatedCount; | |
return material + (0.3 * mobility) - 0.5 * (doubled + isolated); | |
} | |
/* ----------------------------------------------------------------------------------------------- | |
MOVE GENERATION | |
----------------------------------------------------------------------------------------------- */ | |
// KING | |
/** | |
Returns all possible king moves. | |
@param king The king. | |
@param own The own pieces. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::kingMoves(UI64 king, UI64 own, UI64 bitboards[]) | |
{ | |
UI64 moves = ((king << 1) & ~A_FILE) | ((king >> 1) & ~H_FILE); // left-right | |
moves |= (king << 8) | (king >> 8); // up-down | |
moves |= ((king >> 7) & ~A_FILE) | ((king >> 9) & ~H_FILE); // diagonal down | |
moves |= ((king << 9) & ~A_FILE) | ((king << 7) & ~H_FILE); // diagonal up | |
return moves & ~own; | |
} | |
// QUEEN | |
/** | |
Returns all possible queen moves. | |
@param queen The queen. | |
@param emptySquares The emptySquares squares. | |
@param own The own pieces. | |
@return The moves. | |
*/ | |
UI64 Position::queenMoves(UI64 queen, UI64 emptySquares, UI64 own) | |
{ | |
return rookMoves(queen, emptySquares, own) | bishopMoves(queen, emptySquares, own); | |
} | |
/** | |
Returns all possible queen escape moves. | |
@param queen The queen. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::queenEscapeMoves(UI64 queen, UI64 emptySquares) | |
{ | |
return rookEscapeMoves(queen, emptySquares) | bishopEscapeMoves(queen, emptySquares); | |
} | |
// ROOK | |
/** | |
Returns all the rook east moves. | |
@param rooks The rooks. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::rookEast(UI64 rooks, UI64 emptySquares) | |
{ | |
emptySquares &= ~A_FILE; | |
rooks |= emptySquares & (rooks << 1); | |
rooks |= emptySquares & (rooks << 1); | |
rooks |= emptySquares & (rooks << 1); | |
rooks |= emptySquares & (rooks << 1); | |
rooks |= emptySquares & (rooks << 1); | |
rooks |= emptySquares & (rooks << 1); | |
return ~A_FILE & (rooks << 1); | |
} | |
/** | |
Returns all the rook west moves. | |
@param rooks The rooks. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::rookWest(UI64 rooks, UI64 emptySquares) | |
{ | |
emptySquares &= ~H_FILE; | |
rooks |= emptySquares & (rooks >> 1); | |
rooks |= emptySquares & (rooks >> 1); | |
rooks |= emptySquares & (rooks >> 1); | |
rooks |= emptySquares & (rooks >> 1); | |
rooks |= emptySquares & (rooks >> 1); | |
rooks |= emptySquares & (rooks >> 1); | |
return ~H_FILE & (rooks >> 1); | |
} | |
/** | |
Returns all the rook north moves. | |
@param rooks The rooks. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::rookNorth(UI64 rooks, UI64 emptySquares) | |
{ | |
rooks |= emptySquares & (rooks << 8); | |
rooks |= emptySquares & (rooks << 8); | |
rooks |= emptySquares & (rooks << 8); | |
rooks |= emptySquares & (rooks << 8); | |
rooks |= emptySquares & (rooks << 8); | |
rooks |= emptySquares & (rooks << 8); | |
return (rooks << 8); | |
} | |
/** | |
Returns all the rook south moves. | |
@param rooks The rooks. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::rookSouth(UI64 rooks, UI64 emptySquares) | |
{ | |
rooks |= emptySquares & (rooks >> 8); | |
rooks |= emptySquares & (rooks >> 8); | |
rooks |= emptySquares & (rooks >> 8); | |
rooks |= emptySquares & (rooks >> 8); | |
rooks |= emptySquares & (rooks >> 8); | |
rooks |= emptySquares & (rooks >> 8); | |
return (rooks >> 8); | |
} | |
/** | |
Returns all possible rook moves. | |
@param rooks The rooks. | |
@param emptySquares The emptySquares squares. | |
@param own The own pieces. | |
@return The moves. | |
*/ | |
UI64 Position::rookMoves(UI64 rooks, UI64 emptySquares, UI64 own) | |
{ | |
return rookEscapeMoves(rooks, emptySquares) & ~own; | |
} | |
/** | |
Returns all possible rook escape moves. | |
@param rooks The rooks. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::rookEscapeMoves(UI64 rooks, UI64 emptySquares) | |
{ | |
return rookWest(rooks, emptySquares) | rookEast(rooks, emptySquares) | rookNorth(rooks, emptySquares) | rookSouth(rooks, emptySquares); | |
} | |
// BISHOP | |
/** | |
Returns all the bishop north-east moves. | |
@param bishops The bishops. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::bishopNE(UI64 bishops, UI64 emptySquares) | |
{ | |
emptySquares &= ~A_FILE; | |
bishops |= emptySquares & (bishops << 9); | |
bishops |= emptySquares & (bishops << 9); | |
bishops |= emptySquares & (bishops << 9); | |
bishops |= emptySquares & (bishops << 9); | |
bishops |= emptySquares & (bishops << 9); | |
bishops |= emptySquares & (bishops << 9); | |
return ~A_FILE & (bishops << 9); | |
} | |
/** | |
Returns all the bishop north-west moves. | |
@param bishops The bishops. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::bishopNW(UI64 bishops, UI64 emptySquares) | |
{ | |
emptySquares &= ~H_FILE; | |
bishops |= emptySquares & (bishops << 7); | |
bishops |= emptySquares & (bishops << 7); | |
bishops |= emptySquares & (bishops << 7); | |
bishops |= emptySquares & (bishops << 7); | |
bishops |= emptySquares & (bishops << 7); | |
bishops |= emptySquares & (bishops << 7); | |
return ~H_FILE & (bishops << 7); | |
} | |
/** | |
Returns all the bishop south-west moves. | |
@param bishops The bishops. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::bishopSW(UI64 bishops, UI64 emptySquares) | |
{ | |
emptySquares &= ~H_FILE; | |
bishops |= emptySquares & (bishops >> 9); | |
bishops |= emptySquares & (bishops >> 9); | |
bishops |= emptySquares & (bishops >> 9); | |
bishops |= emptySquares & (bishops >> 9); | |
bishops |= emptySquares & (bishops >> 9); | |
bishops |= emptySquares & (bishops >> 9); | |
return ~H_FILE & (bishops >> 9); | |
} | |
/** | |
Returns all the bishop south-east moves. | |
@param bishops The bishops. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::bishopSE(UI64 bishops, UI64 emptySquares) | |
{ | |
emptySquares &= ~A_FILE; | |
bishops |= emptySquares & (bishops >> 7); | |
bishops |= emptySquares & (bishops >> 7); | |
bishops |= emptySquares & (bishops >> 7); | |
bishops |= emptySquares & (bishops >> 7); | |
bishops |= emptySquares & (bishops >> 7); | |
bishops |= emptySquares & (bishops >> 7); | |
return ~A_FILE & (bishops >> 7); | |
} | |
/** | |
Returns all possible bishop moves. | |
@param bishops The bishops. | |
@param emptySquares The emptySquares squares. | |
@param own The own pieces. | |
@return The moves. | |
*/ | |
UI64 Position::bishopMoves(UI64 bishops, UI64 emptySquares, UI64 own) | |
{ | |
return bishopEscapeMoves(bishops, emptySquares) & ~own; | |
} | |
/** | |
Returns all possible bishop escape moves. | |
@param bishops The bishops. | |
@param emptySquares The emptySquares squares. | |
@return The moves. | |
*/ | |
UI64 Position::bishopEscapeMoves(UI64 bishops, UI64 emptySquares) | |
{ | |
return bishopNE(bishops, emptySquares) | bishopNW(bishops, emptySquares) | bishopSE(bishops, emptySquares) | bishopSW(bishops, emptySquares); | |
} | |
// KNIGHT | |
/** | |
Returns all knight north-north-east moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightNNE(UI64 knights) | |
{ | |
return (knights << 17) & ~A_FILE; | |
} | |
/** | |
Returns all knight north-east-east moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightNEE(UI64 knights) | |
{ | |
return (knights << 10) & ~(A_FILE | B_FILE); | |
} | |
/** | |
Returns all knight south-east-east moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightSEE(UI64 knights) | |
{ | |
return (knights >> 6) & ~(A_FILE | B_FILE); | |
} | |
/** | |
Returns all knight south-south-east moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightSSE(UI64 knights) | |
{ | |
return (knights >> 15) & ~A_FILE; | |
} | |
/** | |
Returns all knight north-north-west moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightNNW(UI64 knights) | |
{ | |
return (knights << 15) & ~H_FILE; | |
} | |
/** | |
Returns all knight north-west-west moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightNWW(UI64 knights) | |
{ | |
return (knights << 6) & ~(G_FILE | H_FILE); | |
} | |
/** | |
Returns all knight south-west-west moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightSWW(UI64 knights) | |
{ | |
return (knights >> 10) & ~(G_FILE | H_FILE); | |
} | |
/** | |
Returns all knight south-south-west moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightSSW(UI64 knights) | |
{ | |
return (knights >> 17) & ~H_FILE; | |
} | |
/** | |
Returns all possible knight moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightMoves(UI64 knights, UI64 own) | |
{ | |
return knightEscapeMoves(knights) & ~own; | |
} | |
/** | |
Returns all possible knight escape moves. | |
@param knights The knights. | |
@return The moves. | |
*/ | |
UI64 Position::knightEscapeMoves(UI64 knights) | |
{ | |
return knightNNE(knights) | knightNEE(knights) | knightSEE(knights) | knightSSE(knights) | knightNNW(knights) | knightNWW(knights) | knightSWW(knights) | knightSSW(knights); | |
} | |
// PAWN | |
/** | |
Returns all single push targets for pawns of the given color. | |
@param pawns The pawns. | |
@param emptySquares The emptySquares squares. | |
@param color The piece color (0 = White, 1 = Black). | |
@return The push targets. | |
*/ | |
UI64 Position::singlePushTargets(UI64 pawns, UI64 emptySquares, int color) | |
{ | |
return color == WHITE | |
? (pawns << 8) & emptySquares | |
: (pawns >> 8) & emptySquares; | |
} | |
/** | |
Returns all double push targets for pawns of the given color. | |
@param wPawns The pawns. | |
@param emptySquares The emptySquares squares. | |
@param color The piece color (0 = White, 1 = Black). | |
@return The push targets. | |
*/ | |
UI64 Position::doublePushTargets(UI64 pawns, UI64 emptySquares, int color) | |
{ | |
return color == WHITE | |
? ((singlePushTargets(pawns, emptySquares, color) << 8) & emptySquares) & 0x00000000FF000000 // rank 4 | |
: ((singlePushTargets(pawns, emptySquares, color) >> 8) & emptySquares) & 0x000000FF00000000; // rank 5 | |
} | |
/** | |
Returns all pawn attacks for the given color. | |
@param pawns The pawns. | |
@param color The piece color (0 = White, 1 = Black). | |
@return The attacks. | |
*/ | |
UI64 Position::pawnAttacks(UI64 pawns, int color) | |
{ | |
return color == WHITE | |
? ((pawns << 9) & ~A_FILE) | ((pawns << 7) & ~H_FILE) | |
: ((pawns >> 7) & ~A_FILE) | ((pawns >> 9) & ~H_FILE); | |
} | |
/** | |
Returns all possible moves for pawns of the given color. | |
@param pawns The pawns. | |
@param emptySquares The emptySquares squares. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::pawnMoves(UI64 pawns, UI64 emptySquares, UI64 bitboards[], int color) | |
{ | |
UI64 moves = pawnAttacks(pawns, color) & (bitboards[B_PIECES] | bitboards[ENPASSANT]); | |
moves |= singlePushTargets(pawns, emptySquares, color); | |
moves |= doublePushTargets(pawns, emptySquares, color); | |
return moves; | |
} | |
/* ----------------------------------------------------------------------------------------------- | |
AI | |
----------------------------------------------------------------------------------------------- */ | |
/** | |
Returns all possible attacks for the white player. | |
@param bitboards The bitboards. | |
@return The attacks. | |
*/ | |
UI64 Position::wAttacks(UI64 bitboards[]) | |
{ | |
UI64 attacks = pawnAttacks(bitboards[W_PAWN], WHITE); | |
attacks |= knightMoves(bitboards[W_KNIGHT], bitboards[W_PIECES]); | |
attacks |= rookMoves(bitboards[W_ROOK], bitboards[EMPTYSQUARES], bitboards[W_PIECES]); | |
attacks |= bishopMoves(bitboards[W_BISHOP], bitboards[EMPTYSQUARES], bitboards[W_PIECES]); | |
attacks |= queenMoves(bitboards[W_QUEEN], (bitboards[EMPTYSQUARES]), (bitboards[W_PIECES])); | |
attacks |= kingMoves(bitboards[W_KING], bitboards[W_PIECES], bitboards); | |
return attacks; | |
} | |
/** | |
Returns all possible attacks for the black player. | |
@param bitboards The bitboards. | |
@return The attacks. | |
*/ | |
UI64 Position::bAttacks(UI64 bitboards[]) | |
{ | |
UI64 attacks = pawnAttacks(bitboards[B_PAWN], BLACK); | |
attacks |= knightMoves(bitboards[B_KNIGHT], bitboards[B_PIECES]); | |
attacks |= rookMoves(bitboards[B_ROOK], bitboards[EMPTYSQUARES], bitboards[B_PIECES]); | |
attacks |= bishopMoves(bitboards[B_BISHOP], bitboards[EMPTYSQUARES], bitboards[B_PIECES]); | |
attacks |= queenMoves(bitboards[B_QUEEN], (bitboards[EMPTYSQUARES]), (bitboards[B_PIECES])); | |
attacks |= kingMoves(bitboards[B_KING], bitboards[B_PIECES], bitboards); | |
return attacks; | |
} | |
/** | |
Returns all possible moves for the white player. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::wMoves(UI64 bitboards[]) | |
{ | |
UI64 moves = pawnMoves(bitboards[W_PAWN], bitboards[EMPTYSQUARES], bitboards, WHITE); | |
moves |= knightMoves(bitboards[W_KNIGHT], bitboards[W_PIECES]); | |
moves |= rookMoves(bitboards[W_ROOK], bitboards[EMPTYSQUARES], bitboards[W_PIECES]); | |
moves |= bishopMoves(bitboards[W_BISHOP], bitboards[EMPTYSQUARES], bitboards[W_PIECES]); | |
moves |= queenMoves(bitboards[W_QUEEN], (bitboards[EMPTYSQUARES]), (bitboards[W_PIECES])); | |
moves |= kingMoves(bitboards[W_KING], bitboards[W_PIECES],bitboards); | |
return moves; | |
} | |
/** | |
Returns all possible moves for the black player. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::bMoves(UI64 bitboards[]) | |
{ | |
UI64 moves = pawnMoves(bitboards[B_PAWN], bitboards[EMPTYSQUARES], bitboards, WHITE); | |
moves |= knightMoves(bitboards[B_KNIGHT], bitboards[B_PIECES]); | |
moves |= rookMoves(bitboards[B_ROOK], bitboards[EMPTYSQUARES], bitboards[B_PIECES]); | |
moves |= bishopMoves(bitboards[B_BISHOP], bitboards[EMPTYSQUARES], bitboards[B_PIECES]); | |
moves |= queenMoves(bitboards[B_QUEEN], (bitboards[EMPTYSQUARES]), (bitboards[B_PIECES])); | |
moves |= kingMoves(bitboards[B_KING], bitboards[B_PIECES],bitboards); | |
return moves; | |
} | |
/** | |
Returns all possible escape moves for the white player. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::wEscapeMoves(UI64 bitboards[]) | |
{ | |
UI64 moves = kingMoves(bitboards[W_KING], bitboards[W_PIECES], bitboards); | |
UI64 attacks = pawnAttacks(bitboards[B_PAWN], BLACK); | |
attacks |= kingMoves(bitboards[B_KING], bitboards[B_PIECES], bitboards); | |
attacks |= knightEscapeMoves(bitboards[B_KNIGHT]); | |
attacks |= rookMoves(bitboards[B_ROOK], bitboards[EMPTYSQUARES] | bitboards[W_KING], bitboards[B_PIECES] & ~moves); | |
attacks |= bishopMoves(bitboards[B_BISHOP], bitboards[EMPTYSQUARES] | bitboards[W_KING], bitboards[B_PIECES] & ~moves); | |
attacks |= queenMoves(bitboards[B_QUEEN], bitboards[EMPTYSQUARES] | bitboards[W_KING], bitboards[B_PIECES] & ~moves); | |
return moves & ~attacks; | |
} | |
/** | |
Returns all possible escape moves for the black player. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::bEscapeMoves(UI64 bitboards[]) | |
{ | |
UI64 moves = kingMoves(bitboards[B_KING], bitboards[B_PIECES], bitboards); | |
UI64 attacks = pawnAttacks(bitboards[W_PAWN], WHITE); | |
attacks |= kingMoves(bitboards[W_KING], bitboards[W_PIECES], bitboards); | |
attacks |= knightEscapeMoves(bitboards[W_KNIGHT]); | |
attacks |= rookMoves(bitboards[W_ROOK], bitboards[EMPTYSQUARES] | bitboards[B_KING], bitboards[W_PIECES] & ~moves); | |
attacks |= bishopMoves(bitboards[W_BISHOP], bitboards[EMPTYSQUARES] | bitboards[B_KING], bitboards[W_PIECES] & ~moves); | |
attacks |= queenMoves(bitboards[W_QUEEN], bitboards[EMPTYSQUARES] | bitboards[B_KING], bitboards[W_PIECES] & ~moves); | |
return moves & ~attacks; | |
} | |
/** | |
Returns the moves for a pinned white piece. | |
@param piece The pinned piece. | |
@param moves The moves. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::wPinnedMoves(UI64 piece, UI64 moves, UI64 bitboards[]) | |
{ | |
return pinnedAttacks(piece, bitboards[W_KING], bitboards[B_ROOK], bitboards[B_BISHOP], bitboards[B_QUEEN], bitboards[EMPTYSQUARES]) & moves; | |
} | |
/** | |
Returns the moves for a pinned black piece. | |
@param piece The pinned piece. | |
@param moves The moves. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::bPinnedMoves(UI64 piece, UI64 moves, UI64 bitboards[]) | |
{ | |
return pinnedAttacks(piece, bitboards[B_KING], bitboards[W_ROOK], bitboards[W_BISHOP], bitboards[W_QUEEN], bitboards[EMPTYSQUARES]) & moves; | |
} | |
/** | |
Returns all the possible attacks against a pinned piece. | |
@param piece The pinned piece. | |
@param king The own king. | |
@param rooks The enemy rooks. | |
@param bishops The enemy bishops. | |
@param queen The enemy queen. | |
@param emptySquares The emptySquares squares. | |
@return The attacks. | |
*/ | |
UI64 Position::pinnedAttacks(UI64 piece, UI64 king, UI64 rooks, UI64 bishops, UI64 queen, UI64 emptySquares) | |
{ | |
UI64 attacks, current; | |
// Rook attacks. | |
while (rooks != 0) | |
{ | |
current = rooks & -rooks; | |
attacks |= pieceAttacks(current, rookNorth(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, rookSouth(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, rookWest(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, rookEast(current, emptySquares | piece), king); | |
rooks &= rooks - 1; | |
} | |
// Bishop attacks. | |
while (bishops != 0) | |
{ | |
current = bishops & -bishops; | |
attacks |= pieceAttacks(current, bishopNE(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, bishopNW(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, bishopSW(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, bishopSE(current, emptySquares | piece), king); | |
bishops &= bishops - 1; | |
} | |
// Queen attacks. | |
while (queen != 0) | |
{ | |
current = queen & -queen; | |
attacks |= pieceAttacks(current, rookNorth(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, rookSouth(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, rookWest(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, rookEast(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, bishopNE(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, bishopNW(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, bishopSW(current, emptySquares | piece), king); | |
attacks |= pieceAttacks(current, bishopSE(current, emptySquares | piece), king); | |
queen &= queen -1; | |
} | |
return attacks; | |
} | |
/** | |
Returns the attacks for the given piece. | |
@param pieces The current positions of the attacking pieces. | |
@param attacks The possible attacks. | |
@return The attacks. | |
*/ | |
UI64 Position::pieceAttacks(UI64 piece, UI64 attacks, UI64 king) | |
{ | |
return (attacks & king) != 0 ? piece | attacks : 0; | |
} | |
/** | |
Returns the moves for blocking check for the given white piece. | |
@param piece The piece. | |
@param moves The moves. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::wBlockCheck(UI64 piece, UI64 moves, UI64 bitboards[]) | |
{ | |
return blockAttacks(piece, bitboards[W_KING], bitboards[W_PIECES], bitboards[B_PAWN], bitboards[B_KNIGHT], bitboards[B_BISHOP], bitboards[B_ROOK], bitboards[B_QUEEN], bitboards[EMPTYSQUARES], WHITE) & moves; | |
} | |
/** | |
Returns the moves for blocking check for the given black piece. | |
@param piece The piece. | |
@param moves The moves. | |
@param bitboards The bitboards. | |
@return The moves. | |
*/ | |
UI64 Position::bBlockCheck(UI64 piece, UI64 moves, UI64 bitboards[]) | |
{ | |
return blockAttacks(piece, bitboards[B_KING], bitboards[B_PIECES], bitboards[W_PAWN], bitboards[W_KNIGHT], bitboards[W_BISHOP], bitboards[W_ROOK], bitboards[W_QUEEN], bitboards[EMPTYSQUARES], BLACK) & moves; | |
} | |
/** | |
Returns the moves for blicking attaccks for the given piece. | |
@param piece The piece. | |
@param king The own king. | |
@param own The own pieces. | |
@param pawns The enemy pawns. | |
@param knights The enemy knights. | |
@param bishops The enemy bishops. | |
@param rooks The enemy rooks. | |
@param queen The enemy queen. | |
@param emptySquares The emptySquares squares. | |
@param color The piece color (0 = White, 1 = Black). | |
@return The moves. | |
*/ | |
UI64 Position::blockAttacks(UI64 piece, UI64 king, UI64 own, UI64 pawns, UI64 knights, UI64 bishops, UI64 rooks, UI64 queen, UI64 emptySquares, int color) | |
{ | |
int attackerCount = 0; | |
UI64 attacks, current, result; | |
// Pawn attacks. | |
while (pawns != 0) | |
{ | |
current = pawns & -pawns; | |
result = pieceAttacks(current, pawnAttacks(current, color), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
pawns &= pawns - 1; | |
} | |
// Knight attacks. | |
while (knights != 0) | |
{ | |
current = knights & -knights; | |
result = pieceAttacks(current, knightMoves(current, own), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
knights &= knights - 1; | |
} | |
// Rook attacks. | |
while (rooks != 0) | |
{ | |
current = rooks & -rooks; | |
result = pieceAttacks(current, rookNorth(rooks, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, rookSouth(rooks, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, rookWest(rooks, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, rookEast(rooks, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
rooks &= rooks - 1; | |
} | |
// Bishop attacks. | |
while (bishops != 0) | |
{ | |
current = bishops & -bishops; | |
result = pieceAttacks(current, bishopNE(bishops, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, bishopNW(bishops, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, bishopSW(bishops, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, bishopSE(bishops, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
bishops &= bishops - 1; | |
} | |
// Queen attacks. | |
while (queen != 0) | |
{ | |
current = queen & -queen; | |
result = pieceAttacks(current, rookNorth(queen, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, rookSouth(queen, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, rookWest(queen, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, rookEast(queen, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, bishopNE(queen, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, bishopNW(queen, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, bishopSW(queen, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
result = pieceAttacks(current, bishopSE(queen, emptySquares), king); | |
if (result != 0) | |
attackerCount++; | |
attacks |= result; | |
queen &= queen -1; | |
} | |
return attackerCount == 1 ? attacks : 0; | |
} | |
/** | |
Returns whether the given white piece is pinned. | |
@param piece The piece. | |
@param bitboards The bitboards. | |
@return The result. | |
*/ | |
bool Position::wPiecePinned(UI64 piece, UI64 bitboards[]) | |
{ | |
UI64 attacks = rookMoves(bitboards[B_ROOK], bitboards[EMPTYSQUARES] | piece, bitboards[B_PIECES]); | |
attacks |= bishopMoves(bitboards[B_BISHOP], bitboards[EMPTYSQUARES] | piece, bitboards[B_PIECES]); | |
attacks |= queenMoves(bitboards[B_QUEEN], bitboards[EMPTYSQUARES] | piece, bitboards[B_PIECES]); | |
return (attacks & bitboards[W_KING]) != 0; | |
} | |
/** | |
Returns whether the given black piece is pinned. | |
@param piece The piece. | |
@param bitboards The bitboards. | |
@return The result. | |
*/ | |
bool Position::bPiecePinned(UI64 piece, UI64 bitboards[]) | |
{ | |
UI64 attacks = rookMoves(bitboards[W_ROOK], bitboards[EMPTYSQUARES] | piece, bitboards[W_PIECES]); | |
attacks |= bishopMoves(bitboards[W_BISHOP], bitboards[EMPTYSQUARES] | piece, bitboards[W_PIECES]); | |
attacks |= queenMoves(bitboards[W_QUEEN], bitboards[EMPTYSQUARES] | piece, bitboards[W_PIECES]); | |
return (attacks & bitboards[B_KING]) != 0; | |
} | |
/** | |
todo: docblock | |
*/ | |
UI64 Position::fillNorth(UI64 bitboard) | |
{ | |
return (bitboard << 8) | (bitboard << 16) | (bitboard << 32); | |
} | |
/** | |
todo: docblock | |
*/ | |
UI64 Position::fillSouth(UI64 bitboard) | |
{ | |
return (bitboard >> 8) | (bitboard >> 16) | (bitboard >> 32); | |
} | |
/** | |
Returns the number of items on the given bitboard. | |
@param bitboard The bitboard. | |
@return The count. | |
*/ | |
int Position::itemCount(UI64 bitboard) const | |
{ | |
int count = 0; | |
while (bitboard != 0) | |
{ | |
count++; | |
bitboard &= bitboard - 1; | |
} | |
return count; | |
} | |
/** | |
Returns the number of files with at least two pawns. | |
@param pawns The pawns. | |
@return The count. | |
*/ | |
int Position::doublePawnCount(UI64 pawns) const | |
{ | |
int count = 0; | |
if ((itemCount(pawns) & A_FILE) >= 2) | |
count++; | |
if ((itemCount(pawns) & B_FILE) >= 2) | |
count++; | |
if ((itemCount(pawns) & C_FILE) >= 2) | |
count++; | |
if ((itemCount(pawns) & D_FILE) >= 2) | |
count++; | |
if ((itemCount(pawns) & E_FILE) >= 2) | |
count++; | |
if ((itemCount(pawns) & F_FILE) >= 2) | |
count++; | |
if ((itemCount(pawns) & G_FILE) >= 2) | |
count++; | |
if ((itemCount(pawns) & H_FILE) >= 2) | |
count++; | |
return count; | |
} | |
/** | |
Adds moves for the given pieces. | |
@param pieces The pieces. | |
@param moves The moves. | |
@return void | |
*/ | |
void Position::addMoves(UI64 pieces, UI64 moves) | |
{ | |
while (moves != 0) | |
{ | |
std::vector<UI64> tmp; | |
tmp.insert(tmp.end(), pieces); | |
tmp.insert(tmp.end(), moves & -moves); | |
mMoves.insert(mMoves.end(), tmp); | |
moves &= moves - 1; | |
} | |
} | |
int Position::getTurn() const | |
{ | |
return mTurn; | |
} | |
void Position::setTurn(int turn) | |
{ | |
mTurn = turn; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
class Position | |
{ | |
public: | |
Position(void); | |
~Position(void); | |
void setup(void); | |
std::vector<std::vector<UI64>> genLegalMoves(UI64 bitboards[]); | |
bool whiteChecked(UI64 bitboards[]); | |
bool blackChecked(UI64 bitboards[]); | |
UI64 wAttacks(UI64 bitboards[]); | |
UI64 bAttacks(UI64 bitboards[]); | |
double evaluate(UI64 bitboards[]); | |
int getTurn() const; | |
void setTurn(int turn); | |
private: | |
int mTurn; | |
std::vector<Move> mLegalMoves; | |
std::vector<std::vector<UI64>> mMoves; | |
bool mWhiteCastleShortAllowed; | |
bool mWhiteCastleLongAllowed; | |
bool mBlackCastleShortAllowed; | |
bool mBlackCastleLongAllowed; | |
// Move generation | |
UI64 kingMoves(UI64 king, UI64 own, UI64 bitboards[]); | |
UI64 queenMoves(UI64 queen, UI64 empty, UI64 own); | |
UI64 queenEscapeMoves(UI64 queen, UI64 empty); | |
UI64 rookEast(UI64 rooks, UI64 empty); | |
UI64 rookWest(UI64 rooks, UI64 empty); | |
UI64 rookNorth(UI64 rooks, UI64 empty); | |
UI64 rookSouth(UI64 rooks, UI64 empty); | |
UI64 rookMoves(UI64 rooks, UI64 empty, UI64 own); | |
UI64 rookEscapeMoves(UI64 rooks, UI64 empty); | |
UI64 bishopNE(UI64 bishops, UI64 empty); | |
UI64 bishopNW(UI64 bishops, UI64 empty); | |
UI64 bishopSW(UI64 bishops, UI64 empty); | |
UI64 bishopSE(UI64 bishops, UI64 empty); | |
UI64 bishopMoves(UI64 bishops, UI64 empty, UI64 own); | |
UI64 bishopEscapeMoves(UI64 bishops, UI64 empty); | |
UI64 knightNNE(UI64 knights); | |
UI64 knightNEE(UI64 knights); | |
UI64 knightSEE(UI64 knights); | |
UI64 knightSSE(UI64 knights); | |
UI64 knightNNW(UI64 knights); | |
UI64 knightNWW(UI64 knights); | |
UI64 knightSWW(UI64 knights); | |
UI64 knightSSW(UI64 knights); | |
UI64 knightMoves(UI64 knights, UI64 own); | |
UI64 knightEscapeMoves(UI64 knights); | |
UI64 singlePushTargets(UI64 pawns, UI64 empty, int color); | |
UI64 doublePushTargets(UI64 pawns, UI64 empty, int color); | |
UI64 pawnAttacks(UI64 pawns, int color); | |
UI64 pawnMoves(UI64 pawns, UI64 empty, UI64 bitboards[], int color); | |
// AI | |
UI64 wMoves(UI64 bitboards[]); | |
UI64 bMoves(UI64 bitboards[]); | |
UI64 wEscapeMoves(UI64 bitboards[]); | |
UI64 bEscapeMoves(UI64 bitboards[]); | |
UI64 wPinnedMoves(UI64 piece, UI64 moves, UI64 bitboards[]); | |
UI64 bPinnedMoves(UI64 piece, UI64 moves, UI64 bitboards[]); | |
UI64 pinnedAttacks(UI64 piece, UI64 king, UI64 rooks, UI64 bishops, UI64 queen, UI64 empty); | |
UI64 pieceAttacks(UI64 pieces, UI64 attacks, UI64 king); | |
UI64 wBlockCheck(UI64 piece, UI64 moves, UI64 bitboards[]); | |
UI64 bBlockCheck(UI64 piece, UI64 moves, UI64 bitboards[]); | |
UI64 blockAttacks(UI64 piece, UI64 king, UI64 own, UI64 pawns, UI64 knights, UI64 bishops, UI64 rooks, UI64 queen, UI64 empty, int color); | |
bool wPiecePinned(UI64 piece, UI64 bitboards[]); | |
bool bPiecePinned(UI64 piece, UI64 bitboards[]); | |
// Utils | |
UI64 fillNorth(UI64 bitboard); | |
UI64 fillSouth(UI64 bitboard); | |
int itemCount(UI64 bitboard) const; | |
int doublePawnCount(UI64 pawns) const; | |
void addMoves(UI64 pieces, UI64 moves); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment