#include
<iostream>
#include
<iomanip>
#include
"defines.h"
#include
"protos.h"
#include
"extglobals.h"
#include
"board.h"
void Board::init()
{
viewRotated =
false;
for (int
i = 0; i < 64; i++) square[i] = EMPTY;
square[E1] = WHITE_KING;
square[D1] = WHITE_QUEEN;
square[A1] = WHITE_ROOK;
square[H1] = WHITE_ROOK;
square[B1] = WHITE_KNIGHT;
square[G1] = WHITE_KNIGHT;
square[C1] = WHITE_BISHOP;
square[F1] = WHITE_BISHOP;
square[A2] = WHITE_PAWN;
square[B2] = WHITE_PAWN;
square[C2] = WHITE_PAWN;
square[D2] = WHITE_PAWN;
square[E2] = WHITE_PAWN;
square[F2] = WHITE_PAWN;
square[G2] = WHITE_PAWN;
square[H2] = WHITE_PAWN;
square[E8] = BLACK_KING;
square[D8] = BLACK_QUEEN;
square[A8] = BLACK_ROOK;
square[H8] = BLACK_ROOK;
square[B8] = BLACK_KNIGHT;
square[G8] = BLACK_KNIGHT;
square[C8] = BLACK_BISHOP;
square[F8] = BLACK_BISHOP;
square[A7] = BLACK_PAWN;
square[B7] = BLACK_PAWN;
square[C7] = BLACK_PAWN;
square[D7] = BLACK_PAWN;
square[E7] = BLACK_PAWN;
square[F7] = BLACK_PAWN;
square[G7] = BLACK_PAWN;
square[H7] = BLACK_PAWN;
initFromSquares(square, WHITE_MOVE, 0,
CANCASTLEOO + CANCASTLEOOO, CANCASTLEOO + CANCASTLEOOO, 0);
return;
}
void Board::mirror()
{
// Mirrors the board position
(NOTE: move buffers are not effected!!!).
// The intended use is to test
symmetry of the evalaution function.
// Don't forget to mirror the
position back to the original position, after testing the
evaluation function.
int i,
mirroredBoard[64];
unsigned
char
nextMirror;
int
fiftyMMirror, castleWMirror, castleBMirror, epSqMirror;
int
kmoveBufLen, kendOfGame, kendOfSearch;
nextMirror = !nextMove;
fiftyMMirror = fiftyMove;
castleWMirror = castleBlack;
castleBMirror = castleWhite;
if (epSquare)
{
if (epSquare
< 24) epSqMirror = epSquare + 24;
else
epSqMirror = epSquare - 24;
}
for
(i = 0; i < 64; i++)
{
mirroredBoard[i] = square[MIRROR[i]];
// swap piece color (4th bit):
if (mirroredBoard[i]
!= EMPTY) mirroredBoard[i] ^= 8;
}
// keep the move buffer intact:
kmoveBufLen = moveBufLen[0];
kendOfGame = endOfGame;
kendOfSearch = endOfSearch;
initFromSquares(mirroredBoard, nextMirror,
fiftyMMirror, castleWMirror, castleBMirror, epSqMirror);
moveBufLen[0] = kmoveBufLen;
endOfGame = kendOfGame;
endOfSearch = kendOfSearch;
return;
}
void Board::initFromSquares(int
input[64], unsigned
char
next, int
fiftyM, int
castleW, int
castleB, int
epSq)
{
// sets up the board variables
according to the information found in
// the input[64] array
// All board & game initializations
are done through this function (including readfen and setup).
int i;
// bitboards
whiteKing = 0;
whiteQueens = 0;
whiteRooks = 0;
whiteBishops = 0;
whiteKnights = 0;
whitePawns = 0;
blackKing = 0;
blackQueens = 0;
blackRooks = 0;
blackBishops = 0;
blackKnights = 0;
blackPawns = 0;
whitePieces = 0;
blackPieces = 0;
occupiedSquares = 0;
hashkey = 0;
// populate the 12
bitboard:
for (i = 0; i
< 64; i++)
{
square[i] = input[i];
if (square[i]
== WHITE_KING)
{
whiteKing = whiteKing |
BITSET[i];
hashkey ^=
KEY.keys[i][WHITE_KING];
}
if (square[i]
== WHITE_QUEEN)
{
whiteQueens = whiteQueens |
BITSET[i];
hashkey ^=
KEY.keys[i][WHITE_QUEEN];
}
if (square[i]
== WHITE_ROOK)
{
whiteRooks = whiteRooks |
BITSET[i];
hashkey ^=
KEY.keys[i][WHITE_ROOK];
}
if (square[i]
== WHITE_BISHOP)
{
whiteBishops = whiteBishops |
BITSET[i];
hashkey ^=
KEY.keys[i][WHITE_BISHOP];
}
if (square[i]
== WHITE_KNIGHT)
{
whiteKnights = whiteKnights |
BITSET[i];
hashkey ^=
KEY.keys[i][WHITE_KNIGHT];
}
if (square[i]
== WHITE_PAWN)
{
whitePawns = whitePawns |
BITSET[i];
hashkey ^=
KEY.keys[i][WHITE_PAWN];
}
if (square[i]
== BLACK_KING)
{
blackKing = blackKing |
BITSET[i];
hashkey ^=
KEY.keys[i][BLACK_KING];
}
if (square[i]
== BLACK_QUEEN)
{
blackQueens = blackQueens |
BITSET[i];
hashkey ^=
KEY.keys[i][BLACK_QUEEN];
}
if (square[i]
== BLACK_ROOK)
{
blackRooks = blackRooks |
BITSET[i];
hashkey ^=
KEY.keys[i][BLACK_ROOK];
}
if (square[i]
== BLACK_BISHOP)
{
blackBishops = blackBishops |
BITSET[i];
hashkey ^=
KEY.keys[i][BLACK_BISHOP];
}
if (square[i]
== BLACK_KNIGHT)
{
blackKnights = blackKnights |
BITSET[i];
hashkey ^=
KEY.keys[i][BLACK_KNIGHT];
}
if (square[i]
== BLACK_PAWN)
{
blackPawns = blackPawns |
BITSET[i];
hashkey ^=
KEY.keys[i][BLACK_PAWN];
}
}
whitePieces = whiteKing | whiteQueens |
whiteRooks | whiteBishops | whiteKnights | whitePawns;
blackPieces = blackKing | blackQueens |
blackRooks | blackBishops | blackKnights | blackPawns;
occupiedSquares = whitePieces | blackPieces;
nextMove = next;
castleWhite = castleW;
castleBlack = castleB;
epSquare = epSq;
fiftyMove = fiftyM;
if (castleWhite
& CANCASTLEOO) hashkey ^= KEY.wk;
if (castleWhite
& CANCASTLEOOO) hashkey ^= KEY.wq;
if (castleBlack
& CANCASTLEOO) hashkey ^= KEY.bk;
if (castleBlack
& CANCASTLEOOO) hashkey ^= KEY.bq;
if (nextMove)
hashkey ^= KEY.side;
if (epSq)
hashkey ^= KEY.ep[epSq];
Material = bitCnt(whitePawns) * PAWN_VALUE +
bitCnt(whiteKnights) * KNIGHT_VALUE +
bitCnt(whiteBishops) * BISHOP_VALUE +
bitCnt(whiteRooks) * ROOK_VALUE +
bitCnt(whiteQueens) * QUEEN_VALUE;
Material -= (bitCnt(blackPawns) * PAWN_VALUE
+
bitCnt(blackKnights) * KNIGHT_VALUE +
bitCnt(blackBishops) * BISHOP_VALUE +
bitCnt(blackRooks) * ROOK_VALUE +
bitCnt(blackQueens) * QUEEN_VALUE);
endOfGame = 0;
endOfSearch = 0;
for (i
= 0; i < MAX_PLY; i++)
{
moveBufLen[i] = 0;
triangularLength[i] = 0;
}
inodes = 0;
return;
}
void Board::display()
{
int
rank, file;
std::cout << std::endl;
{
if (!viewRotated)
{
for
(rank = 8; rank >= 1; rank--)
{
std::cout
<< "
+---+---+---+---+---+---+---+---+"
<< std::endl;
std::cout << std::setw(3) << rank <<
" |";
for
(file = 1; file <= 8; file++)
{
std::cout <<
" " <<
PIECENAMES[square[BOARDINDEX[file][rank]]] <<
"|";
}
std::cout << std::endl;
}
std::cout
<< "
+---+---+---+---+---+---+---+---+"
<< std::endl;
std::cout
<< " a b c d
e f g h" << std::endl <<
std::endl;
}
else
{
std::cout
<< " h g f e
d c b a" << std::endl;
for
(rank = 1; rank <= 8; rank++)
{
std::cout << "
+---+---+---+---+---+---+---+---+"
<< std::endl;
std::cout << " |";
for
(file = 8; file >= 1; file--)
{
std::cout
<< " "
<< PIECENAMES[square[BOARDINDEX[file][rank]]] <<
"|";
}
std::cout << std::setw(3)
<< rank << std::endl;
}
std::cout
<< "
+---+---+---+---+---+---+---+---+"
<< std::endl << std::endl;
}
}
// std::cout << "next=" << (int)board.nextMove
<< std::endl;
// std::cout << "ep=" <<
board.epSquare << std::endl;
// std::cout << "fifty=" <<
board.fiftyMove << std::endl;
// std::cout << "white castle="
<< (int)board.castleWhite << std::endl;
// std::cout << "black castle="
<< (int)board.castleWhite << std::endl;
// std::cout << "key=" <<
board.hashkey << std::endl;
// std::cout << "endOfGame=" <<
board.endOfGame << std::endl;
// std::cout << "endOfSearch=" <<
board.endOfSearch << std::endl;
// std::cout << "repetitionCount="
<< repetitionCount() << std::endl;
// std::cout << "sign=..." << (board.hashkey
& 0x00000fff) << std::endl;
return;
}
#include
<iostream>
#include
"defines.h"
#include
"protos.h"
#include
"extglobals.h"
#include
"move.h"
#ifdef WINGLET_DEBUG_MOVES
void
debugMoves(char
*, Move &);
#endif
void makeMove(Move &move)
{
unsigned
int
from = move.getFrom();
unsigned
int
to = move.getTosq();
unsigned
int
piece = move.getPiec();
unsigned
int
captured = move.getCapt();
board.gameLine[board.endOfSearch].move.moveInt = move.moveInt;
board.gameLine[board.endOfSearch].castleWhite
= board.castleWhite;
board.gameLine[board.endOfSearch].castleBlack
= board.castleBlack;
board.gameLine[board.endOfSearch].fiftyMove
= board.fiftyMove;
board.gameLine[board.endOfSearch].epSquare
= board.epSquare;
board.gameLine[board.endOfSearch].key =
board.hashkey;
BitMap fromBitMap = BITSET[from];
BitMap fromToBitMap = fromBitMap | BITSET[to];
board.hashkey ^= (KEY.keys[from][piece] ^
KEY.keys[to][piece]);
if (board.epSquare)
board.hashkey ^= KEY.ep[board.epSquare];
switch
(piece)
{
case
1: // white pawn:
board.whitePawns ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
WHITE_PAWN;
board.epSquare = 0;
board.fiftyMove = 0;
if
((RANKS[from] == 2) && (RANKS[to] == 4))
{
board.epSquare = from +
8;
board.hashkey ^=
KEY.ep[from + 8];
}
if
(captured)
{
if
(move.isEnpassant())
{
board.blackPawns
^= BITSET[to-8];
board.blackPieces
^= BITSET[to-8];
board.occupiedSquares
^= fromToBitMap | BITSET[to-8];
board.square[to-8] = EMPTY;
board.Material
+= PAWN_VALUE;
board.hashkey
^= KEY.keys[to-8][BLACK_PAWN];
}
else
{
makeCapture(captured, to);
board.occupiedSquares ^= fromBitMap;
}
}
else
board.occupiedSquares ^= fromToBitMap;
if (move.isPromotion())
{
makeWhitePromotion(move.getProm(), to);
board.square[to]
= move.getProm();
}
break;
case
2: // white king:
board.whiteKing ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
WHITE_KING;
board.epSquare =
0;
board.fiftyMove++;
if
(board.castleWhite & CANCASTLEOO) board.hashkey ^= KEY.wk;
if
(board.castleWhite & CANCASTLEOOO) board.hashkey ^= KEY.wq;
board.castleWhite = 0;
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
if (move.isCastle())
{
if
(move.isCastleOO())
{
board.whiteRooks
^= BITSET[H1] | BITSET[F1];
board.whitePieces
^= BITSET[H1] | BITSET[F1];
board.occupiedSquares
^= BITSET[H1] | BITSET[F1];
board.square[H1] = EMPTY;
board.square[F1] = WHITE_ROOK;
board.hashkey ^=
(KEY.keys[H1][WHITE_ROOK] ^ KEY.keys[F1][WHITE_ROOK]);
}
else
{
board.whiteRooks
^= BITSET[A1] | BITSET[D1];
board.whitePieces
^= BITSET[A1] | BITSET[D1];
board.occupiedSquares ^= BITSET[A1] | BITSET[D1];
board.square[A1] = EMPTY;
board.square[D1] = WHITE_ROOK;
board.hashkey ^=
(KEY.keys[A1][WHITE_ROOK] ^ KEY.keys[D1][WHITE_ROOK]);
}
}
break;
case
3: // white knight:
board.whiteKnights ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
WHITE_KNIGHT;
board.epSquare =
0;
board.fiftyMove++;
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
5: // white bishop:
board.whiteBishops ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
WHITE_BISHOP;
board.epSquare = 0;
board.fiftyMove++;
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
6: // white rook:
board.whiteRooks ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
WHITE_ROOK;
board.epSquare =
0;
board.fiftyMove++;
if
(from == A1)
{
if
(board.castleWhite & CANCASTLEOOO) board.hashkey ^= KEY.wq;
board.castleWhite
&= ~CANCASTLEOOO;
}
if
(from == H1)
{
if (board.castleWhite & CANCASTLEOO) board.hashkey ^=
KEY.wk;
board.castleWhite &= ~CANCASTLEOO;
}
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
7: // white queen:
board.whiteQueens ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
WHITE_QUEEN;
board.epSquare =
0;
board.fiftyMove++;
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
9: // black pawn:
board.blackPawns ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
BLACK_PAWN;
board.epSquare = 0;
board.fiftyMove = 0;
if
((RANKS[from] == 7) && (RANKS[to] == 5))
{
board.epSquare = from -
8;
board.hashkey ^= KEY.ep[from - 8];
}
if
(captured)
{
if
(move.isEnpassant())
{
board.whitePawns
^= BITSET[to+8];
board.whitePieces
^= BITSET[to+8];
board.occupiedSquares ^= fromToBitMap | BITSET[to+8];
board.square[to+8] = EMPTY;
board.Material
-= PAWN_VALUE;
board.hashkey
^= KEY.keys[to+8][WHITE_PAWN];
}
else
{
makeCapture(captured, to);
board.occupiedSquares ^= fromBitMap;
}
}
else
board.occupiedSquares ^= fromToBitMap;
if (move.isPromotion())
{
makeBlackPromotion(move.getProm(), to);
board.square[to]
= move.getProm();
}
break;
case
10: // black king:
board.blackKing ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
BLACK_KING;
board.epSquare =
0;
board.fiftyMove++;
if
(board.castleBlack & CANCASTLEOO) board.hashkey ^= KEY.bk;
if
(board.castleBlack & CANCASTLEOOO) board.hashkey ^= KEY.bq;
board.castleBlack = 0;
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
if
(move.isCastle())
{
if
(move.isCastleOO())
{
board.blackRooks
^= BITSET[H8] | BITSET[F8];
board.blackPieces
^= BITSET[H8] | BITSET[F8];
board.occupiedSquares ^= BITSET[H8] | BITSET[F8];
board.square[H8] = EMPTY;
board.square[F8] = BLACK_ROOK;
board.hashkey ^=
(KEY.keys[H8][BLACK_ROOK] ^ KEY.keys[F8][BLACK_ROOK]);
}
else
{
board.blackRooks
^= BITSET[A8] | BITSET[D8];
board.blackPieces
^= BITSET[A8] | BITSET[D8];
board.occupiedSquares ^= BITSET[A8] | BITSET[D8];
board.square[A8] = EMPTY;
board.square[D8] = BLACK_ROOK;
board.hashkey ^=
(KEY.keys[A8][BLACK_ROOK] ^ KEY.keys[D8][BLACK_ROOK]);
}
}
break;
case
11: // black knight:
board.blackKnights ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
BLACK_KNIGHT;
board.epSquare =
0;
board.fiftyMove++;
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
13: // black bishop:
board.blackBishops ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
BLACK_BISHOP;
board.epSquare = 0;
board.fiftyMove++;
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
14: // black rook:
board.blackRooks ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
BLACK_ROOK;
board.epSquare =
0;
board.fiftyMove++;
if
(from == A8)
{
if
(board.castleBlack & CANCASTLEOOO) board.hashkey ^= KEY.bq;
board.castleBlack
&= ~CANCASTLEOOO;
}
if
(from == H8)
{
if
(board.castleBlack & CANCASTLEOO) board.hashkey ^= KEY.bk;
board.castleBlack
&= ~CANCASTLEOO;
}
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
15: // black queen:
board.blackQueens ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
EMPTY;
board.square[to] =
BLACK_QUEEN;
board.epSquare =
0;
board.fiftyMove++;
if
(captured)
{
makeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
}
board.nextMove = !board.nextMove;
board.hashkey ^= KEY.side;
board.endOfSearch++;
#ifdef WINGLET_DEBUG_MOVES
debugMoves("makemove",
move);
#endif
}
void unmakeMove(Move &move)
{
unsigned
int
piece = move.getPiec();
unsigned
int
captured = move.getCapt();
unsigned
int
from = move.getFrom();
unsigned
int
to = move.getTosq();
BitMap fromBitMap = BITSET[from];
BitMap fromToBitMap = fromBitMap | BITSET[to];
switch
(piece)
{
case
1: // white pawn:
board.whitePawns ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
WHITE_PAWN;
board.square[to] =
EMPTY;
if
(captured)
{
if
(move.isEnpassant())
{
board.blackPawns
^= BITSET[to-8];
board.blackPieces
^= BITSET[to-8];
board.occupiedSquares ^= fromToBitMap | BITSET[to-8];
board.square[to-8] = BLACK_PAWN;
board.Material
-= PAWN_VALUE;
}
else
{
unmakeCapture(captured, to);
board.occupiedSquares ^= fromBitMap;
}
}
else
board.occupiedSquares ^= fromToBitMap;
if
(move.isPromotion())
{
unmakeWhitePromotion(move.getProm(), to);
}
break;
case
2: // white king:
board.whiteKing ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
WHITE_KING;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
if
(move.isCastle())
{
if
(move.isCastleOO())
{
board.whiteRooks ^= BITSET[H1] | BITSET[F1];
board.whitePieces
^= BITSET[H1] | BITSET[F1];
board.occupiedSquares ^= BITSET[H1] | BITSET[F1];
board.square[H1] = WHITE_ROOK;
board.square[F1] = EMPTY;
}
else
{
board.whiteRooks
^= BITSET[A1] | BITSET[D1];
board.whitePieces
^= BITSET[A1] | BITSET[D1];
board.occupiedSquares ^= BITSET[A1] | BITSET[D1];
board.square[A1] = WHITE_ROOK;
board.square[D1] = EMPTY;
}
}
break;
case
3: // white knight:
board.whiteKnights ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
WHITE_KNIGHT;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
5: // white bishop:
board.whiteBishops ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
WHITE_BISHOP;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
6: // white rook:
board.whiteRooks ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
WHITE_ROOK;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
7: // white queen:
board.whiteQueens ^=
fromToBitMap;
board.whitePieces ^=
fromToBitMap;
board.square[from] =
WHITE_QUEEN;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
9: // black pawn:
board.blackPawns ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
BLACK_PAWN;
board.square[to] =
EMPTY;
if
(captured)
{
if
(move.isEnpassant())
{
board.whitePawns
^= BITSET[to+8];
board.whitePieces
^= BITSET[to+8];
board.occupiedSquares ^= fromToBitMap | BITSET[to+8];
board.square[to+8] = WHITE_PAWN;
board.Material
+= PAWN_VALUE;
}
else
{
unmakeCapture(captured, to);
board.occupiedSquares ^= fromBitMap;
}
}
else
board.occupiedSquares ^= fromToBitMap;
if (move.isPromotion())
{
unmakeBlackPromotion(move.getProm(), to);
}
break;
case
10: // black king:
board.blackKing ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
BLACK_KING;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
if (move.isCastle())
{
if
(move.isCastleOO())
{
board.blackRooks
^= BITSET[H8] | BITSET[F8];
board.blackPieces
^= BITSET[H8] | BITSET[F8];
board.occupiedSquares ^= BITSET[H8] | BITSET[F8];
board.square[H8] = BLACK_ROOK;
board.square[F8] = EMPTY;
}
else
{
board.blackRooks ^= BITSET[A8] | BITSET[D8];
board.blackPieces ^= BITSET[A8] | BITSET[D8];
board.occupiedSquares ^= BITSET[A8] | BITSET[D8];
board.square[A8] = BLACK_ROOK;
board.square[D8] = EMPTY;
}
}
break;
case
11: // black knight:
board.blackKnights ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
BLACK_KNIGHT;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
13: // black bishop:
board.blackBishops ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
BLACK_BISHOP;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
14: // black rook:
board.blackRooks ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
BLACK_ROOK;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
case
15: // black queen:
board.blackQueens ^=
fromToBitMap;
board.blackPieces ^=
fromToBitMap;
board.square[from] =
BLACK_QUEEN;
board.square[to] =
EMPTY;
if
(captured)
{
unmakeCapture(captured,
to);
board.occupiedSquares ^=
fromBitMap;
}
else
board.occupiedSquares ^= fromToBitMap;
break;
}
board.nextMove = !board.nextMove;
board.endOfSearch--;
board.castleWhite =
board.gameLine[board.endOfSearch].castleWhite;
board.castleBlack =
board.gameLine[board.endOfSearch].castleBlack;
board.epSquare =
board.gameLine[board.endOfSearch].epSquare;
board.fiftyMove =
board.gameLine[board.endOfSearch].fiftyMove;
board.hashkey =
board.gameLine[board.endOfSearch].key;
#ifdef WINGLET_DEBUG_MOVES
debugMoves("unmakemove",
move);
#endif
return;
}
void makeCapture(unsigned
int &captured,
unsigned
int &to)
{
// deals with all
captures, except en-passant
BitMap toBitMap;
toBitMap = BITSET[to];
board.hashkey ^= KEY.keys[to][captured];
switch
(captured)
{
case
1: // white pawn:
board.whitePawns ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.Material -=
PAWN_VALUE;
break;
case
2: // white king:
board.whiteKing ^=
toBitMap;
board.whitePieces ^=
toBitMap;
break;
case
3: // white knight:
board.whiteKnights ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.Material -=
KNIGHT_VALUE;
break;
case
5: // white bishop:
board.whiteBishops ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.Material -=
BISHOP_VALUE;
break;
case
6: // white rook:
board.whiteRooks ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.Material -=
ROOK_VALUE;
if (to
== A1)
{
if (board.castleWhite
& CANCASTLEOOO) board.hashkey ^= KEY.wq;
board.castleWhite
&= ~CANCASTLEOOO;
}
if (to
== H1)
{
if (board.castleWhite
& CANCASTLEOO) board.hashkey ^= KEY.wk;
board.castleWhite
&= ~CANCASTLEOO;
}
break;
case
7: // white queen:
board.whiteQueens ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.Material -=
QUEEN_VALUE;
break;
case
9: // black pawn:
board.blackPawns ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.Material +=
PAWN_VALUE;
break;
case
10: // black king:
board.blackKing ^=
toBitMap;
board.blackPieces ^=
toBitMap;
break;
case
11: // black knight:
board.blackKnights ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.Material +=
KNIGHT_VALUE;
break;
case
13: // black bishop:
board.blackBishops ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.Material +=
BISHOP_VALUE;
break;
case
14: // black rook:
board.blackRooks ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.Material +=
ROOK_VALUE;
if (to
== A8)
{
if (board.castleBlack
& CANCASTLEOOO) board.hashkey ^= KEY.bq;
board.castleBlack &= ~CANCASTLEOOO;
}
if (to
== H8)
{
if (board.castleBlack
& CANCASTLEOO) board.hashkey ^= KEY.bk;
board.castleBlack
&= ~CANCASTLEOO;
}
break;
case
15: // black queen:
board.blackQueens ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.Material +=
QUEEN_VALUE;
break;
}
board.fiftyMove = 0;
}
void unmakeCapture(unsigned
int
&captured, unsigned
int
&to)
{
// deals with all captures, except
en-passant
BitMap toBitMap;
toBitMap = BITSET[to];
switch
(captured)
{
case
1: // white pawn:
board.whitePawns ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.square[to] =
WHITE_PAWN;
board.Material +=
PAWN_VALUE;
break;
case
2: // white king:
board.whiteKing ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.square[to] =
WHITE_KING;
break;
case
3: // white knight:
board.whiteKnights ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.square[to] =
WHITE_KNIGHT;
board.Material +=
KNIGHT_VALUE;
break;
case
5: // white bishop:
board.whiteBishops ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.square[to] =
WHITE_BISHOP;
board.Material +=
BISHOP_VALUE;
break;
case
6: // white rook:
board.whiteRooks ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.square[to] =
WHITE_ROOK;
board.Material +=
ROOK_VALUE;
break;
case
7: // white queen:
board.whiteQueens ^=
toBitMap;
board.whitePieces ^=
toBitMap;
board.square[to] =
WHITE_QUEEN;
board.Material +=
QUEEN_VALUE;
break;
case
9: // black pawn:
board.blackPawns ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.square[to] =
BLACK_PAWN;
board.Material -=
PAWN_VALUE;
break;
case
10: // black king:
board.blackKing ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.square[to] =
BLACK_KING;
break;
case
11: // black knight:
board.blackKnights ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.square[to] =
BLACK_KNIGHT;
board.Material -=
KNIGHT_VALUE;
break;
case
13: // black bishop:
board.blackBishops ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.square[to] =
BLACK_BISHOP;
board.Material -=
BISHOP_VALUE;
break;
case
14: // black rook:
board.blackRooks ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.square[to] =
BLACK_ROOK;
board.Material -=
ROOK_VALUE;
break;
case
15: // black queen:
board.blackQueens ^=
toBitMap;
board.blackPieces ^=
toBitMap;
board.square[to] =
BLACK_QUEEN;
board.Material -=
QUEEN_VALUE;
break;
}
}
void makeWhitePromotion(unsigned
int
prom, unsigned
int
&to)
{
BitMap toBitMap;
toBitMap = BITSET[to];
board.whitePawns ^= toBitMap;
board.Material -= PAWN_VALUE;
board.hashkey ^= (KEY.keys[to][WHITE_PAWN] ^
KEY.keys[to][prom]);
if
(prom == 7)
{
board.whiteQueens ^= toBitMap;
board.Material +=
QUEEN_VALUE;
}
else
if
(prom == 6)
{
board.whiteRooks ^= toBitMap;
board.Material += ROOK_VALUE;
}
else
if
(prom == 5)
{
board.whiteBishops ^= toBitMap;
board.Material +=
BISHOP_VALUE;
}
else
if
(prom == 3)
{
board.whiteKnights ^= toBitMap;
board.Material +=
KNIGHT_VALUE;
}
}
void unmakeWhitePromotion(unsigned
int
prom, unsigned
int
&to)
{
BitMap toBitMap;
toBitMap = BITSET[to];
board.whitePawns ^= toBitMap;
board.Material += PAWN_VALUE;
if
(prom == 7)
{
board.whiteQueens ^= toBitMap;
board.Material -=
QUEEN_VALUE;
}
else
if
(prom == 6)
{
board.whiteRooks ^= toBitMap;
board.Material -= ROOK_VALUE;
}
else
if
(prom == 5)
{
board.whiteBishops ^= toBitMap;
board.Material -=
BISHOP_VALUE;
}
else
if
(prom == 3)
{
board.whiteKnights ^= toBitMap;
board.Material -=
KNIGHT_VALUE;
}
}
void makeBlackPromotion(unsigned
int
prom, unsigned
int
&to)
{
BitMap toBitMap;
toBitMap = BITSET[to];
board.blackPawns ^= toBitMap;
board.Material += PAWN_VALUE;
board.hashkey ^= (KEY.keys[to][BLACK_PAWN] ^
KEY.keys[to][prom]);
if
(prom == 15)
{
board.blackQueens ^= toBitMap;
board.Material -=
QUEEN_VALUE;
}
else
if
(prom == 14)
{
board.blackRooks ^= toBitMap;
board.Material -= ROOK_VALUE;
}
else
if
(prom == 13)
{
board.blackBishops ^= toBitMap;
board.Material -=
BISHOP_VALUE;
}
else
if
(prom == 11)
{
board.blackKnights ^= toBitMap;
board.Material -=
KNIGHT_VALUE;
}
}
void unmakeBlackPromotion(unsigned
int
prom, unsigned
int
&to)
{
BitMap toBitMap;
toBitMap = BITSET[to];
board.blackPawns ^= toBitMap;
board.Material -= PAWN_VALUE;
if
(prom == 15)
{
board.blackQueens ^= toBitMap;
board.Material +=
QUEEN_VALUE;
}
else
if
(prom == 14)
{
board.blackRooks ^= toBitMap;
board.Material += ROOK_VALUE;
}
else
if
(prom == 13)
{
board.blackBishops ^= toBitMap;
board.Material +=
BISHOP_VALUE;
}
else
if
(prom == 11)
{
board.blackKnights ^= toBitMap;
board.Material +=
KNIGHT_VALUE;
}
}
BOOLTYPE isOwnKingAttacked()
{
// check to see if we are leaving
our king in check
if
(board.nextMove)
{
return
isAttacked(board.blackKing, !board.nextMove);
}
else
{
return
isAttacked(board.whiteKing, !board.nextMove);
}
}
BOOLTYPE isOtherKingAttacked()
{
// check to see if we are leaving
our king in check
if (board.nextMove)
{
return
isAttacked(board.whiteKing, board.nextMove);
}
else
{
return
isAttacked(board.blackKing, board.nextMove);
}
}
BOOLTYPE isValidTextMove(char
*userMove, Move &move)
{
// Checks if userMove is valid by
comparing it with moves from the move generator
// If found valid, the move is
returned
unsigned
char
userFrom, userTo, userPromote;
BOOLTYPE moveFound;
int i;
if (strlen(userMove)
> 3)
{
userFrom = userMove[0] - 97;
userFrom += 8 * (userMove[1] - 49);
userTo = userMove[2] - 97;
userTo += 8 * (userMove[3] - 49);
}
userPromote = 0;
if (strlen(userMove)
> 4)
{
if (board.nextMove
== WHITE_MOVE)
{
switch
(userMove[4])
{
case
'q':
userPromote = WHITE_QUEEN;
break;
case
'r':
userPromote = WHITE_ROOK;
break;
case
'b':
userPromote = WHITE_BISHOP;
break;
case
'n':
userPromote = WHITE_KNIGHT;
break;
}
}
else
switch
(userMove[4])
{
case
'q':
userPromote = BLACK_QUEEN;
break;
case
'r':
userPromote = BLACK_ROOK;
break;
case
'b':
userPromote = BLACK_BISHOP;
break;
case
'n':
userPromote = BLACK_KNIGHT;
break;
}
}
moveFound =
false;
for (i
= board.moveBufLen[0]; i < board.moveBufLen[1]; i++)
{
if ((board.moveBuffer[i].getFrom()
== userFrom) && (board.moveBuffer[i].getTosq() == userTo))
{
if (((board.square[userFrom]
== WHITE_PAWN) && (RANKS[userFrom] == 7)) ||
((board.square[userFrom] ==
BLACK_PAWN) && (RANKS[userFrom] == 2)))
{
if
(board.moveBuffer[i].getProm() == userPromote)
{
move.moveInt =
board.moveBuffer[i].moveInt;
return
true;
}
}
else
{
move.moveInt =
board.moveBuffer[i].moveInt;
return
true;
}
}
}
move.moveInt = 0;
return
false;
}
#ifdef WINGLET_DEBUG_MOVES
void debugMoves(char
*caller, Move &move)
{
// check if board.square, piece
bitmaps and whitepieces and blackpiese and occupied square are
all consistent after (un)makmove
char
input[80];
int
mat, i, j;
U64 key;
// check if both kings are present
if ((bitCnt(board.whiteKing)
!= 1) || (bitCnt(board.blackKing) != 1))
{
std::cout <<
"king captured after "
<< caller << std::endl;
displayMove(move); std::cout <<
std::endl;
for
(j = 0 ; j < board.endOfSearch ; j++)
{
std::cout
<< j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
// check if board.square and piece
bitmaps and whitepieces and blackpiese and occupied square are
all telling the same
for (i
= 0 ; i < 64 ; i++)
{
if ((board.blackQueens
& BITSET[i]) && (board.square[i] != BLACK_QUEEN))
{
std::cout
<< "inconsistency in black
queens after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
if ((board.blackRooks
& BITSET[i]) && (board.square[i] != BLACK_ROOK))
{
std::cout
<< "inconsistency in black
rooks after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
displayBitmap(board.blackRooks);
std::cin >> input;
}
if
((board.blackBishops & BITSET[i]) && (board.square[i] !=
BLACK_BISHOP))
{
std::cout
<< "inconsistency in black
bishops after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
if ((board.blackKnights
& BITSET[i]) && (board.square[i] != BLACK_KNIGHT))
{
std::cout
<< "inconsistency in black
knights after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
displayMove(move);
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout
<< j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
if ((board.blackKing
& BITSET[i]) && (board.square[i] != BLACK_KING))
{
std::cout
<< "inconsistency in black
king after " << caller << std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
if
((board.blackPawns & BITSET[i]) && (board.square[i] !=
BLACK_PAWN))
{
std::cout
<< "inconsistency in black
pawns after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
displayBitmap(board.blackPawns);
std::cout.flush();
std::cin >> input;
}
if ((board.whiteQueens
& BITSET[i]) && (board.square[i] != WHITE_QUEEN))
{
std::cout
<< "inconsistency in white
queens after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
if ((board.whiteRooks
& BITSET[i]) && (board.square[i] != WHITE_ROOK))
{
std::cout
<< "inconsistency in white
rooks after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for
(j = 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
displayBitmap(board.whiteRooks);
std::cin >> input;
}
if ((board.whiteBishops
& BITSET[i]) && (board.square[i] != WHITE_BISHOP))
{
std::cout
<< "inconsistency in white
bishops after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
if ((board.whiteKnights
& BITSET[i]) && (board.square[i] != WHITE_KNIGHT))
{
std::cout
<< "inconsistency in white
knights after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
if ((board.whiteKing
& BITSET[i]) && (board.square[i] != WHITE_KING))
{
std::cout
<< "inconsistency in white
king after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
if ((board.whitePawns
& BITSET[i]) && (board.square[i] != WHITE_PAWN))
{
std::cout
<< "inconsistency in white
pawns after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout << j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
std::cin >> input;
}
}
if
(board.whitePieces != (board.whiteKing | board.whiteQueens |
board.whiteRooks | board.whiteBishops | board.whiteKnights |
board.whitePawns ))
{
std::cout <<
"inconsistency in
whitePieces after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout
<< j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
displayBitmap(board.whitePieces);
std::cin >> input;
}
if (board.blackPieces
!= (board.blackKing | board.blackQueens | board.blackRooks |
board.blackBishops | board.blackKnights | board.blackPawns ))
{
std::cout <<
"inconsistency in
blackPieces after " << caller <<
std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout
<< j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
displayBitmap(board.blackPieces);
std::cin >> input;
}
if (board.occupiedSquares
!= (board.whitePieces | board.blackPieces))
{
std::cout <<
"inconsistency in
occupiedSquares after " << caller
<< std::endl;
displayMove(move); std::cout <<
std::endl;
for (j
= 0 ; j < board.endOfSearch ; j++)
{
std::cout
<< j+1 << ". ";
displayMove(board.gameLine[j].move);
std::cout <<std::endl;
}
board.display();
displayBitmap(board.occupiedSquares);
std::cin >> input;
}
mat = bitCnt(board.whitePawns) * PAWN_VALUE +
bitCnt(board.whiteKnights) * KNIGHT_VALUE +
bitCnt(board.whiteBishops) * BISHOP_VALUE +
bitCnt(board.whiteRooks)
* ROOK_VALUE +
bitCnt(board.whiteQueens) * QUEEN_VALUE;
mat -= (bitCnt(board.blackPawns) * PAWN_VALUE
+
bitCnt(board.blackKnights) * KNIGHT_VALUE +
bitCnt(board.blackBishops) * BISHOP_VALUE +
bitCnt(board.blackRooks) * ROOK_VALUE +
bitCnt(board.blackQueens) * QUEEN_VALUE);
if (board.Material
!= mat)
{
std::cout <<
"inconsistency in material
after " << caller << std::endl;
displayMove(move);
board.display();
std::cin >> input;
}
key = 0;
for (i = 0; i
< 64; i++)
{
if (board.square[i]
!= EMPTY) key ^= KEY.keys[i][board.square[i]];
}
if (board.castleWhite
& CANCASTLEOO) key ^= KEY.wk;
if (board.castleWhite
& CANCASTLEOOO) key ^= KEY.wq;
if (board.castleBlack
& CANCASTLEOO) key ^= KEY.bk;
if (board.castleBlack
& CANCASTLEOOO) key ^= KEY.bq;
if (board.nextMove)
key ^= KEY.side;
if (board.epSquare)
key ^= KEY.ep[board.epSquare];
if
(board.hashkey != key)
{
std::cout <<
"inconsistency in hashkey after "
<< caller << std::endl;
displayMove(move);
board.display();
std::cin
>> input;
}
return;
}
#endif
|