diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/board.cpp | 123 | ||||
| -rw-r--r-- | src/board.hpp | 8 |
2 files changed, 130 insertions, 1 deletions
diff --git a/src/board.cpp b/src/board.cpp index 5107a0f..f78d429 100644 --- a/src/board.cpp +++ b/src/board.cpp @@ -156,3 +156,126 @@ void PlayMove(Move move, Game *b) { } }; int PositionToIndex(Position i) { return i.rank * 8 + i.file; } + +UndoMove MakeMove(Move move, Game *g) { + UndoMove undo = {}; + + undo.from = move.From; + undo.to = move.To; + + undo.movedPiece = g->pieces[PositionToIndex(move.From)]; + undo.capturedPiece = g->pieces[PositionToIndex(move.To)]; + + undo.oldTurn = g->turn; + undo.oldCanEnpassant = g->canEnpassant; + undo.oldEnPassant = g->enPassant; + + undo.oldHalfMoveClock = g->halfMoveClock; + undo.oldMoveClock = g->MoveClock; + + undo.oldState = g->state; + undo.oldCaslte = g->castle; + + // play move + + Piece piece = g->pieces[PositionToIndex(move.From)]; + Piece piece2 = g->pieces[PositionToIndex(move.To)]; + + if (piece2.type != NONE) { + if (piece2.color == g->turn) { + assert(false && "capturing friendly piece error"); + } + } + piece.moved = true; + + // clock + g->MoveClock++; + if (piece.type == PAWN || piece2.type != NONE) { + g->halfMoveClock = 0; + } else { + g->halfMoveClock++; + } + + // Playing enpasstant + if (piece.type == PAWN && g->canEnpassant && move.To == g->enPassant) { + Position capturedPawn = move.To; + capturedPawn.rank += piece.color ? 1 : -1; + g->pieces[PositionToIndex(capturedPawn)] = {false, NONE, false}; + + undo.wasEnPassantCapture = true; + undo.enPassantCapturedSquare = capturedPawn; + undo.enPassantCapturedPiece = g->pieces[PositionToIndex(capturedPawn)]; + } + + g->canEnpassant = false; + + // Adding enpassant + if (piece.type == PAWN) { + Position to = move.To; + to.rank -= (piece.color ? -2 : 2); + if (to == move.From) { + g->canEnpassant = true; + Position target = move.From; + target.rank += piece.color ? -1 : 1; + g->enPassant = target; + }; + } + + // Promotions + if (piece.type == PAWN && move.To.rank == (piece.color ? 0 : 7)) { + // TODO parse the promote type from uci isntead of ignoreting it + piece.type = move.promotion == NONE ? QUEEN : move.promotion; + } + + // setting the moves + g->pieces[PositionToIndex(move.To)] = piece; + g->pieces[PositionToIndex(move.From)] = {false, NONE, false}; + + // post move change + + // changing who turn it is + g->turn = !g->turn; + + // 3 fold check + uint64_t key = GenerateZobristKey(g); + + undo.zobristKey = key; + + g->ThreeFoldMap[key]++; + + if (g->ThreeFoldMap[key] >= 3) { + g->state = DRAW; + } + + if (g->halfMoveClock >= 50) { + g->state = DRAW; + } + + return undo; +}; +void UnMake(UndoMove undo, Game *g) { + g->pieces[PositionToIndex(undo.from)] = undo.movedPiece; + + g->pieces[PositionToIndex(undo.to)] = undo.capturedPiece; + + if (undo.wasEnPassantCapture) { + g->pieces[PositionToIndex(undo.enPassantCapturedSquare)] = + undo.enPassantCapturedPiece; + } + + g->turn = undo.oldTurn; + + g->canEnpassant = undo.oldCanEnpassant; + g->enPassant = undo.oldEnPassant; + + g->halfMoveClock = undo.oldHalfMoveClock; + g->MoveClock = undo.oldMoveClock; + + g->state = undo.oldState; + + g->castle = undo.oldCaslte; + + if (--g->ThreeFoldMap[undo.zobristKey] <= 0) { + g->ThreeFoldMap.erase(undo.zobristKey); + } +}; diff --git a/src/board.hpp b/src/board.hpp index e9e3570..70c5502 100644 --- a/src/board.hpp +++ b/src/board.hpp @@ -64,13 +64,17 @@ struct UndoMove { Position from; Position to; + bool wasEnPassantCapture = false; + Position enPassantCapturedSquare; + Piece enPassantCapturedPiece; + bool oldTurn; bool oldCanEnpassant; Position oldEnPassant; std::string oldCaslte; int oldHalfMoveClock; int oldMoveClock; - std::unordered_map<uint64_t, int> OldThreeFoldMap; + uint64_t zobristKey; GameState oldState; }; void printBoard(Game *b); @@ -78,4 +82,6 @@ Piece createPiece(PieceType type, bool color, bool moved = false); void PlayMove(Move move, Game *b); int PositionToIndex(Position i); +UndoMove MakeMove(Move move, Game *g); +void UnMake(UndoMove undo, Game *g); #endif /* SRC_BOARD_H_ */ |
