From d69c731bde5cf2c958c794f505684365072ab64a Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 28 Jul 2026 13:52:49 +0200 Subject: adding make move and unmake move --- src/board.cpp | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) (limited to 'src/board.cpp') 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); + } +}; -- cgit v1.2.3