21 #include "BoardState.h" 23 #include "SearchAlgorithm.h" 25 #include "StateStore.h" 32 whiteInCheck(false), whiteCheckStateCalculated(false),
33 blackInCheck(false), blackCheckStateCalculated(false),
34 whiteInMate(false), whiteMateStateCalculated(false),
35 blackInMate(false), blackMateStateCalculated(false),
36 cachedHash(0), hashCalculated(false),
37 cachedHash2(0), hash2Calculated(false)
41 black.queen = black.king;
45 BoardState::~BoardState()
58 black.enemyMove(m2, tmp);
67 white.enemyMove(m, tmp);
69 whiteCheckStateCalculated = whiteMateStateCalculated = blackCheckStateCalculated = blackMateStateCalculated =
false;
70 hashCalculated = hash2Calculated =
false;
78 Bitboard b = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
87 Bitboard b = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
95 bool BoardState::inCheck(Side side)
99 if (whiteCheckStateCalculated)
103 whiteCheckStateCalculated =
true;
105 whiteInCheck = underAttack(white.firstKing(), Black);
111 if (blackCheckStateCalculated)
115 Square sq = black.firstKing();
117 blackCheckStateCalculated =
true;
119 blackInCheck = underAttack(sq, White);
125 bool BoardState::inCheckmate(Side side)
128 if (side == White && whiteMateStateCalculated)
130 else if (side == Black && blackMateStateCalculated)
132 else if (side == White)
134 whiteMateStateCalculated =
true;
135 result = &whiteInMate;
139 blackMateStateCalculated =
true;
140 result = &blackInMate;
155 sq = nextPawn(side, &b))
157 for (
Square sq2 = b.getAndClearFirstSetBit();
159 sq2 = b.getAndClearFirstSetBit())
161 MoveList tmpList, tmpList2;
163 newState.
move(
Move(sq.col, sq.row, sq2.col, sq2.row), side, Queen );
164 if (!newState.inCheck(side))
168 for (sq = firstKnight(side, &b);
170 sq = nextKnight(side, &b))
172 for (
Square sq2 = b.getAndClearFirstSetBit();
174 sq2 = b.getAndClearFirstSetBit())
176 MoveList tmpList, tmpList2;
178 newState.
move(
Move(sq.col, sq.row, sq2.col, sq2.row), side, Queen );
179 if (!newState.inCheck(side))
183 for (sq = firstRook(side, &b);
185 sq = nextRook(side, &b))
187 for (
Square sq2 = b.getAndClearFirstSetBit();
189 sq2 = b.getAndClearFirstSetBit())
191 MoveList tmpList, tmpList2;
193 newState.
move(
Move(sq.col, sq.row, sq2.col, sq2.row), side, Queen );
194 if (!newState.inCheck(side))
198 for (sq = firstBishop(side, &b);
200 sq = nextBishop(side, &b))
202 for (
Square sq2 = b.getAndClearFirstSetBit();
204 sq2 = b.getAndClearFirstSetBit())
206 MoveList tmpList, tmpList2;
208 newState.
move(
Move(sq.col, sq.row, sq2.col, sq2.row), side, Queen );
209 if (!newState.inCheck(side))
213 for (sq = firstQueen(side, &b);
215 sq = nextQueen(side, &b))
217 for (
Square sq2 = b.getAndClearFirstSetBit();
219 sq2 = b.getAndClearFirstSetBit())
221 MoveList tmpList, tmpList2;
223 newState.
move(
Move(sq.col, sq.row, sq2.col, sq2.row), side, Queen );
224 if (!newState.inCheck(side))
228 sq = firstKing(side, &b);
229 for (
Square sq2 = b.getAndClearFirstSetBit();
231 sq2 = b.getAndClearFirstSetBit())
233 MoveList tmpList, tmpList2;
235 newState.
move(
Move(sq.col, sq.row, sq2.col, sq2.row), side, Queen );
236 if (!newState.inCheck(side))
243 bool BoardState::underAttack(
Square sq, Side side)
247 Bitboard b = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
253 Bitboard b = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
265 if (b && !sq.invalid())
267 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
270 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
271 Bitboard enPassant = black.enPassant;
273 *b = pawnMoves(allPieces, enemyPieces, enPassant,sq);
280 if (b && !sq.invalid())
282 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
285 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
288 Bitboard enPassant = white.enPassant;
290 *b = pawnMoves(allPieces, enemyPieces, enPassant, sq);
303 if (b && !sq.invalid())
305 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
308 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
309 Bitboard enPassant = black.enPassant;
311 *b = pawnMoves(allPieces, enemyPieces, enPassant,sq);
318 if (b && !sq.invalid())
320 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
323 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
326 Bitboard enPassant = white.enPassant;
328 *b = pawnMoves(allPieces, enemyPieces, enPassant, sq);
340 Square sq = white.firstRook();
341 if (b && !sq.invalid())
343 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
346 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
347 *b = rookMoves(allPieces, enemyPieces, sq);
353 Square sq = black.firstRook();
354 if (b && !sq.invalid())
356 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
359 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
362 *b = rookMoves(allPieces, enemyPieces, sq);
375 if (b && !sq.invalid())
377 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
380 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
381 *b = rookMoves(allPieces, enemyPieces, sq);
388 if (b && !sq.invalid())
390 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
393 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
396 *b = rookMoves(allPieces, enemyPieces, sq);
408 Square sq = white.firstKnight();
409 if (b && !sq.invalid())
411 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
414 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
415 *b = knightMoves(allPieces, enemyPieces, sq);
421 Square sq = black.firstKnight();
422 if (b && !sq.invalid())
424 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
427 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
430 *b = knightMoves(allPieces, enemyPieces, sq);
443 if (b && !sq.invalid())
445 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
448 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
449 *b = knightMoves(allPieces, enemyPieces, sq);
456 if (b && !sq.invalid())
458 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
461 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
464 *b = knightMoves(allPieces, enemyPieces, sq);
476 Square sq = white.firstBishop();
477 if (b && !sq.invalid())
479 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
482 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
483 *b = bishopMoves(allPieces, enemyPieces, sq);
489 Square sq = black.firstBishop();
490 if (b && !sq.invalid())
492 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
495 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
498 *b = bishopMoves(allPieces, enemyPieces, sq);
511 if (b && !sq.invalid())
513 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
516 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
517 *b = bishopMoves(allPieces, enemyPieces, sq);
524 if (b && !sq.invalid())
526 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
529 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
532 *b = bishopMoves(allPieces, enemyPieces, sq);
544 Square sq = white.firstQueen();
545 if (b && !sq.invalid())
547 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
550 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
551 *b = queenMoves(allPieces, enemyPieces, sq);
557 Square sq = black.firstQueen();
558 if (b && !sq.invalid())
560 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
563 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
566 *b = queenMoves(allPieces, enemyPieces, sq);
579 if (b && !sq.invalid())
581 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
584 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
585 *b = queenMoves(allPieces, enemyPieces, sq);
592 if (b && !sq.invalid())
594 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
597 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
600 *b = queenMoves(allPieces, enemyPieces, sq);
612 Square sq = white.firstKing();
613 if (b && !sq.invalid())
615 Bitboard allPieces = black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
618 allPieces = allPieces | white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
619 *b = kingMoves(allPieces, enemyPieces, sq, white.
rooksMoved[0], white.
rooksMoved[1], white.kingMoved);
625 Square sq = black.firstKing();
626 if (b && !sq.invalid())
628 Bitboard allPieces = white.
pawns|white.knights|white.rooks|white.bishops|white.queen|white.king;
631 allPieces = allPieces | black.
pawns|black.knights|black.rooks|black.bishops|black.queen|black.king;
634 *b = kingMoves(allPieces, enemyPieces, sq, black.
rooksMoved[0], black.
rooksMoved[1], black.kingMoved);
652 return white.heuristic() - black.heuristic();
654 return black.heuristic() - white.heuristic();
659 printf(
"+-+-+-+-+-+-+-+-+\n");
660 for (
int row = 7; row >= 0; row--)
663 for (
int col = 0; col < 8; col++)
669 if (b2 & black.
pawns)
671 else if (b2 & black.knights)
673 else if (b2 & black.rooks)
675 else if (b2 & black.bishops)
677 else if (b2 & black.queen)
679 else if (b2 & black.king)
681 else if (b & white.
pawns)
683 else if (b & white.knights)
685 else if (b & white.rooks)
687 else if (b & white.bishops)
689 else if (b & white.queen)
691 else if (b & white.king)
697 printf(
" %d\n+-+-+-+-+-+-+-+-+\n", row);
699 printf(
" A B C D E F G H\n");
702 extern StateStore stateStore;
706 return stateStore.lookup(
this, minPly, toPlay, h, ml);
711 stateStore.insert(
this, toPlay, h, ply, ml);
714 void BoardState::savePartial()
716 stateStore.insertPartial(
this);
719 void BoardState::uncache(Side toPlay)
721 stateStore.remove(
this, toPlay);
724 uint32_t BoardState::hash()
729 hashCalculated =
true;
735 sq = nextPawn(White))
737 accum ^= hashes[White][0][sq.col][sq.row];
739 for (sq = firstKnight(White);
741 sq = nextKnight(White))
743 accum ^= hashes[White][1][sq.col][sq.row];
745 for (sq = firstRook(White);
747 sq = nextRook(White))
749 accum ^= hashes[White][2][sq.col][sq.row];
751 for (sq = firstBishop(White);
753 sq = nextBishop(White))
755 accum ^= hashes[White][3][sq.col][sq.row];
757 for (sq = firstQueen(White);
759 sq = nextQueen(White))
761 accum ^= hashes[White][4][sq.col][sq.row];
763 sq = firstKing(White);
764 accum ^= hashes[White][5][sq.col][sq.row];
768 sq = nextPawn(Black))
770 accum ^= hashes[Black][0][sq.col][sq.row];
772 for (sq = firstKnight(Black);
774 sq = nextKnight(Black))
776 accum ^= hashes[Black][1][sq.col][sq.row];
778 for (sq = firstRook(Black);
780 sq = nextRook(Black))
782 accum ^= hashes[Black][2][sq.col][sq.row];
784 for (sq = firstBishop(Black);
786 sq = nextBishop(Black))
788 accum ^= hashes[Black][3][sq.col][sq.row];
790 for (sq = firstQueen(Black);
792 sq = nextQueen(Black))
794 accum ^= hashes[Black][4][sq.col][sq.row];
796 sq = firstKing(Black);
797 accum ^= hashes[Black][5][sq.col][sq.row];
800 accum ^= hashWhiteRookMovedL;
802 accum ^= hashWhiteRookMovedR;
804 accum ^= hashWhiteKingMoved;
806 accum ^= hashBlackRookMovedL;
808 accum ^= hashBlackRookMovedR;
810 accum ^= hashBlackKingMoved;
812 sq = white.enPassant.getAndClearFirstSetBit();
814 accum ^= hashes[White][6 ][sq.col][sq.row];
815 sq = black.enPassant.getAndClearFirstSetBit();
817 accum ^= hashes[Black][6 ][sq.col][sq.row];
823 uint32_t BoardState::hash2()
828 hash2Calculated =
true;
833 sq = nextPawn(White))
835 accum ^= hashes2[White][0][sq.col][sq.row];
837 for (sq = firstKnight(White);
839 sq = nextKnight(White))
841 accum ^= hashes2[White][1][sq.col][sq.row];
843 for (sq = firstRook(White);
845 sq = nextRook(White))
847 accum ^= hashes2[White][2][sq.col][sq.row];
849 for (sq = firstBishop(White);
851 sq = nextBishop(White))
853 accum ^= hashes2[White][3][sq.col][sq.row];
855 for (sq = firstQueen(White);
857 sq = nextQueen(White))
859 accum ^= hashes2[White][4][sq.col][sq.row];
861 sq = firstKing(White);
862 accum ^= hashes2[White][5][sq.col][sq.row];
866 sq = nextPawn(Black))
868 accum ^= hashes2[Black][0][sq.col][sq.row];
870 for (sq = firstKnight(Black);
872 sq = nextKnight(Black))
874 accum ^= hashes2[Black][1][sq.col][sq.row];
876 for (sq = firstRook(Black);
878 sq = nextRook(Black))
880 accum ^= hashes2[Black][2][sq.col][sq.row];
882 for (sq = firstBishop(Black);
884 sq = nextBishop(Black))
886 accum ^= hashes2[Black][3][sq.col][sq.row];
888 for (sq = firstQueen(Black);
890 sq = nextQueen(Black))
892 accum ^= hashes2[Black][4][sq.col][sq.row];
894 sq = firstKing(Black);
895 accum ^= hashes2[Black][5][sq.col][sq.row];
898 accum ^= hashWhiteRookMovedL2;
900 accum ^= hashWhiteRookMovedR2;
902 accum ^= hashWhiteKingMoved2;
904 accum ^= hashBlackRookMovedL2;
906 accum ^= hashBlackRookMovedR2;
908 accum ^= hashBlackKingMoved2;
910 sq = white.enPassant.getAndClearFirstSetBit();
912 accum ^= hashes2[White][6 ][sq.col][sq.row];
913 sq = black.enPassant.getAndClearFirstSetBit();
915 accum ^= hashes2[Black][6 ][sq.col][sq.row];
void move(Move m, Side s, Piece promotion=Pawn)
bool load(int minPly, Side toPlay, MoveList &ml, long &h)
void friendlyMove(Move m, Piece promotion=Pawn)
Square firstPawn(Side s, Bitboard *b=NULL)
long heuristic(Side side)
bool isAttacking(Square sq, Bitboard enemyPieces)
void save(int ply, Side toPlay, long h, MoveList &ml)
bool set(int rank, int file)
bool isLegal(Move m, Bitboard enemyPieces, Bitboard enemyPawnsEnPassant)
bool isLegal(Move m, Side s)