From c563e611c1b64e02b18bdd0d5b2cfaa98e8ab07f Mon Sep 17 00:00:00 2001 From: Tait Hoyem <44244401+TTWNO@users.noreply.github.com> Date: Sun, 28 Apr 2019 18:22:53 +0000 Subject: [PATCH] Add king_checked, fancify chess board. --- src/chess.cpp | 110 +++++++++++++++++++++++++++++++++++++++------- src/constants.h | 14 ++++++ src/functions.cpp | 6 +++ src/functions.h | 1 + tests/main.cpp | 5 ++- 5 files changed, 117 insertions(+), 19 deletions(-) diff --git a/src/chess.cpp b/src/chess.cpp index bec4398..3fe13d8 100644 --- a/src/chess.cpp +++ b/src/chess.cpp @@ -10,26 +10,50 @@ using namespace std; -void print_board(array const& board){ +void print_board(array *board, vector &highlighted_moves){ for (int i = 2; i < 10; ++i){ cout << 10-i << " |"; for (int j = 1; j < 9; ++j){ int ix = (i*10) + j; - int piece = board[ix]; + int piece = (*board)[ix]; string piece_string = FANCY_CHESS_CHARS[piece]; - string color = is_white(piece)?"White":"Black"; - cout << color::rize(piece_string, color, "Default"); - cout << " "; + string foreground_color = is_white(piece)?"White":"Black"; + string background_color = ""; + string modifier = ""; + + for (int move : highlighted_moves){ + if (get_to_sq(move) == ix){ + if (get_check_flag(move) == 1){ + background_color = "Light Red"; + } else if (get_captured_pc(move) != 0){ + background_color = "Green"; + // If a checkmate occors on this move + // Doesn't appear to work in practoce. + } else if (to_notation(move, board).find("#") != string::npos){ + background_color = "White"; + modifier = "Blink"; + } else { + background_color = "Yellow"; + } + } + } + + cout << color::rize(" ", foreground_color, background_color, modifier); + cout << color::rize(piece_string, foreground_color, background_color, modifier); + cout << color::rize(" ", foreground_color, background_color, modifier); } cout << endl; } - cout << "-------------------" << endl; - cout << " A B C D E F G H" << endl; + cout << "--------------------------" << endl; + cout << " A B C D E F G H" << endl; } // TODO: allow algebraic notation. int main(){ + + cout << "Hit h for help!" << endl; + Color whos_turn = Color::WHITE; array my_board; copy(DEFAULT_BOARD.begin(), DEFAULT_BOARD.end(), @@ -41,6 +65,9 @@ int main(){ int en_passant_square = 0; int castle_perms = 0xF; bool reset_en_passant = false; + + vector highlighted_moves = {}; + while (true){ all_moves = {}; @@ -49,8 +76,21 @@ int main(){ // Gets all moves for color who's turn it is. get_all_moves_for_pieces(my_pieces, &my_board, &all_moves, en_passant_square, castle_perms); - cout << "Castle perms: " << castle_perms << endl; - print_board(my_board); + print_board(&my_board, highlighted_moves); + + // If there are no moves. The game is over. + // If the king is ALSO in check, then the other team won! + if (all_moves.empty()){ + if (king_checked(&my_board, whos_turn)){ + string winning_team = rev_color(whos_turn)==Color::WHITE?"White":"Black"; + cout << "GG! " << winning_team << " won!" << endl; + break; + } else { + cout << "Stalemate, too bad!" << endl; + break; + } + } + // Gets a string from cin called input string input; getline(cin, input); @@ -71,22 +111,58 @@ int main(){ if (input == "q"){ break; } else if (input == "l"){ - cout << "Listing moves: \n"; for (string notation : all_moves_notation){ cout << notation << " "; } cout << endl; continue; + } else if (input == "c"){ + highlighted_moves = {}; + } else if (input == "h"){ + cout << "Commands:" < to list all moves for a specific position." << endl; + cout << " these will be highlighted on the board with various colors" << endl; + cout << " Red: Checking move"<< endl; + cout << " Blue: capturing move" << endl; + cout << " Yellow: all other moves" << endl; + cout << " c to clear the highlights" << endl; } // If the input did not match any legal move. if (!move_exec){ - cout << "Invalid move!" << std::endl; - cout << "These are the only valid moves: "; - for (string notation : all_moves_notation){ - cout << notation << " "; + int l_pos = input.find("l"); + // If input starts with "l". + // It cannot equal only l because that case is taken care of above. + // And it continues to the next loop. + if (l_pos == 0){ + string possible_position = input.substr(2, 2); + bool asking_for_specific_moves = false; + for (string pos : POSITION_STRING){ + if(pos == possible_position){ + asking_for_specific_moves = true; + } + } + // If input matches a position. + if (asking_for_specific_moves){ + highlighted_moves = {}; + for (int move : all_moves){ + if (POSITION_STRING[get_from_sq(move)] == possible_position){ + highlighted_moves.push_back(move); + cout << to_notation(move, &my_board) << " "; + } + } + cout << endl; + } else { + cout << "Invalid move!" << std::endl; + cout << "These are the only valid moves: "; + for (string notation : all_moves_notation){ + cout << notation << " "; + } + cout << endl; + continue; + } } - cout << endl; - continue; // If the input did match a legal move. } else { int moving_from_pos = get_from_sq(move_to_exec); @@ -130,13 +206,13 @@ int main(){ reset_en_passant = false; } if (en_passant_square != 0){ - cout << "En passant move at: " << POSITION_STRING[en_passant_square] << endl; reset_en_passant = true; } // This reverses the whos_turn variable. // and runs the move on the my_board variable. my_board = dumb_move(move_to_exec, my_board); whos_turn = rev_color(whos_turn); + highlighted_moves = {}; } } return 0; diff --git a/src/constants.h b/src/constants.h index bb1f8f8..4a4f37b 100644 --- a/src/constants.h +++ b/src/constants.h @@ -94,6 +94,20 @@ const std::array DEFAULT_BOARD = { INV,INV,INV,INV,INV,INV,INV,INV,INV,INV, INV,INV,INV,INV,INV,INV,INV,INV,INV,INV }; +const std::array BOARD_COLORS = { + NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR, + NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR, + NO_COLOR, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, NO_COLOR, + NO_COLOR, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, NO_COLOR, + NO_COLOR, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, NO_COLOR, + NO_COLOR, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, NO_COLOR, + NO_COLOR, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, NO_COLOR, + NO_COLOR, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, NO_COLOR, + NO_COLOR, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, NO_COLOR, + NO_COLOR, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, NO_COLOR, + NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR, + NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR +}; const std::array CHESS_CHARS = { ' ', diff --git a/src/functions.cpp b/src/functions.cpp index def07ac..fd438aa 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -114,6 +114,12 @@ bool is_attacked(int pos, std::array board){ return false; } +bool king_checked(std::array *board, Color color_of_king){ + PieceType king = color_of_king==WHITE?W_KING:B_KING; + int king_pos = get_pos_of(king, board); + return is_attacked(king_pos, *board); +} + void add_checked_flags(PieceType pt, std::array *board, std::vector *pns){ PieceType other_king = is_white(pt)?PieceType::B_KING:PieceType::W_KING; int other_king_pos = get_pos_of(other_king, board); diff --git a/src/functions.h b/src/functions.h index e0b385c..7803622 100644 --- a/src/functions.h +++ b/src/functions.h @@ -58,6 +58,7 @@ std::array dumb_move(int move, std::array board) // Decides if there this piece in position is in check bool is_attacked(int pos, std::array board); +bool king_checked(std::array *board, Color king_color); // Convert move (and board becuase notation needs more info than the move itself) // ...into algbraic notation. diff --git a/tests/main.cpp b/tests/main.cpp index e828eb2..9eaa7ce 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -291,8 +291,9 @@ TEST_CASE("Tests for check on square of queenside capture", "[get_all_moves]"){ CHECK(get_notations(cannot_queenside4, CASTLE_CHECK4_BOARD) == CASTLE_CHECK4_NOTATION); } -TEST_CASE("Test that king check detection is working correctly.", "[is_attacked]"){ - CHECK(is_attacked(ROOK_CHECK_KING_POS, ROOK_CHECK_MOVED_BOARD)); +TEST_CASE("Test that king check detection is working correctly.", "[king_checked]"){ + auto rook_check_moved_board = ROOK_CHECK_MOVED_BOARD; + CHECK(king_checked(&rook_check_moved_board, Color::WHITE)); } TEST_CASE("Test for add_checked_flags is working correctly.", "[get_all_moves][add_checked_flags]"){