diff --git a/src/functions.cpp b/src/functions.cpp index e22de7d..95cf9aa 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -290,6 +290,35 @@ std::array dumb_move(int move, std::array board) return new_board; } +void _filter_unneeded_squares(std::vector *moves, int piecetype, int origin){ + for (auto move_pn=moves->begin(); move_pn!=moves->end();){ + if (get_captured_pc(*move_pn) == piecetype && + get_to_sq(*move_pn) != origin){ + ++move_pn; + } else { + move_pn = moves->erase(move_pn); + } + } + +}; + +void _non_pawn_disambiguate(int from, int to, int piecetype, std::vector *moves, std::string *disambig){ + 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]; + } +} + std::string to_notation(int move, std::array *board){ std::stringstream ss; @@ -329,14 +358,31 @@ std::string to_notation(int move, std::array *board){ if (captured_piece != 0){ capture_character = "x"; + // Comment #6 + // if a pawn is capturing, have the disambiguation be the pawn's file + // stored in a seperate variable because pawn disabiguation by file happens at the start of a notation. For example: + // exf4 as opposed to Qh1xf4 if (piecetype == PieceType::W_PAWN || piecetype == PieceType::B_PAWN){ pawn_file = POSITION_STRING[from][0]; } } + // Pawns do not require this, as their file is ALWAYS enough to identify them, + // and the file is always speicified on a pawn capture. + // (See comment #6) if (piecetype != PieceType::W_PAWN && piecetype != PieceType::B_PAWN){ + // Simulated a piece of the same type, and opposite color moving from the to square + // to check if any other pieces can also move here. + // Basically it searches to see if there are duplicate pieces which can move to the same spot. + // and stores any duplicates in the other_moves variable. + PieceType opposite_piece = rev_color(piecetype); + std::vector other_moves = {}; + get_all_moves_as_if(to, opposite_piece, board, &other_moves, false); + // This takes out any mention of other squares involing blank pieces, or any peices that do not invole the current one. + _filter_unneeded_squares(&other_moves, piecetype, from); piece_character = CHESS_CHARS_INSENSITIVE[piecetype]; + _non_pawn_disambiguate(from, to, piecetype, &other_moves, &disambig); } if (get_en_pass_flag(move) == 1){ en_passant = "e.p."; @@ -346,48 +392,12 @@ std::string to_notation(int move, std::array *board){ // This checks if the other team has any valid moves. // If not, the check sign changes to a hashtag (#). std::vector other_moves = {}; - for (PieceType opt : other_pieces){ - for (int pos_of_opt : get_poss_of(opt, board)){ - get_all_moves(pos_of_opt, &moved_board, &other_moves); - } - } + get_all_moves_for_pieces(other_pieces, &moved_board, &other_moves); if (other_moves.empty()){ 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]; - } - } - + // If promoting, add an equals sign and the piece promoting to. if (promoting_to != PieceType::NONE){ promotion << "=" << CHESS_CHARS_INSENSITIVE[promoting_to]; } diff --git a/src/functions.h b/src/functions.h index c94dced..92e6836 100644 --- a/src/functions.h +++ b/src/functions.h @@ -64,5 +64,5 @@ bool is_checked(int pos, std::array board); std::string to_notation(int move, std::array *board); // These functions are just for printing (for now) so they are not included in the tests. -void get_all_moves_for_pieces(std::array pieces, std::array *board, std::vector *moves, int en_passant, int castle_perms); +void get_all_moves_for_pieces(std::array pieces, std::array *board, std::vector *moves, int en_passant=0, int castle_perms=0); void remove_chars_from_string(std::string &std, std::string to_remove);