aboutsummaryrefslogtreecommitdiff
path: root/src/board.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/board.cpp')
-rw-r--r--src/board.cpp123
1 files changed, 123 insertions, 0 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);
+ }
+};