From d69be941e43c0c71e7fb509326261d9ed9c27e43 Mon Sep 17 00:00:00 2001 From: Tait Hoyem <44244401+TTWNO@users.noreply.github.com> Date: Sat, 27 Apr 2019 03:02:26 +0000 Subject: [PATCH] to_notation working --- src/functions.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++--- tests/main.cpp | 2 +- tests/valid_moves.h | 20 ++++++++--------- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/functions.cpp b/src/functions.cpp index 225b578..afe745a 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -269,16 +269,33 @@ std::array dumb_move(int move, std::array board) std::string to_notation(int move, std::array *board){ std::stringstream ss; + auto moved_board = dumb_move(move, *board); int from = get_from_sq(move); std::string from_string = POSITION_STRING[from]; int to = get_to_sq(move); int captured_piece = get_captured_pc(move); + // Blank if pawn + // otherwise N/B/R/Q/K corresponding to each piece + // same black and white std::string piece_character = ""; + // Blank if not a capture + // x if a capture move std::string capture_character = ""; + // Blank if not en passant move + // otherwise e.p. std::string en_passant = ""; + // Black if no check, + // + if check + // # if checkmate std::string check = ""; - int piecetype = (*board)[from]; + // Blank if only this piece can move to the to square + // include file (a-h) if another piece can move to the to square + // includes rank (1-8) if pieces have same file + // includes both (f)(r) if 2+ identical piece can move to the to square + std::string disambig = ""; + PieceType piecetype = (*board)[from]; auto other_pieces = is_white(piecetype)?Pieces::BLACK:Pieces::WHITE; + switch(piecetype){ case PieceType::W_KNIGHT: case PieceType::B_KNIGHT: @@ -313,7 +330,6 @@ std::string to_notation(int move, std::array *board){ } if (get_check_flag(move) == 1){ check = "+"; - auto moved_board = dumb_move(move, *board); // This checks if the other team has any valid moves. // If not, the check sign changes to a hashtag (#). std::vector other_moves = {}; @@ -326,10 +342,43 @@ std::string to_notation(int move, std::array *board){ check = "#"; } } + // Simulated a piece of the same type, and opposite coor moving from the to square + // to check if any other pieces can also move here. + PieceType opposite_piece = rev_color(piecetype); + std::vector moves = {}; + get_all_moves_as_if(to, opposite_piece, board, &moves, false); + // Pawns do not require this, as their file is ALWAYS enough to identify them, + // and the file is always speicified on a pawn capture. + if (piecetype != PieceType::W_PAWN && + piecetype != PieceType::B_PAWN){ + for (auto move_pn=moves.begin(); move_pn!=moves.end();){ + if (get_captured_pc(*move_pn) == piecetype && + get_to_sq(*move_pn) != from){ + ++move_pn; + } else { + move_pn = moves.erase(move_pn); + } + } + if (moves.size() == 1){ + disambig = POSITION_STRING[from][0]; + int other_from = get_to_sq(moves.at(0)); + int min_from = other_fromfrom?other_from:from; + // If the remainder of the difference divided by 10 is 0 + // they are on the same file. + // Use rank to disambiguate + if ((max_from-min_from) % 10 == 0){ + disambig = POSITION_STRING[from][1]; + } + } else if (moves.size() > 1){ + disambig = POSITION_STRING[from]; + } + } + // end of checking for multiple pieces if (get_castle_flag(move) == 1){ return to-from<0 ? "O-O-O" : "O-O"; } else { - ss << piece_character << capture_character << POSITION_STRING[to] << en_passant << check; + ss << piece_character << disambig << capture_character << POSITION_STRING[to] << en_passant << check; } return ss.str(); } diff --git a/tests/main.cpp b/tests/main.cpp index 38ea7c3..66c377a 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -247,7 +247,7 @@ TEST_CASE("Test for disambiguating moves in algebraic notation", "[to_notation]" CHECK(get_notations(wrook1_moves, DISAMB_BOARD) == DISAMB_WROOK1_NOTATION); CHECK(get_notations(wrook2_moves, DISAMB_BOARD) == DISAMB_WROOK2_NOTATION); CHECK(get_notations(bishop1_moves, DISAMB_BOARD) == DISAMB_BISHOP1_NOTATION); - CHECK(get_notations(bishop2_moves, DISAMB_BOARD) == DISAMB_BISHOP1_NOTATION); + CHECK(get_notations(bishop2_moves, DISAMB_BOARD) == DISAMB_BISHOP2_NOTATION); CHECK(get_notations(queen1_moves, DISAMB_BOARD) == DISAMB_QUEEN1_NOTATION); CHECK(get_notations(queen2_moves, DISAMB_BOARD) == DISAMB_QUEEN2_NOTATION); CHECK(get_notations(queen3_moves, DISAMB_BOARD) == DISAMB_QUEEN3_NOTATION); diff --git a/tests/valid_moves.h b/tests/valid_moves.h index a3e725c..f1ad8c7 100644 --- a/tests/valid_moves.h +++ b/tests/valid_moves.h @@ -660,7 +660,7 @@ const int DISAMB_WROOK1_POS = A5; const int DISAMB_WROOK2_POS = A1; const int DISAMB_QUEEN1_POS = E4; const int DISAMB_QUEEN2_POS = H4; -const int DISAMB_QUEEN3_POS = H8; +const int DISAMB_QUEEN3_POS = H1; const std::array DISAMB_BOARD = { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, @@ -677,15 +677,15 @@ const std::array DISAMB_BOARD = { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }; -const std::vector DISAMB_BISHOP1_NOTATION = {}; -const std::vector DISAMB_BISHOP2_NOTATION = {}; -const std::vector DISAMB_BROOK1_NOTATION = {}; -const std::vector DISAMB_BROOK2_NOTATION = {}; -const std::vector DISAMB_WROOK1_NOTATION = {}; -const std::vector DISAMB_WROOK2_NOTATION = {}; -const std::vector DISAMB_QUEEN1_NOTATION = {}; -const std::vector DISAMB_QUEEN2_NOTATION = {}; -const std::vector DISAMB_QUEEN3_NOTATION = {}; +const std::vector DISAMB_BROOK1_NOTATION = {"Rc8", "Rb8", "Ra8", "Rde8", "Rdf8", "Rdg8", "Rd7"}; +const std::vector DISAMB_BROOK2_NOTATION = {"Rhg8", "Rhf8", "Rhe8", "Rh7", "Rh6", "Rh5", "Rxh4"}; +const std::vector DISAMB_WROOK1_NOTATION = {"Ra6", "Rxa7", "Rb5", "Rc5", "Rd5", "Re5", "Rf5", "Rg5", "Rh5", "R5a4", "R5a3", "R5a2"}; +const std::vector DISAMB_WROOK2_NOTATION = {"R1a2", "R1a3", "R1a4", "Rb1", "Rc1", "Rd1", "Re1", "Rf1", "Rg1"}; +const std::vector DISAMB_BISHOP1_NOTATION = {"Bc7", "Bdb8", "Be7", "Bf8", "Bdc5", "Bb4", "Ba3", "Be5", "Bf4", "Bg3", "Bh2"}; +const std::vector DISAMB_BISHOP2_NOTATION = {"Bab8", "Bb6", "Bac5", "Bd4", "Be3", "Bf2", "Bg1"}; +const std::vector DISAMB_QUEEN1_NOTATION = {"Qd4", "Qc4", "Qb4", "Qa4", "Qe5", "Qe6", "Qee7", "Qe8", "Qef4", "Qeg4", "Qe3", "Qe2", "Qe4e1", "Qd5", "Qc6", "Qb7", "Qa8", "Qf5", "Qg6", "Qeh7", "Qd3", "Qc2", "Qeb1", "Qef3", "Qeg2"}; +const std::vector DISAMB_QUEEN2_NOTATION = {"Qhg4", "Qhf4", "Qh5", "Qh6", "Qhh7", "Qxh8", "Q4h3", "Q4h2", "Qg5", "Qf6", "Qhe7", "Qxd8", "Qg3", "Qf2", "Qh4e1"}; +const std::vector DISAMB_QUEEN3_NOTATION = {"Qg1", "Qf1", "Qh1e1", "Qd1", "Qc1", "Qhb1", "Q1h2", "Q1h3", "Qhg2", "Qhf3"}; // CHeck that converting moves to algebraic notation have checkmate marks (#)