From 601b4d1439507ddc404012fba8b488b07f794b9d Mon Sep 17 00:00:00 2001 From: Tait Hoyem <44244401+TTWNO@users.noreply.github.com> Date: Sat, 27 Apr 2019 04:24:10 +0000 Subject: [PATCH] Add pawn promotion notation --- src/constants.h | 6 ++++++ src/functions.cpp | 51 +++++++++++++++++++-------------------------- tests/main.cpp | 4 ++++ tests/valid_moves.h | 8 +++++++ 4 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/constants.h b/src/constants.h index 034d51d..cd52254 100644 --- a/src/constants.h +++ b/src/constants.h @@ -100,5 +100,11 @@ const std::array CHESS_CHARS = { 'P', 'N', 'B', 'R', 'Q', 'K', 'p', 'n', 'b', 'r', 'q', 'k' }; +// This returns the same letter weather the team is black or white +const std::array CHESS_CHARS_INSENSITIVE = { + " ", + "P", "N", "B", "R", "Q", "K", + "P", "N", "B", "R", "Q", "K" +}; #endif diff --git a/src/functions.cpp b/src/functions.cpp index afe745a..a3aee78 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -271,12 +271,17 @@ std::string to_notation(int move, std::array *board){ auto moved_board = dumb_move(move, *board); int from = get_from_sq(move); + PieceType piecetype = (*board)[from]; std::string from_string = POSITION_STRING[from]; int to = get_to_sq(move); int captured_piece = get_captured_pc(move); + int promoting_to = get_promoted_to_pc(move); + // Blank if not pawn + // file if pawn and capture move + std::string pawn_file = ""; // Blank if pawn // otherwise N/B/R/Q/K corresponding to each piece - // same black and white + // same for black and white std::string piece_character = ""; // Blank if not a capture // x if a capture move @@ -293,38 +298,22 @@ std::string to_notation(int move, std::array *board){ // 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]; + // Blank if not a pawn promotion move. + // Otherwise is equal to "=P/N/B/R/Q". + std::stringstream promotion; auto other_pieces = is_white(piecetype)?Pieces::BLACK:Pieces::WHITE; - switch(piecetype){ - case PieceType::W_KNIGHT: - case PieceType::B_KNIGHT: - piece_character = "N"; - break; - case PieceType::W_BISHOP: - case PieceType::B_BISHOP: - piece_character = "B"; - break; - case PieceType::W_ROOK: - case PieceType::B_ROOK: - piece_character = "R"; - break; - case PieceType::W_QUEEN: - case PieceType::B_QUEEN: - piece_character = "Q"; - break; - case PieceType::W_KING: - case PieceType::B_KING: - piece_character = "K"; - break; - } - if (captured_piece > 0){ + if (captured_piece != 0){ capture_character = "x"; - // If is a pawn - if (piece_character == ""){ - ss << from_string[0]; + if (piecetype == PieceType::W_PAWN || + piecetype == PieceType::B_PAWN){ + pawn_file = POSITION_STRING[from][0]; } } + if (piecetype != PieceType::W_PAWN && + piecetype != PieceType::B_PAWN){ + piece_character = CHESS_CHARS_INSENSITIVE[piecetype]; + } if (get_en_pass_flag(move) == 1){ en_passant = "e.p."; } @@ -374,11 +363,15 @@ std::string to_notation(int move, std::array *board){ disambig = POSITION_STRING[from]; } } + + if (promoting_to != PieceType::NONE){ + promotion << "=" << CHESS_CHARS_INSENSITIVE[promoting_to]; + } // 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 << disambig << capture_character << POSITION_STRING[to] << en_passant << check; + ss << pawn_file << piece_character << disambig << capture_character << POSITION_STRING[to] << en_passant << promotion.str() << check; } return ss.str(); } diff --git a/tests/main.cpp b/tests/main.cpp index 66c377a..9d76e6b 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -220,6 +220,8 @@ TEST_CASE("Test that algebraic notation conversion is working.", "[to_notation]" auto king_castle_moves = get_all_moves(CASTLING_POS, CASTLE_BOARD, true, 0, 0xF); auto king_bcastle_moves = get_all_moves(BCASTLING_POS, CASTLE_BOARD, true, 0, 0xF); auto en_passant_moves = get_all_moves(EN_PASSANT_TEST_POS, EN_PASSANT_TEST_BOARD, true, EN_PASSANT_SQUARE, 0); + auto pawn_prom_moves = get_all_moves(PROM_PAWN_POS, PROM_PAWN_BOARD); + auto bpawn_prom_moves = get_all_moves(PROM_BPAWN_POS, PROM_BPAWN_BOARD); CHECK(get_notations(knight_moves, KNIGHT_BLOCKED1_BOARD) == KNIGHT_BLOCKED1_NOTATION); CHECK(get_notations(bishop_moves, BISHOP_BLOCKED1_BOARD) == BISHOP_BLOCKED1_NOTATION); @@ -229,6 +231,8 @@ TEST_CASE("Test that algebraic notation conversion is working.", "[to_notation]" CHECK(get_notations(king_castle_moves, CASTLE_BOARD) == CASTLING_MOVES_NOTATION); CHECK(get_notations(king_bcastle_moves, CASTLE_BOARD) == BCASTLING_MOVES_NOTATION); CHECK(get_notations(en_passant_moves, EN_PASSANT_TEST_BOARD) == EN_PASSANT_TEST_NOTATION); + CHECK(get_notations(pawn_prom_moves, PROM_PAWN_BOARD) == PROM_PAWN_NOTATION); + CHECK(get_notations(bpawn_prom_moves, PROM_BPAWN_BOARD) == PROM_BPAWN_NOTATION); } TEST_CASE("Test for disambiguating moves in algebraic notation", "[to_notation]"){ diff --git a/tests/valid_moves.h b/tests/valid_moves.h index f1ad8c7..ff35dd6 100644 --- a/tests/valid_moves.h +++ b/tests/valid_moves.h @@ -234,6 +234,10 @@ const std::vector PROM_PAWN_PROMS = { W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN }; +const std::vector PROM_PAWN_NOTATION = { + "gxh8=N","gxh8=B","gxh8=R","gxh8=Q", + "gxf8=N","gxf8=B","gxf8=R","gxf8=Q" +}; // Black pawn promotion const int PROM_BPAWN_POS = B2; @@ -260,6 +264,10 @@ const std::vector PROM_BPAWN_PROMS = { B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN }; +const std::vector PROM_BPAWN_NOTATION = { + "bxc1=N","bxc1=B","bxc1=R","bxc1=Q", + "bxa1=N","bxa1=B","bxa1=R","bxa1=Q" +}; const int NO_EN_PASSANT_TEST_POS = D5; const std::array NO_EN_PASSANT_TEST_BOARD = {