summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2022-02-16 15:18:26 +0100
committerLoic Guegan <manzerbredes@mailbox.org>2022-02-16 15:18:26 +0100
commit0584edb107467a294f17a50d063e667f22f4a47b (patch)
tree67e95c79a1fc71562dcf9d65e9f614614154ed74
parent94c2565647d84f31d5ccac0d88717aef29d4a9a1 (diff)
Enable to retreive SAN move
-rw-r--r--src/Board.cpp14
-rw-r--r--src/Board.hpp2
-rw-r--r--src/ChessArbiter.cpp34
-rw-r--r--src/ChessArbiter.hpp4
-rw-r--r--tests/board.cpp12
5 files changed, 64 insertions, 2 deletions
diff --git a/src/Board.cpp b/src/Board.cpp
index 6546354..2c7c3f0 100644
--- a/src/Board.cpp
+++ b/src/Board.cpp
@@ -83,6 +83,20 @@ void Board::Move(std::string move) {
}
}
+bool Board::IsPieceMoveUnique(char piece, std::string move_dst) {
+ bool isBlack = std::islower(piece);
+ unsigned char count = 0;
+ for (std::string &move : ListPossibleMoves(isBlack)) {
+ std::string src = move.substr(0, 2);
+ std::string dst = move.substr(2, 2);
+ Piece p = GetPieceAt(src); // Never fails since it is legal
+ if (p.piece == piece && move_dst == dst) {
+ count++;
+ }
+ }
+ return (count <= 1);
+}
+
std::string Board::Serialize() {
std::string s;
for (short i = 0; i < 8; i++) {
diff --git a/src/Board.hpp b/src/Board.hpp
index aee2e10..a3981bc 100644
--- a/src/Board.hpp
+++ b/src/Board.hpp
@@ -22,6 +22,8 @@ public:
std::vector<Piece> GetPlayerPieces(bool);
/// @brief Count the number of a specific piece on the board
short CountPiece(char);
+ /// @brief Return true if at most 1 similar piece can go to move_dst
+ bool IsPieceMoveUnique(char piece, std::string move_dst);
/// @brief Get the location of the first king found on the board
std::string GetKingLocation(bool);
/// @brief Check if a move is technically possible (does not means it is
diff --git a/src/ChessArbiter.cpp b/src/ChessArbiter.cpp
index b2e73b6..6e66939 100644
--- a/src/ChessArbiter.cpp
+++ b/src/ChessArbiter.cpp
@@ -2,7 +2,8 @@
namespace chessarbiter {
ChessArbiter::ChessArbiter()
- : wPawn(1), wRook(5), wKnight(3), wBishop(3), wQueen(9), wKing(0) {}
+ : wPawn(1), wRook(5), wKnight(3), wBishop(3), wQueen(9), wKing(0), SAN("") {
+}
void ChessArbiter::Setup(std::string fen) {
positions.clear();
@@ -45,6 +46,8 @@ bool ChessArbiter::Play(std::string move) {
std::string dst = move.substr(2, 2);
bool IsCapture = !board.IsEmpty(dst);
FEN newFen = fen;
+ SAN_last = SAN;
+ SAN = "";
// Perform the move
if (move == "O-O" || move == "O-O-O") {
@@ -61,7 +64,31 @@ bool ChessArbiter::Play(std::string move) {
board.Move("e1c1");
board.Move("a1d1");
}
+ SAN = move;
} else {
+ // Update SAN move
+ if (moved.piece == 'p' || moved.piece == 'P') {
+ if (IsCapture) {
+ SAN = src[0];
+ SAN += "x" + dst;
+ } else {
+ SAN = dst;
+ }
+ } else {
+ SAN = std::toupper(moved.piece);
+ if (!board.IsPieceMoveUnique(moved.piece, dst)) {
+ if (src[0] == dst[0]) {
+ SAN += src[1];
+ } else {
+ SAN += src[0];
+ }
+ }
+ if (IsCapture) {
+ SAN += "x";
+ }
+ SAN += dst;
+ }
+ // Perform the move
board.Move(move);
}
@@ -113,6 +140,7 @@ bool ChessArbiter::Play(std::string move) {
// Check for illegal move
if (IsCheck(!fen.player)) {
SetFEN(fen_last);
+ SAN = SAN_last;
return (false);
}
@@ -309,6 +337,7 @@ bool ChessArbiter::IsDrawByNoMoves() {
if (Play(move)) {
positions[fen.board]--; // If move work, remove its position
SetFEN(fen_last);
+ SAN = SAN_last;
return (false);
}
}
@@ -338,6 +367,7 @@ bool ChessArbiter::IsCheckMate() {
if (Play(move)) {
positions[fen.board]--; // If move work, remove its position
SetFEN(fen_last);
+ SAN = SAN_last;
return (false);
}
}
@@ -346,4 +376,6 @@ bool ChessArbiter::IsCheckMate() {
return (false);
}
+std::string ChessArbiter::GetSAN() { return (SAN); }
+
} // namespace chessarbiter \ No newline at end of file
diff --git a/src/ChessArbiter.hpp b/src/ChessArbiter.hpp
index 09d8295..e5cec69 100644
--- a/src/ChessArbiter.hpp
+++ b/src/ChessArbiter.hpp
@@ -15,7 +15,7 @@ class ChessArbiter {
/// @brief FEN methods used internally
void SetFEN(std::string);
void SetFEN(FEN);
-
+ std::string SAN,SAN_last;
public:
ChessArbiter();
void Setup(std::string);
@@ -36,6 +36,8 @@ public:
bool IsPlayable();
/// @brief Get pieces captures by a player
std::string GetCaptures(bool);
+ /// @brief Get the english SAN format of the last move
+ std::string GetSAN();
/// @brief List all the legal moves of a player
std::vector<std::string> ListLegalMoves(bool);
/// @brief Check if a specific castle is possible by a player
diff --git a/tests/board.cpp b/tests/board.cpp
index eb777a3..c1f11c3 100644
--- a/tests/board.cpp
+++ b/tests/board.cpp
@@ -416,3 +416,15 @@ TEST_CASE("Serialize", "[board/Serialize]") {
"P ");
}
+TEST_CASE("IsPieceMoveUnique", "[board/IsPieceMoveUnique]") {
+ Board b;
+ b.AddPiece('N', "a1");
+ b.AddPiece('n', "c1");
+
+ CHECK(b.IsPieceMoveUnique('n', "b3"));
+ CHECK(b.IsPieceMoveUnique('N', "b3"));
+
+ b.AddPiece('N', "d2");
+ CHECK(b.IsPieceMoveUnique('n', "b3"));
+ CHECK_FALSE(b.IsPieceMoveUnique('N', "b3"));
+}