aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/board.cpp123
-rw-r--r--src/board.hpp8
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_ */