diff options
| author | Loic Guegan <manzerbredes@mailbox.org> | 2022-02-19 18:23:06 +0100 |
|---|---|---|
| committer | Loic Guegan <manzerbredes@mailbox.org> | 2022-02-19 18:23:06 +0100 |
| commit | 5e78a4172da975ac227779456e670492217de206 (patch) | |
| tree | 8f71add7ce8323b83b2810e6484a89c462835a00 /src | |
| parent | f60b684790ae7a726763e4c6f9122371c71d17e9 (diff) | |
Now SAN moves can be parsed
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChessArbiter.cpp | 109 | ||||
| -rw-r--r-- | src/ChessArbiter.hpp | 1 |
2 files changed, 110 insertions, 0 deletions
diff --git a/src/ChessArbiter.cpp b/src/ChessArbiter.cpp index 18e1e1c..e747397 100644 --- a/src/ChessArbiter.cpp +++ b/src/ChessArbiter.cpp @@ -400,4 +400,113 @@ bool ChessArbiter::IsCheckMate() { std::string ChessArbiter::GetSAN() { return (SAN); } char ChessArbiter::GetCapture() { return (capture); } + +std::string ChessArbiter::ParseSAN(std::string SANMove) { + std::string src, dst; + char piece = ' '; + char hint = ' '; + bool isHintRank = false; + + // First castling + if (SANMove[0] == 'O' || SANMove[0] == '0') { + char c3 = (SANMove.size() >= 3) ? SANMove[3] : '?'; + // Long castle + if (c3 == '-') { + if (fen.player && IsCastlePossible(fen.player, true)) { + return ("e8c8"); + } else if (IsCastlePossible(fen.player, true)) { + return ("e1c1"); + } + } else { + if (fen.player && IsCastlePossible(fen.player, false)) { + return ("e8g8"); + } else if (IsCastlePossible(fen.player, false)) { + return ("e1g1"); + } + } + } + + // First deduce dst square in the move + if (SANMove.size() > 0) { + // Pawn moves + if (std::islower(SANMove[0])) { + if (fen.player) { + piece = 'p'; + } else { + piece = 'P'; + } + // Not a capture + if (SANMove[1] != 'x') { + dst = SANMove.substr(0, 2); + } else { + dst = SANMove.substr(2, 2); + } + } else { + piece = SANMove[0]; + char c1 = (SANMove.size() >= 2) ? SANMove[1] : '?'; + char c2 = (SANMove.size() >= 3) ? SANMove[2] : '?'; + char c3 = (SANMove.size() >= 4) ? SANMove[3] : '?'; + if (c1 == 'x') { + dst = SANMove.substr(2, 2); + } else if (c2 == 'x') { + hint = c1; + dst = SANMove.substr(3, 2); + } else if (IS_DIGIT(c2)) { + dst = SANMove.substr(1, 2); + } else { + hint = c1; + dst = SANMove.substr(2, 2); + } + } + } + isHintRank = IS_DIGIT(hint); + + // Now find src thanks to legal moves + std::vector<std::string> src_candidates; + for (std::string &move : ListLegalMoves(fen.player)) { + std::string current_src = move.substr(0, 2); + std::string current_dst = move.substr(2, 2); + if (current_dst == dst) { + src_candidates.push_back(current_src); + } + } + + // Now filter the legals move + if (src_candidates.size() > 0) { + if (src_candidates.size() > 1) { + std::vector<std::string> src_candidates_filtered; + // Filter according to pieces: + for (std::string &cand : src_candidates) { + Piece p = board.GetPieceAt(cand); // This call never fails + if (std::toupper(p.piece) == piece) { + src_candidates_filtered.push_back(cand); + } + } + src_candidates = src_candidates_filtered; + src_candidates_filtered.clear(); + // Last Filtering + if (src_candidates.size() > 1) { + for (std::string &cand : src_candidates) { + char cand_hint = cand[0]; + if (isHintRank) { + cand_hint = cand[1]; + } + if (hint == cand_hint) { + src_candidates_filtered.push_back(cand); + } + } + } + src_candidates = src_candidates_filtered; + } + src = src_candidates[0]; + } + + // Ensure that we return empty string if no matches + if(src.size()<=0){ + return(""); + } + // Else return "srcdst" string + return (src + dst); +} + } // namespace chessarbiter
\ No newline at end of file diff --git a/src/ChessArbiter.hpp b/src/ChessArbiter.hpp index 6d31073..e012b4a 100644 --- a/src/ChessArbiter.hpp +++ b/src/ChessArbiter.hpp @@ -65,5 +65,6 @@ public: bool IsDrawByNoMoves(); bool IsDrawByRepetitions(); bool IsDraw(); + std::string ParseSAN(std::string SANMove); }; } // namespace chessarbiter |
