From 6269bc0311c9ffaa2cd2bc36ef941c42c1d1d81c Mon Sep 17 00:00:00 2001 From: Tait Hoyem <44244401+TTWNO@users.noreply.github.com> Date: Mon, 29 Apr 2019 17:20:08 +0000 Subject: [PATCH] * -> & (use references instead of pointers) --- src/all_moves_functions.cpp | 70 +++++++++--------- src/functions.cpp | 140 ++++++++++++++++++------------------ src/functions.h | 35 +++++---- tests/main.cpp | 15 ++-- tests/test_functions.cpp | 20 +++--- tests/test_functions.h | 18 ++--- 6 files changed, 153 insertions(+), 145 deletions(-) diff --git a/src/all_moves_functions.cpp b/src/all_moves_functions.cpp index 200e8ff..bec21a7 100644 --- a/src/all_moves_functions.cpp +++ b/src/all_moves_functions.cpp @@ -14,8 +14,8 @@ inline Position _pair_to_pos_unsafe(int x, int y){ } // This function returns true if the color of the piece on tile (x,y) is the Color c -bool _xy_is_color(int pos, std::array* board, Color c){ - return c==Color::WHITE ? is_white((*board)[pos]) : is_black((*board)[pos]); +bool _xy_is_color(int pos, const std::array& board, Color c){ + return c==Color::WHITE ? is_white(board[pos]) : is_black(board[pos]); } Color _rev_color(Color c){ @@ -23,7 +23,7 @@ Color _rev_color(Color c){ } // This function will set the boolean guarding it to false if it is blocked, thus stopping it from running. -void _add_if_not_blocked(int pos, int from, std::vector *pns, std::array *board, Color color_of_piece, Color color_of_opposite, bool *is_not_blocked){ +void _add_if_not_blocked(int pos, int from, std::vector& pns, const std::array& board, Color color_of_piece, Color color_of_opposite, bool *is_not_blocked){ if (*is_not_blocked){ if (!is_valid_position(pos)){ *is_not_blocked = false; @@ -31,17 +31,17 @@ void _add_if_not_blocked(int pos, int from, std::vector *pns, std::arraypush_back(make_move(from, pos, (*board)[pos])); + pns.push_back(make_move(from, pos, board[pos])); *is_not_blocked = false; } else { - pns->push_back(make_move(from, pos, (*board)[pos])); + pns.push_back(make_move(from, pos, board[pos])); } } } } // Only for the king, using rays for left and right, and adding the castle flag if needed. -void _king_add_if_not_blocked(int pos, int from, std::vector *pns, std::array *board, Color color_of_piece, Color color_of_opposite, bool *is_not_blocked, int castle_flag){ +void _king_add_if_not_blocked(int pos, int from, std::vector& pns, const std::array& board, Color color_of_piece, Color color_of_opposite, bool *is_not_blocked, int castle_flag){ if (*is_not_blocked){ if (!is_valid_position(pos)){ *is_not_blocked = false; @@ -49,10 +49,10 @@ void _king_add_if_not_blocked(int pos, int from, std::vector *pns, std::arr if (_xy_is_color(pos, board, color_of_piece)){ *is_not_blocked = false; } else if (_xy_is_color(pos, board, color_of_opposite)){ - pns->push_back(make_move(from, pos, (*board)[pos], PieceType::NONE)); + pns.push_back(make_move(from, pos, board[pos], PieceType::NONE)); *is_not_blocked = false; } else { - pns->push_back(make_move(from, pos, (*board)[pos], PieceType::NONE, 0, 0, castle_flag)); + pns.push_back(make_move(from, pos, board[pos], PieceType::NONE, 0, 0, castle_flag)); } } } @@ -60,69 +60,69 @@ void _king_add_if_not_blocked(int pos, int from, std::vector *pns, std::arr // This function is for non-ray types only, as it ignores the 'ray rules', and just jumps over stuff (e.g. knight), or only moves one space generally (e.g. king) -void _add_if_not_blocked(int pos, int from, std::vector *pns, std::array *board, Color color_of_piece, Color color_of_opposite){ +void _add_if_not_blocked(int pos, int from, std::vector& pns, const std::array& board, Color color_of_piece, Color color_of_opposite){ if (!is_valid_position(pos) || _xy_is_color(pos, board, color_of_piece)){ return; } else { - pns->push_back(make_move(from, pos, (*board)[pos])); + pns.push_back(make_move(from, pos, board[pos])); } } -void _add_pawn_promotions(int from, int to, PieceType capture, Color color_of_piece, std::vector *pns){ +void _add_pawn_promotions(int from, int to, PieceType capture, Color color_of_piece, std::vector& pns){ if (color_of_piece == Color::WHITE){ - pns->push_back(make_move(from, to, capture, PieceType::W_KNIGHT)); - pns->push_back(make_move(from, to, capture, PieceType::W_BISHOP)); - pns->push_back(make_move(from, to, capture, PieceType::W_ROOK)); - pns->push_back(make_move(from, to, capture, PieceType::W_QUEEN)); + pns.push_back(make_move(from, to, capture, PieceType::W_KNIGHT)); + pns.push_back(make_move(from, to, capture, PieceType::W_BISHOP)); + pns.push_back(make_move(from, to, capture, PieceType::W_ROOK)); + pns.push_back(make_move(from, to, capture, PieceType::W_QUEEN)); } else { - pns->push_back(make_move(from, to, capture, PieceType::B_KNIGHT)); - pns->push_back(make_move(from, to, capture, PieceType::B_BISHOP)); - pns->push_back(make_move(from, to, capture, PieceType::B_ROOK)); - pns->push_back(make_move(from, to, capture, PieceType::B_QUEEN)); + pns.push_back(make_move(from, to, capture, PieceType::B_KNIGHT)); + pns.push_back(make_move(from, to, capture, PieceType::B_BISHOP)); + pns.push_back(make_move(from, to, capture, PieceType::B_ROOK)); + pns.push_back(make_move(from, to, capture, PieceType::B_QUEEN)); } } // This is a specialized function for the pawn's diagonal takes. // It will only to pns if there is a piece of opposite color on it. -void _pawn_diag_add_if_not_blocked(int pos, int from, std::vector *pns, std::array *board, Color color_of_piece, Color color_of_opposite, int en_passant, int promoting){ +void _pawn_diag_add_if_not_blocked(int pos, int from, std::vector& pns, const std::array& board, Color color_of_piece, Color color_of_opposite, int en_passant, int promoting){ if (is_valid_position(pos)){ // Theoretically this is not run with en_passant because those flags should NEVER overlap, but if it does, my tests will alert me. if (_xy_is_color(pos, board, color_of_opposite)){ if (promoting){ - _add_pawn_promotions(from, pos, (*board)[pos], color_of_piece, pns); + _add_pawn_promotions(from, pos, board[pos], color_of_piece, pns); } else { - pns->push_back(make_move(from, pos, (*board)[pos])); + pns.push_back(make_move(from, pos, board[pos])); } } else if (pos == en_passant){ // If capturing from the left to the right, set the captured piece to directly right of current from pos (+1) // ...otherwise get to the right (-1) int captured_pos = from-pos>0?from+1:from-1; - pns->push_back(make_move(from, pos, (*board)[captured_pos], PieceType::NONE, 1)); + pns.push_back(make_move(from, pos, board[captured_pos], PieceType::NONE, 1)); } } } // This is a specialized functions for the pawn's inability to take going forward. // Notice the lack of push_backion where there usually is when (x,y) is a different color. -void _pawn_add_if_not_blocked(int pos, int from, std::vector *pns, std::array *board, Color color_of_piece, Color color_of_opposite, bool *is_not_blocked, bool double_move, bool promoted){ +void _pawn_add_if_not_blocked(int pos, int from, std::vector& pns, const std::array& board, Color color_of_piece, Color color_of_opposite, bool *is_not_blocked, bool double_move, bool promoted){ if (*is_not_blocked){ - if ((*board)[pos] != PieceType::NONE || - (*board)[pos] == PieceType::INV){ + if (board[pos] != PieceType::NONE || + board[pos] == PieceType::INV){ *is_not_blocked = false; } else if (double_move){ - pns->push_back(make_move(from, pos, PieceType::NONE, PieceType::NONE, 0, 1)); + pns.push_back(make_move(from, pos, PieceType::NONE, PieceType::NONE, 0, 1)); } else if (promoted){ _add_pawn_promotions(from, pos, PieceType::NONE, color_of_piece, pns); } else { - pns->push_back(make_move(from, pos, (*board)[pos])); + pns.push_back(make_move(from, pos, board[pos])); } } } -void _get_all_moves_rook(int pos, std::vector *pns, std::array* board, Color pc, Color rc){ +void _get_all_moves_rook(int pos, std::vector& pns, const std::array& board, Color pc, Color rc){ for (int rk_off : ROOK_PIECE_OFFSETS){ bool* not_blocked = new bool(true); for (int offset=1; offset<8; offset++){ @@ -131,7 +131,7 @@ void _get_all_moves_rook(int pos, std::vector *pns, std::array *pns, std::array* board, Color pc, Color rc){ +void _get_all_moves_bishop(int pos, std::vector& pns, const std::array& board, Color pc, Color rc){ for (int bs_off : BISHOP_PIECE_OFFSETS){ bool* not_blocked = new bool(true); for (int offset=1; offset<8; offset++){ @@ -140,13 +140,13 @@ void _get_all_moves_bishop(int pos, std::vector *pns, std::array *pns, std::array* board, Color pc, Color rc){ +void _get_all_moves_knight(int pos, std::vector& pns, const std::array& board, Color pc, Color rc){ for (int kn_off : KNIGHT_PIECE_OFFSETS){ _add_if_not_blocked(pos+kn_off, pos, pns, board, pc, rc); } } -void _get_all_moves_king(int pos, std::vector *pns, std::array* board, Color pc, Color rc, int castle_perms){ +void _get_all_moves_king(int pos, std::vector& pns, const std::array& board, Color pc, Color rc, int castle_perms){ for (int kn_off : KING_PIECE_OFFSETS){ _add_if_not_blocked(pos+kn_off, pos, pns, board, pc, rc); } @@ -161,7 +161,7 @@ void _get_all_moves_king(int pos, std::vector *pns, std::array *pns, std::array *pns, std::array* board, Color pc, Color rc, int en_passant){ +void _get_all_moves_pawn(int pos, std::vector& pns, const std::array& board, Color pc, Color rc, int en_passant){ // if it's white use different offsets, and pawn starting rank int offset2 = pc==Color::WHITE?-20:20; diff --git a/src/functions.cpp b/src/functions.cpp index 0b193d3..d5a44a7 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -12,9 +12,6 @@ #include #include -// TODO implement functions.h functions. -// NOTE tests will NOT run unless you implement these functions. - Rank get_rank(int pos){ int rank = 0; while (pos >= 0){ @@ -43,8 +40,8 @@ Color get_color(PieceType pt){ return Color::NO_COLOR; } -Color get_color(int pn, std::array const *board){ - return get_color((*board)[pn]); +Color get_color(int pn, const std::array& board){ + return get_color(board[pn]); } Color rev_color(Color c){ @@ -65,46 +62,45 @@ PieceType rev_color(PieceType pt){ return PieceType::NONE; } -std::vector get_possible_movers(Position pn, std::array board){ +std::vector get_possible_movers(Position pn, const std::array& board){ std::vector pns = {Position::A1}; return pns; } -int get_pos_of(PieceType pt, std::array const *board){ +int get_pos_of(PieceType pt, const std::array& board){ for (int pn = Position::A8; pn!=Position::H1; pn++){ - if ((*board)[pn] == pt){ + if (board[pn] == pt){ return pn; } } return Position::NA; } -std::vector get_poss_of(PieceType pt, std::array const *board){ +std::vector get_poss_of(PieceType pt, const std::array& board){ std::vector results; for (int pn = Position::A8; pn!=Position::H1; pn++){ - if ((*board)[pn] == pt){ + if (board[pn] == pt){ results.push_back(pn); } } return results; } -void get_poss_of(PieceType pt, std::array* board, std::vector* pns){ +void get_poss_of(PieceType pt, const std::array& board, std::vector& pns){ for (int pn = Position::A8; pn!=Position::H1; pn++){ - if ((*board)[pn] == pt){ - pns->push_back(pn); + if (board[pn] == pt){ + pns.push_back(pn); } } } -bool is_attacked(int pos, std::array board){ - PieceType ptt = board[pos]; - Color pc = get_color(ptt); +bool would_be_attacked(int pos, PieceType piece, const std::array& board){ + Color pc = get_color(piece); auto other_pieces = pc==Color::WHITE?Pieces::BLACK:Pieces::WHITE; for (PieceType opposite_color_piece : other_pieces){ PieceType same_color_piece = rev_color(opposite_color_piece); std::vector moves; - get_all_moves_as_if(pos, same_color_piece, &board, &moves, false); + get_all_moves_as_if(pos, same_color_piece, board, moves, false); for (int reverse_move : moves){ if (get_captured_pc(reverse_move) == opposite_color_piece){ return true; @@ -112,19 +108,25 @@ bool is_attacked(int pos, std::array board){ } } return false; + +} + +bool is_attacked(int pos, const std::array& board){ + return would_be_attacked(pos, board[pos], board); } -bool king_checked(std::array *board, Color color_of_king){ +bool king_checked(const 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); + return is_attacked(king_pos, board); } -void add_checked_flags(PieceType pt, std::array *board, std::vector *pns){ +void add_checked_flags(PieceType pt, const 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); - for (auto move_pn=pns->begin(); move_pn!=pns->end();){ - auto moved_board = dumb_move(*move_pn, *board); + for (auto move_pn=pns.begin(); move_pn!=pns.end();){ + std::array moved_board; + dumb_move(*move_pn, board, moved_board); if (is_attacked(other_king_pos, moved_board)){ *move_pn |= (1 << 25); } @@ -133,17 +135,17 @@ void add_checked_flags(PieceType pt, std::array *board, std::vec } //TODO: Make faster by running from king squar eonly, instead of running on every piece of opposite team. -void filter_checked_moves(PieceType pt, std::array *board, std::vector *pns){ +void filter_checked_moves(PieceType pt, const std::array& board, std::vector& pns){ PieceType my_king = is_white(pt)?PieceType::W_KING:PieceType::B_KING; int my_king_pos = get_pos_of(my_king, board); bool remove_all_castles = false; - for (auto p_pn= pns->begin(); p_pn!=pns->end();){ + for (auto p_pn= pns.begin(); p_pn!=pns.end();){ if (get_castle_flag(*p_pn) == 1){ // If removing all castle flags is triggered // (by being in check) // remove all of them. if (remove_all_castles){ - p_pn = pns->erase(p_pn); + p_pn = pns.erase(p_pn); ++p_pn; break; } @@ -152,26 +154,18 @@ void filter_checked_moves(PieceType pt, std::array *board, std:: // If moved left // Queenside if ((get_from_sq(*p_pn) - get_to_sq(*p_pn)) > 0){ - int right_move = make_move(get_from_sq(*p_pn), get_to_sq(*p_pn)+1); - int full_move = make_move(get_from_sq(*p_pn), get_to_sq(*p_pn)); - auto right_board = dumb_move(right_move, *board); - auto full_board = dumb_move(full_move, *board); - if (is_attacked(get_to_sq(*p_pn)+1, right_board) || - is_attacked(get_to_sq(*p_pn), full_board)){ - p_pn = pns->erase(p_pn); + if(would_be_attacked(get_to_sq(*p_pn), my_king, board) || + would_be_attacked(get_to_sq(*p_pn)+1, my_king, board)){ + p_pn = pns.erase(p_pn); } else { ++p_pn; break; } // Kingside } else { - int left_move = make_move(get_from_sq(*p_pn), get_to_sq(*p_pn)-1); - int full_move = make_move(get_from_sq(*p_pn), get_to_sq(*p_pn)); - auto left_board = dumb_move(left_move, *board); - auto full_board = dumb_move(full_move, *board); - if (is_attacked(get_to_sq(*p_pn)-1, left_board) || - is_attacked(get_to_sq(*p_pn), full_board)){ - p_pn = pns->erase(p_pn); + if(would_be_attacked(get_to_sq(*p_pn), my_king, board) || + would_be_attacked(get_to_sq(*p_pn)-1, my_king, board)){ + p_pn = pns.erase(p_pn); } else { ++p_pn; break; @@ -182,11 +176,12 @@ void filter_checked_moves(PieceType pt, std::array *board, std:: // remove all castle moves if ((pt == PieceType::W_KING || pt == PieceType::B_KING) && - is_attacked(get_from_sq(*p_pn), *board)){ + is_attacked(get_from_sq(*p_pn), board)){ remove_all_castles = true; } // Make move - std::array moved_board = dumb_move(*p_pn, *board); + std::array moved_board; + dumb_move(*p_pn, board, moved_board); // This is for when the king is the same piece that is moving. // If this is the case, reset to king position to the new position given by the get_to_sq() of the move. if (pt == my_king){ @@ -194,7 +189,7 @@ void filter_checked_moves(PieceType pt, std::array *board, std:: } if (is_attacked(my_king_pos, moved_board)){ - p_pn = pns->erase(p_pn); + p_pn = pns.erase(p_pn); } else { ++p_pn; } @@ -202,7 +197,7 @@ void filter_checked_moves(PieceType pt, std::array *board, std:: } } -void get_all_moves_as_if(int pos, PieceType pt, std::array* board, std::vector* moves, bool recursive, int en_passant, int castle_perms){ +void get_all_moves_as_if(int pos, PieceType pt, const std::array& board, std::vector& moves, bool recursive, int en_passant, int castle_perms){ Color color_of_piece = get_color(pt); Color color_of_opponent = rev_color(color_of_piece); switch(pt){ @@ -240,18 +235,16 @@ void get_all_moves_as_if(int pos, PieceType pt, std::array* boar } } -void get_all_moves(int pos, std::array *board, std::vector *moves, bool recursive, int en_passant, int castle_perms){ - get_all_moves_as_if(pos, (*board)[pos], board, moves, recursive, en_passant, castle_perms); +void get_all_moves(int pos, const std::array& board, std::vector& moves, bool recursive, int en_passant, int castle_perms){ + get_all_moves_as_if(pos, board[pos], board, moves, recursive, en_passant, castle_perms); } - -std::vector get_all_moves(int pos, std::array board, bool recursive, int en_passant, int castle_perms){ - std::vector moves; - get_all_moves(pos, &board, &moves, recursive, en_passant, castle_perms); +std::vector get_all_moves(int pos, const std::array& board, bool recursive, int en_passant, int castle_perms){ + std::vector moves = {}; + get_all_moves_as_if(pos, board[pos], board, moves, recursive, en_passant, castle_perms); return moves; } -std::array dumb_move(int move, std::array board){ - std::array new_board; +void dumb_move(int move, const std::array& board, std::array& new_board){ std::copy(std::begin(board), std::end(board), std::begin(new_board)); int en_passant_flag = get_en_pass_flag(move); int castle_flag = get_castle_flag(move); @@ -295,44 +288,49 @@ std::array dumb_move(int move, std::array board) new_board[to] = piece; new_board[from] = PieceType::NONE; } +} +std::array dumb_move(int pos, const std::array& board){ + std::array new_board = {}; + dumb_move(pos, board, new_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();){ +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); + 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)); +void _non_pawn_disambiguate(int from, int to, int piecetype, const 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]; + disambig = POSITION_STRING[from][1]; } - } else if (moves->size() > 1){ - *disambig = POSITION_STRING[from]; + } else if (moves.size() > 1){ + disambig = POSITION_STRING[from]; } } -std::string to_notation(int move, std::array *board){ +std::string to_notation(int move, const std::array& board){ std::stringstream ss; - auto moved_board = dumb_move(move, *board); + std::array moved_board; + dumb_move(move, board, moved_board); int from = get_from_sq(move); - PieceType piecetype = (*board)[from]; + PieceType piecetype = board[from]; std::string from_string = POSITION_STRING[from]; int to = get_to_sq(move); int captured_piece = get_captured_pc(move); @@ -386,11 +384,11 @@ std::string to_notation(int move, std::array *board){ // 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); + 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); + _filter_unneeded_squares(other_moves, piecetype, from); piece_character = CHESS_CHARS_INSENSITIVE[piecetype]; - _non_pawn_disambiguate(from, to, piecetype, &other_moves, &disambig); + _non_pawn_disambiguate(from, to, piecetype, other_moves, disambig); } if (get_en_pass_flag(move) == 1){ en_passant = "e.p."; @@ -400,7 +398,7 @@ 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 = {}; - get_all_moves_for_pieces(other_pieces, &moved_board, &other_moves); + get_all_moves_for_pieces(other_pieces, moved_board, other_moves); if (other_moves.empty()){ check = "#"; } @@ -418,12 +416,12 @@ std::string to_notation(int move, std::array *board){ return ss.str(); } -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, const std::array& board, std::vector& moves, int en_passant, int castle_perms){ for (PieceType pt : pieces){ for (int pos_of : get_poss_of(pt, board)){ std::vector local_moves = {}; - get_all_moves_as_if(pos_of, pt, board, &local_moves, true, en_passant, castle_perms); - moves->insert(moves->end(), local_moves.begin(), local_moves.end()); + get_all_moves_as_if(pos_of, pt, board, local_moves, true, en_passant, castle_perms); + moves.insert(moves.end(), local_moves.begin(), local_moves.end()); } } } diff --git a/src/functions.h b/src/functions.h index 7803622..8d1d473 100644 --- a/src/functions.h +++ b/src/functions.h @@ -6,8 +6,8 @@ #include // Returns a list of positions with PieceType pt -int get_pos_of(PieceType pt, std::array const *board); -std::vector get_poss_of(PieceType pt, std::array const *board); +int get_pos_of(PieceType pt, const std::array& board); +std::vector get_poss_of(PieceType pt, const std::array& board); // Convert a Position number into a pair of x y coordiinates std::pair pos_to_pair(Position pn); @@ -23,7 +23,7 @@ Rank get_rank(int pos); bool is_white(int pt); bool is_black(int pt); -Color get_color(int pn, std::array const *board); +Color get_color(int pn, const std::array& board); Color get_color(PieceType pt); // NO_COLOR returns NO_COLOR // WHITE returns BLACK @@ -34,36 +34,41 @@ PieceType rev_color(PieceType pt); // Get all positions of pieces which can move to this square // This may require helper functions for each individual peice. // TODO rename to something less stupid. -void get_possible_movers(Position pn, std::array *pt,std::vector *moves); +void get_possible_movers(Position pn, const std::array& pt ,std::vector& moves); // Get all possible moved for piece in Position pn. // This may require helper functions for each individual piece. -void get_possible_moves(Position pn, std::array *pt,std::vector *moves); +void get_possible_moves(Position pn, const std::array& pt, std::vector& moves); // This functions removes moves that put your own king in check. -void filter_checked_moves(int pos, std::array *board, std::vector *moves); +void filter_checked_moves(int pos, const std::array& board, std::vector& moves); // This function is like get_all_moves, except it doesn't check pos and base the piecetype on that, // ... but instead acts as if the PieceType pt is on pos, and returns possible move sbased on that. -void get_all_moves_as_if(int pos, PieceType pt, std::array *board, std::vector *moves, bool recursvie=true, int en_passant=Position::NA, int castle_perms=0); +void get_all_moves_as_if(int pos, PieceType pt, const std::array& board, std::vector& moves, bool recursvie=true, int en_passant=Position::NA, int castle_perms=0); // Get all moves for piece in Position pn. -void get_all_moves(int pos, std::array *pt, std::vector *moves, bool recursive=true, int en_passant=Position::NA, int castle_perms=0); -std::vector get_all_moves(int pos, std::array board, bool recursive=true, int en_passant=Position::NA, int castle_perms=0); +void get_all_moves(int pos, const std::array& pt, std::vector& moves, bool recursive=true, int en_passant=Position::NA, int castle_perms=0); +std::vector get_all_moves(int pos, const std::array& board, bool recursive=true, int en_passant=Position::NA, int castle_perms=0); // Dumb function to do board moves. // Does not check if move is valid, just does it. -std::array dumb_move(int move, std::array board); +void dumb_move(int move, const std::array& board, std::array& new_board); +std::array dumb_move(int move, const 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); +// Decides if piece pt in position pos is/would be (theoretichally) in check +bool would_be_attacked(int pos, PieceType pt, const std::array& board); + +bool is_attacked(int pos, const std::array& board); + + +bool king_checked(const std::array& board, Color king_color); // Convert move (and board becuase notation needs more info than the move itself) // ...into algbraic notation. -std::string to_notation(int move, std::array *board); +std::string to_notation(int move, const 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=0, int castle_perms=0); +void get_all_moves_for_pieces(std::array pieces, const 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); diff --git a/tests/main.cpp b/tests/main.cpp index 9eaa7ce..d457402 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -34,13 +34,13 @@ TEST_CASE("Test that get_rank() works)", "[get_rank]"){ } TEST_CASE("Test that an unordered set of positions are returned when looking for a piece type through a board", "[get_pos_of]"){ - CHECK(get_poss_of(PieceType::B_PAWN, &DEFAULT_BOARD) == B_PAWNS_SQUARES); + CHECK(get_poss_of(PieceType::B_PAWN, DEFAULT_BOARD) == B_PAWNS_SQUARES); } TEST_CASE("Test that a color can be gotten from a given square on the board", "[get_color]"){ - CHECK(get_color(Position::C8, &DUMB_MOVE_1) == Color::BLACK); - CHECK(get_color(Position::F4, &DUMB_MOVE_1) == Color::NO_COLOR); - CHECK(get_color(Position::C2, &DUMB_MOVE_1) == Color::WHITE); + CHECK(get_color(Position::C8, DUMB_MOVE_1) == Color::BLACK); + CHECK(get_color(Position::F4, DUMB_MOVE_1) == Color::NO_COLOR); + CHECK(get_color(Position::C2, DUMB_MOVE_1) == Color::WHITE); } TEST_CASE("Test that a color can be gotten from a PieceType", "[get_color]"){ CHECK(get_color(PieceType::NONE) == Color::NO_COLOR); @@ -129,6 +129,11 @@ TEST_CASE("Tests is_king_checked works", "[is_attacked]"){ CHECK(is_attacked(BLACK_CHECK_POS2, BLACK_CHECK_BOARD2)); } +TEST_CASE("Test the hypothetical positions can be tests for attacking", "[would_be_checked]"){ + CHECK_FALSE(would_be_attacked(BCASTLE_FROM_POS+1, PieceType::B_KING, CASTLE_BOARD)); + CHECK_FALSE(would_be_attacked(BCASTLE_FROM_POS+2, PieceType::B_KING, CASTLE_BOARD)); +} + TEST_CASE("Test that moves that put own king in check are not returned", "[get_all_moves]"){ CHECK(get_to_squares(get_all_moves(ROOK_CHECK_TEST_POS, ROOK_CHECK_TEST_BOARD)) == ROOK_CHECK_TEST_MOVES); CHECK(get_to_squares(get_all_moves(PAWN_CHECK_TEST_POS, PAWN_CHECK_TEST_BOARD)) == PAWN_CHECK_TEST_MOVES); @@ -293,7 +298,7 @@ TEST_CASE("Tests for check on square of queenside capture", "[get_all_moves]"){ 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)); + 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]"){ diff --git a/tests/test_functions.cpp b/tests/test_functions.cpp index 125882a..fe351f8 100644 --- a/tests/test_functions.cpp +++ b/tests/test_functions.cpp @@ -6,66 +6,66 @@ #include #include -std::vector get_to_squares(std::vector moves){ +std::vector get_to_squares(const std::vector& moves){ std::vector transformed; for (int mv : moves){ transformed.push_back(get_to_sq(mv)); } return transformed; } -std::vector get_from_squared(std::vector moves){ +std::vector get_from_squared(const std::vector& moves){ std::vector transformed; for (int mv : moves){ transformed.push_back(get_from_sq(mv)); } return transformed; } -std::vector get_captured_pieces(std::vector moves){ +std::vector get_captured_pieces(const std::vector& moves){ std::vector transformed; for (int mv : moves){ transformed.push_back(get_captured_pc(mv)); } return transformed; } -std::vector get_promoted_pieces(std::vector moves){ +std::vector get_promoted_pieces(const std::vector& moves){ std::vector transformed; for (int mv : moves){ transformed.push_back(get_promoted_to_pc(mv)); } return transformed; } -std::vector get_en_passant_flags(std::vector moves){ +std::vector get_en_passant_flags(const std::vector& moves){ std::vector transformed; for (int mv : moves){ transformed.push_back(get_en_pass_flag(mv)); } return transformed; } -std::vector get_pawn_start_flags(std::vector moves){ +std::vector get_pawn_start_flags(const std::vector& moves){ std::vector transformed; for (int mv : moves){ transformed.push_back(get_pawn_st_flag(mv)); } return transformed; } -std::vector get_castle_flags(std::vector moves){ +std::vector get_castle_flags(const std::vector& moves){ std::vector transformed; for (int mv : moves){ transformed.push_back(get_castle_flag(mv)); } return transformed; } -std::vector get_checked_flags(std::vector moves){ +std::vector get_checked_flags(const std::vector& moves){ std::vector transformed; for (int mv : moves){ transformed.push_back(get_check_flag(mv)); } return transformed; } -std::vector get_notations(std::vector moves, std::array board){ +std::vector get_notations(const std::vector& moves, const std::array& board){ std::vector notations; for (int move : moves){ - notations.push_back(to_notation(move, &board)); + notations.push_back(to_notation(move, board)); } return notations; } diff --git a/tests/test_functions.h b/tests/test_functions.h index 0c217c0..38cb3e5 100644 --- a/tests/test_functions.h +++ b/tests/test_functions.h @@ -5,13 +5,13 @@ #include #include -std::vector get_from_squares(std::vector moves); -std::vector get_to_squares(std::vector moves); -std::vector get_captured_pieces(std::vector moves); -std::vector get_promoted_pieces(std::vector moves); -std::vector get_en_passant_flags(std::vector moves); -std::vector get_pawn_start_flags(std::vector moves); -std::vector get_castle_flags(std::vector moves); -std::vector get_checked_flags(std::vector moves); -std::vector get_notations(std::vector moves, std::array board); +std::vector get_from_squares(const std::vector& moves); +std::vector get_to_squares(const std::vector& moves); +std::vector get_captured_pieces(const std::vector& moves); +std::vector get_promoted_pieces(const std::vector& moves); +std::vector get_en_passant_flags(const std::vector& moves); +std::vector get_pawn_start_flags(const std::vector& moves); +std::vector get_castle_flags(const std::vector& moves); +std::vector get_checked_flags(const std::vector& moves); +std::vector get_notations(const std::vector& moves, const std::array& board); #endif