|
@@ -42,7 +42,7 @@ void ChessGame::move(Move move)
|
|
|
if (turn == BLACK_SIDE) {
|
|
|
moveCount++;
|
|
|
}
|
|
|
- turn = turn == WHITE_SIDE ? BLACK_SIDE : WHITE_SIDE;
|
|
|
+ turn = otherSide(turn);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -73,25 +73,21 @@ void ChessGame::loadFromFen(const std::string& fenString)
|
|
|
else if (turn == "b"s) this->turn = BLACK_SIDE;
|
|
|
else throw runtime_error("invalid turn "s + turn);
|
|
|
|
|
|
- canCastleQueenSide[WHITE_SIDE] = false;
|
|
|
- canCastleKingSide[WHITE_SIDE] = false;
|
|
|
- canCastleQueenSide[BLACK_SIDE] = false;
|
|
|
- canCastleKingSide[BLACK_SIDE] = false;
|
|
|
-
|
|
|
+ castlingRights = 0;
|
|
|
if (castling != "-")
|
|
|
for (auto character : castling) {
|
|
|
switch (character) {
|
|
|
case 'k':
|
|
|
- canCastleKingSide[WHITE_SIDE] = true;
|
|
|
+ setCanCastleKingSide(WHITE_SIDE, true);
|
|
|
break;
|
|
|
case 'q':
|
|
|
- canCastleQueenSide[WHITE_SIDE] = true;
|
|
|
+ setCanCastleQueenSide(WHITE_SIDE, true);
|
|
|
break;
|
|
|
case 'K':
|
|
|
- canCastleKingSide[BLACK_SIDE] = true;
|
|
|
+ setCanCastleKingSide(BLACK_SIDE, true);
|
|
|
break;
|
|
|
case 'Q':
|
|
|
- canCastleQueenSide[BLACK_SIDE] = true;
|
|
|
+ setCanCastleQueenSide(BLACK_SIDE, true);
|
|
|
break;
|
|
|
default:
|
|
|
throw runtime_error("invalid castling right: "s + character);
|
|
@@ -132,10 +128,10 @@ std::string ChessGame::generateFen(void) const
|
|
|
string turn = this->turn == WHITE_SIDE ? "w"s : "b"s;
|
|
|
|
|
|
string castlingRights =
|
|
|
- (canCastleKingSide[BLACK_SIDE] ? "K"s : ""s) +
|
|
|
- (canCastleQueenSide[BLACK_SIDE] ? "Q"s : ""s) +
|
|
|
- (canCastleKingSide[WHITE_SIDE] ? "k"s : ""s) +
|
|
|
- (canCastleQueenSide[WHITE_SIDE] ? "q"s : ""s);
|
|
|
+ (getCanCastleKingSide(BLACK_SIDE) ? "K"s : ""s) +
|
|
|
+ (getCanCastleQueenSide(BLACK_SIDE)? "Q"s : ""s) +
|
|
|
+ (getCanCastleKingSide(WHITE_SIDE) ? "k"s : ""s) +
|
|
|
+ (getCanCastleQueenSide(WHITE_SIDE) ? "q"s : ""s);
|
|
|
if (castlingRights.empty())
|
|
|
castlingRights = "-"s;
|
|
|
|
|
@@ -158,20 +154,38 @@ std::string ChessGame::generateFen(void) const
|
|
|
UndoInfo ChessGame::doMove(const MoveInfo& mi)
|
|
|
{
|
|
|
UndoInfo ui;
|
|
|
- ui.before = board;
|
|
|
|
|
|
+ ui.castlingRights = castlingRights;
|
|
|
if (mi.movedPiece == KING) {
|
|
|
- canCastleKingSide[turn] = false;
|
|
|
- canCastleQueenSide[turn] = true;
|
|
|
+ setCanCastleKingSide(turn, false);
|
|
|
+ setCanCastleQueenSide(turn, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ ui.type = mi.movedPiece;
|
|
|
+ Bitboard& b = board.getBitboards(turn)[ui.type];
|
|
|
+ ui.before = b;
|
|
|
+
|
|
|
+ Bitboard target = Bitboard::fromIndex(mi.move.destination);
|
|
|
+ b &= ~Bitboard::fromIndex(mi.move.origin);
|
|
|
+ b |= target;
|
|
|
+
|
|
|
+ ui.captured = PieceType::EMPTY;
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
+ Bitboard& e = board.getBitboards(otherSide(turn))[i];
|
|
|
+ if (target & e) {
|
|
|
+ ui.captured = static_cast<PieceType>(i);
|
|
|
+ ui.beforeCaptured = e;
|
|
|
+ e ^= target;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- board.move(mi.move);
|
|
|
turn = otherSide(turn);
|
|
|
moveCount++;
|
|
|
+ ui.reversibleHalfMoves = reversibleHalfMoves;
|
|
|
if(mi.movedPiece != PAWN &&
|
|
|
board.getAtPosition(mi.move.destination) != EMPTY) {
|
|
|
reversibleHalfMoves++;
|
|
|
- ui.decrementReversibleHalfMoves = true;
|
|
|
}
|
|
|
return ui;
|
|
|
}
|
|
@@ -179,9 +193,13 @@ UndoInfo ChessGame::doMove(const MoveInfo& mi)
|
|
|
|
|
|
void ChessGame::undoMove(const UndoInfo& ui)
|
|
|
{
|
|
|
- board = ui.before;
|
|
|
turn = otherSide(turn);
|
|
|
+
|
|
|
+ Bitboard& b = board.getBitboards(turn)[ui.type];
|
|
|
+ b = ui.before;
|
|
|
+ if (ui.captured != PieceType::EMPTY)
|
|
|
+ board.getBitboards(otherSide(turn))[ui.captured] = ui.beforeCaptured;
|
|
|
moveCount--;
|
|
|
- if (ui.decrementReversibleHalfMoves)
|
|
|
- reversibleHalfMoves--;
|
|
|
+ reversibleHalfMoves = ui.reversibleHalfMoves;
|
|
|
+ castlingRights = ui.castlingRights;
|
|
|
}
|