aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/board.cpp127
-rw-r--r--src/board.hpp20
-rw-r--r--src/fen.cpp24
-rw-r--r--src/moves.cpp3
-rw-r--r--src/uci.cpp2
-rw-r--r--src/zobrist.cpp8
6 files changed, 125 insertions, 59 deletions
diff --git a/src/board.cpp b/src/board.cpp
index cbad8cb..ce116a1 100644
--- a/src/board.cpp
+++ b/src/board.cpp
@@ -1,13 +1,11 @@
#include "board.hpp"
#include "zobrist.hpp"
#include <cassert>
-#include <string>
-Piece createPiece(PieceType type, bool color, bool moved) {
+Piece createPiece(PieceType type, bool color) {
Piece piece;
piece.type = type;
piece.color = color;
- piece.moved = moved;
return piece;
}
@@ -30,7 +28,11 @@ UndoMove MakeMove(Move move, Game *g) {
undo.oldMoveClock = g->MoveClock;
undo.oldState = g->state;
- undo.oldCaslte = g->castle;
+
+ undo.OldwhiteCastleKing = g->whiteCastleKing;
+ undo.OldwhiteCastleQueen = g->whiteCastleQueen;
+ undo.OldblackCastleKing = g->blackCastleKing;
+ undo.OldblackCastleQueen = g->blackCastleQueen;
// play move
@@ -42,7 +44,6 @@ UndoMove MakeMove(Move move, Game *g) {
assert(false && "capturing friendly piece error");
}
}
- piece.moved = true;
// clock
g->MoveClock++;
@@ -56,7 +57,7 @@ UndoMove MakeMove(Move move, Game *g) {
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, NONEPIECE, false};
+ g->pieces[PositionToIndex(capturedPawn)] = {false, NONEPIECE};
undo.wasEnPassantCapture = true;
undo.enPassantCapturedSquare = capturedPawn;
@@ -82,42 +83,19 @@ UndoMove MakeMove(Move move, Game *g) {
// TODO parse the promote type from uci isntead of ignoreting it
piece.type = move.promotion == NONEPIECE ? QUEEN : move.promotion;
}
- assert(g->castle != "");
// caslte
if (piece.type == KING && move.From.rank == (piece.color ? 0 : 7) &&
- g->castle != "-" &&
(move.From.file + 2 == move.To.file ||
move.From.file - 2 == move.To.file)) {
- bool caslteSide =
- (move.From.file > move.To.file); // 0 queen side, 1 king side
- char castleCharacter =
- (caslteSide ? (piece.color ? 'K' : 'k') : (piece.color ? 'Q' : 'q'));
- std::string newCastleString = "";
- if (g->castle.contains('Q') && 'Q' != castleCharacter) {
- newCastleString += 'Q';
- };
- if (g->castle.contains('K') && 'K' != castleCharacter) {
- newCastleString += 'K';
- };
- if (g->castle.contains('q') && 'q' != castleCharacter) {
- newCastleString += 'q';
- };
- if (g->castle.contains('k') && 'k' != castleCharacter) {
- newCastleString += 'k';
- };
- if (newCastleString == "") {
- newCastleString = "-";
- };
- g->castle = newCastleString;
-
+ undo.wasCastle = true;
+ undo.CastledSide = (move.To.file > move.From.file);
if (move.From.file + 2 == move.To.file) {
Position rook_pos = move.To;
rook_pos.file += 1;
Piece rook = g->pieces[PositionToIndex(rook_pos)];
- g->pieces[PositionToIndex(rook_pos)] = {false, NONEPIECE, false};
- rook.moved = true;
+ g->pieces[PositionToIndex(rook_pos)] = {false, NONEPIECE};
rook_pos = move.From;
rook_pos.file -= 1;
g->pieces[PositionToIndex(rook_pos)] = rook;
@@ -126,17 +104,61 @@ UndoMove MakeMove(Move move, Game *g) {
Position rook_pos = move.To;
rook_pos.file -= 1;
Piece rook = g->pieces[PositionToIndex(rook_pos)];
- g->pieces[PositionToIndex(rook_pos)] = {false, NONEPIECE, false};
- rook.moved = true;
+ g->pieces[PositionToIndex(rook_pos)] = {false, NONEPIECE};
rook_pos = move.From;
rook_pos.file += 1;
g->pieces[PositionToIndex(rook_pos)] = rook;
}
};
- // setting the moves
+ // removing caslte rights
+ if (piece.type == KING) {
+ if (piece.color) {
+ g->whiteCastleKing = false;
+ g->whiteCastleQueen = false;
+ } else {
+ g->blackCastleKing = false;
+ g->blackCastleQueen = false;
+ }
+ }
+
+ // this part was written by ai
+ if (piece.type == ROOK) {
+ if (piece.color) { // White
+ if (move.From.rank == 7 && move.From.file == 0) // a1
+ g->whiteCastleQueen = false;
+
+ if (move.From.rank == 7 && move.From.file == 7) // h1
+ g->whiteCastleKing = false;
+ } else { // Black
+ if (move.From.rank == 0 && move.From.file == 0) // a8
+ g->blackCastleQueen = false;
+
+ if (move.From.rank == 0 && move.From.file == 7) // h8
+ g->blackCastleKing = false;
+ }
+ }
+
+ // this part is also written with ai
+ if (piece2.type == ROOK) {
+ if (piece2.color) { // White rook captured
+ if (move.To.rank == 7 && move.To.file == 0) // a1
+ g->whiteCastleQueen = false;
+
+ if (move.To.rank == 7 && move.To.file == 7) // h1
+ g->whiteCastleKing = false;
+ } else { // Black rook captured
+ if (move.To.rank == 0 && move.To.file == 0) // a8
+ g->blackCastleQueen = false;
+
+ if (move.To.rank == 0 && move.To.file == 7) // h8
+ g->blackCastleKing = false;
+ }
+ }
+
+ // playing the moves
g->pieces[PositionToIndex(move.To)] = piece;
- g->pieces[PositionToIndex(move.From)] = {false, NONEPIECE, false};
+ g->pieces[PositionToIndex(move.From)] = {false, NONEPIECE};
// changing who turn it is
g->turn = !g->turn;
@@ -178,9 +200,36 @@ void UnMakeMove(UndoMove undo, Game *g) {
g->state = undo.oldState;
- g->castle = undo.oldCaslte;
+ g->whiteCastleKing = undo.OldwhiteCastleKing;
+ g->whiteCastleQueen = undo.OldwhiteCastleQueen;
+ g->blackCastleKing = undo.OldblackCastleKing;
+ g->blackCastleQueen = undo.OldblackCastleQueen;
- if (--g->ThreeFoldMap[undo.zobristKey] <= 0) {
- g->ThreeFoldMap.erase(undo.zobristKey);
+ if (undo.wasCastle) {
+ if (undo.CastledSide) {
+ // rook f-file -> h-file
+ Position rookFrom = undo.to;
+ rookFrom.file -= 1; // f1/f8
+
+ Position rookTo = undo.to;
+ rookTo.file += 1; // h1/h8
+
+ g->pieces[PositionToIndex(rookTo)] = g->pieces[PositionToIndex(rookFrom)];
+ g->pieces[PositionToIndex(rookFrom)] = {false, NONEPIECE};
+ } else {
+ // rook d-file -> a-file
+ Position rookFrom = undo.to;
+ rookFrom.file += 1; // d1/d8
+
+ Position rookTo = undo.to;
+ rookTo.file -= 2; // a1/a8
+
+ g->pieces[PositionToIndex(rookTo)] = g->pieces[PositionToIndex(rookFrom)];
+ g->pieces[PositionToIndex(rookFrom)] = {false, NONEPIECE};
+ }
}
+ g->ThreeFoldMap[undo.zobristKey] -= 1;
+ if (g->ThreeFoldMap[undo.zobristKey] <= 0) {
+ g->ThreeFoldMap.erase(undo.zobristKey);
+ };
};
diff --git a/src/board.hpp b/src/board.hpp
index 4f04783..2e8cb82 100644
--- a/src/board.hpp
+++ b/src/board.hpp
@@ -2,7 +2,6 @@
#define SRC_BOARD_H_
#include <cstdint>
-#include <string>
#include <unordered_map>
enum PieceType {
@@ -26,7 +25,6 @@ enum GameState {
struct Piece {
bool color = 0;
PieceType type = NONEPIECE;
- bool moved = false;
};
struct Position {
@@ -42,7 +40,10 @@ struct TranspositionsEntry {
struct Game {
Piece pieces[64];
bool turn = 1; // 1 white; 0 black
- std::string castle = "";
+ bool whiteCastleKing = false;
+ bool whiteCastleQueen = false;
+ bool blackCastleKing = false;
+ bool blackCastleQueen = false;
uint8_t halfMoveClock = 0;
uint16_t MoveClock = 0;
Position enPassant;
@@ -75,13 +76,22 @@ struct UndoMove {
bool oldTurn;
bool oldCanEnpassant;
Position oldEnPassant;
- std::string oldCaslte;
+
+ bool OldwhiteCastleKing;
+ bool OldwhiteCastleQueen;
+ bool OldblackCastleKing;
+ bool OldblackCastleQueen;
+
int oldHalfMoveClock;
int oldMoveClock;
uint64_t zobristKey;
GameState oldState;
+
+ // castling
+ bool wasCastle = false;
+ bool CastledSide = false; // 0 for queen side, 1 for king side
};
-Piece createPiece(PieceType type, bool color, bool moved = false);
+Piece createPiece(PieceType type, bool color);
int PositionToIndex(Position i);
UndoMove MakeMove(Move move, Game *g);
diff --git a/src/fen.cpp b/src/fen.cpp
index 7597143..4b8686e 100644
--- a/src/fen.cpp
+++ b/src/fen.cpp
@@ -13,8 +13,6 @@ void setBoardFen(std::string fen, Game *b) {
int file = 0;
int rank = 0;
- std::string castle = "";
-
enum parserState {
POSITION,
TURN,
@@ -53,15 +51,26 @@ void setBoardFen(std::string fen, Game *b) {
}
if (state == CASTLE) {
if (fen[i] == '-') {
- castle = "-";
+ b->blackCastleKing = false;
+ b->blackCastleQueen = false;
+ b->whiteCastleKing = false;
+ b->whiteCastleQueen = false;
continue;
}
- if (toupper(fen[i]) == 'K') {
- castle += fen[i];
+ if (fen[i] == 'K') {
+ b->whiteCastleKing = true;
continue;
}
- if (toupper(fen[i]) == 'Q') {
- castle += fen[i];
+ if (fen[i] == 'Q') {
+ b->whiteCastleQueen = true;
+ continue;
+ }
+ if (fen[i] == 'k') {
+ b->blackCastleKing = true;
+ continue;
+ }
+ if (fen[i] == 'q') {
+ b->blackCastleQueen = true;
continue;
}
}
@@ -135,5 +144,4 @@ void setBoardFen(std::string fen, Game *b) {
}
break;
}
- b->castle = castle.empty() ? "-" : castle;
}
diff --git a/src/moves.cpp b/src/moves.cpp
index edf6c1e..008020d 100644
--- a/src/moves.cpp
+++ b/src/moves.cpp
@@ -1,13 +1,14 @@
#include <array>
#include <cassert>
#include <cstdint>
+#include <cstdlib>
#include <sys/types.h>
#include <vector>
#include "board.hpp"
#include "moves.hpp"
-void GenerateKnightMoves(Game *b, int from, std::vector<Move> &moves) {
+void GenerateKnightMoves(Game *b, int from, std::vector<Move> &moves) {
Piece knight = b->pieces[from];
if (knight.type != KNIGHT) {
assert(false && "Calling generate knight moves on non knight");
diff --git a/src/uci.cpp b/src/uci.cpp
index 310d31c..8a7ad9a 100644
--- a/src/uci.cpp
+++ b/src/uci.cpp
@@ -83,7 +83,6 @@ Game initBoard(
b.canEnpassant = false;
b.state = TURN;
b.turn = true;
- b.castle = "";
b.halfMoveClock = 0;
b.MoveClock = 0;
b.Transpositions = transPositions;
@@ -91,7 +90,6 @@ Game initBoard(
Piece EmptyPiece = {
false,
NONEPIECE,
- false,
};
for (int i = 0; i < 64; i++) {
b.pieces[i] = EmptyPiece;
diff --git a/src/zobrist.cpp b/src/zobrist.cpp
index 05d4cf2..cfc7769 100644
--- a/src/zobrist.cpp
+++ b/src/zobrist.cpp
@@ -49,16 +49,16 @@ uint64_t GenerateZobristKey(Game *b) {
// castling
int castle = 0;
- if (b->castle.find('K') != std::string::npos)
+ if (b->whiteCastleKing)
castle |= 1;
- if (b->castle.find('Q') != std::string::npos)
+ if (b->whiteCastleQueen)
castle |= 2;
- if (b->castle.find('k') != std::string::npos)
+ if (b->blackCastleKing)
castle |= 4;
- if (b->castle.find('q') != std::string::npos)
+ if (b->blackCastleQueen)
castle |= 8;
key ^= CastleKeys[castle];