* -> & (use references instead of pointers)

master
Tait Hoyem 5 years ago
parent 096676fc36
commit 6269bc0311

@ -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<PieceType, 120>* board, Color c){
return c==Color::WHITE ? is_white((*board)[pos]) : is_black((*board)[pos]);
bool _xy_is_color(int pos, const std::array<PieceType, 120>& 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<int> *pns, std::array<PieceType, 120> *board, Color color_of_piece, Color color_of_opposite, bool *is_not_blocked){
void _add_if_not_blocked(int pos, int from, std::vector<int>& pns, const std::array<PieceType, 120>& 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<int> *pns, std::array<Pi
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]));
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<int> *pns, std::array<PieceType, 120> *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<int>& pns, const std::array<PieceType, 120>& 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<int> *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<int> *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<int> *pns, std::array<PieceType, 120> *board, Color color_of_piece, Color color_of_opposite){
void _add_if_not_blocked(int pos, int from, std::vector<int>& pns, const std::array<PieceType, 120>& 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<int> *pns){
void _add_pawn_promotions(int from, int to, PieceType capture, Color color_of_piece, std::vector<int>& 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<int> *pns, std::array<PieceType, 120> *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<int>& pns, const std::array<PieceType, 120>& 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<int> *pns, std::array<PieceType, 120> *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<int>& pns, const std::array<PieceType, 120>& 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<int> *pns, std::array<PieceType, 120>* board, Color pc, Color rc){
void _get_all_moves_rook(int pos, std::vector<int>& pns, const std::array<PieceType, 120>& 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<int> *pns, std::array<PieceType, 1
}
}
void _get_all_moves_bishop(int pos, std::vector<int> *pns, std::array<PieceType, 120>* board, Color pc, Color rc){
void _get_all_moves_bishop(int pos, std::vector<int>& pns, const std::array<PieceType, 120>& 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<int> *pns, std::array<PieceType,
}
}
void _get_all_moves_knight(int pos, std::vector<int> *pns, std::array<PieceType, 120>* board, Color pc, Color rc){
void _get_all_moves_knight(int pos, std::vector<int>& pns, const std::array<PieceType, 120>& 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<int> *pns, std::array<PieceType, 120>* board, Color pc, Color rc, int castle_perms){
void _get_all_moves_king(int pos, std::vector<int>& pns, const std::array<PieceType, 120>& 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<int> *pns, std::array<PieceType, 1
if (castle_perms & CastlePerms::WKS){
_king_add_if_not_blocked(pos+2, pos, pns, board, pc, rc, right_castle, 1);
}
if (castle_perms & CastlePerms::WQS && (*board)[pos-3] == PieceType::NONE){
if (castle_perms & CastlePerms::WQS && board[pos-3] == PieceType::NONE){
_king_add_if_not_blocked(pos-2, pos, pns, board, pc, rc, left_castle, 1);
}
} else {
@ -170,13 +170,13 @@ void _get_all_moves_king(int pos, std::vector<int> *pns, std::array<PieceType, 1
if (castle_perms & CastlePerms::BKS){
_king_add_if_not_blocked(pos+2, pos, pns, board, pc, rc, right_castle, 1);
}
if (castle_perms & CastlePerms::BQS && (*board)[pos-3] == PieceType::NONE){
if (castle_perms & CastlePerms::BQS && board[pos-3] == PieceType::NONE){
_king_add_if_not_blocked(pos-2, pos, pns, board, pc, rc, left_castle, 1);
}
}
}
void _get_all_moves_pawn(int pos, std::vector<int> *pns, std::array<PieceType, 120>* board, Color pc, Color rc, int en_passant){
void _get_all_moves_pawn(int pos, std::vector<int>& pns, const std::array<PieceType, 120>& 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;

@ -12,9 +12,6 @@
#include <stdio.h>
#include <math.h>
// 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<PieceType, 120> const *board){
return get_color((*board)[pn]);
Color get_color(int pn, const std::array<PieceType, 120>& 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<int> get_possible_movers(Position pn, std::array<PieceType, 120> board){
std::vector<int> get_possible_movers(Position pn, const std::array<PieceType, 120>& board){
std::vector<int> pns = {Position::A1};
return pns;
}
int get_pos_of(PieceType pt, std::array<PieceType, 120> const *board){
int get_pos_of(PieceType pt, const std::array<PieceType, 120>& 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<int> get_poss_of(PieceType pt, std::array<PieceType, 120> const *board){
std::vector<int> get_poss_of(PieceType pt, const std::array<PieceType, 120>& board){
std::vector<int> 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<PieceType, 120>* board, std::vector<int>* pns){
void get_poss_of(PieceType pt, const std::array<PieceType, 120>& board, std::vector<int>& 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<PieceType, 120> board){
PieceType ptt = board[pos];
Color pc = get_color(ptt);
bool would_be_attacked(int pos, PieceType piece, const std::array<PieceType, 120>& 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<int> 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<PieceType, 120> board){
}
}
return false;
}
bool is_attacked(int pos, const std::array<PieceType, 120>& board){
return would_be_attacked(pos, board[pos], board);
}
bool king_checked(std::array<PieceType, 120> *board, Color color_of_king){
bool king_checked(const std::array<PieceType, 120>& 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<PieceType, 120> *board, std::vector<int> *pns){
void add_checked_flags(PieceType pt, const std::array<PieceType, 120>& board, std::vector<int>& 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<PieceType, 120> 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<PieceType, 120> *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<PieceType, 120> *board, std::vector<int> *pns){
void filter_checked_moves(PieceType pt, const std::array<PieceType, 120>& board, std::vector<int>& 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<PieceType, 120> *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<PieceType, 120> *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<PieceType, 120> moved_board = dumb_move(*p_pn, *board);
std::array<PieceType, 120> 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<PieceType, 120> *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<PieceType, 120> *board, std::
}
}
void get_all_moves_as_if(int pos, PieceType pt, std::array<PieceType, 120>* board, std::vector<int>* moves, bool recursive, int en_passant, int castle_perms){
void get_all_moves_as_if(int pos, PieceType pt, const std::array<PieceType, 120>& board, std::vector<int>& 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<PieceType, 120>* boar
}
}
void get_all_moves(int pos, std::array<PieceType, 120> *board, std::vector<int> *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<PieceType, 120>& board, std::vector<int>& 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<int> get_all_moves(int pos, std::array<PieceType, 120> board, bool recursive, int en_passant, int castle_perms){
std::vector<int> moves;
get_all_moves(pos, &board, &moves, recursive, en_passant, castle_perms);
std::vector<int> get_all_moves(int pos, const std::array<PieceType, 120>& board, bool recursive, int en_passant, int castle_perms){
std::vector<int> moves = {};
get_all_moves_as_if(pos, board[pos], board, moves, recursive, en_passant, castle_perms);
return moves;
}
std::array<PieceType, 120> dumb_move(int move, std::array<PieceType, 120> board){
std::array<PieceType, 120> new_board;
void dumb_move(int move, const std::array<PieceType, 120>& board, std::array<PieceType, 120>& 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<PieceType, 120> dumb_move(int move, std::array<PieceType, 120> board)
new_board[to] = piece;
new_board[from] = PieceType::NONE;
}
}
std::array<PieceType, 120> dumb_move(int pos, const std::array<PieceType, 120>& board){
std::array<PieceType, 120> new_board = {};
dumb_move(pos, board, new_board);
return new_board;
}
void _filter_unneeded_squares(std::vector<int> *moves, int piecetype, int origin){
for (auto move_pn=moves->begin(); move_pn!=moves->end();){
void _filter_unneeded_squares(std::vector<int>& 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<int> *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<int>& 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_from<from?other_from:from;
int max_from = other_from>from?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<PieceType, 120> *board){
std::string to_notation(int move, const std::array<PieceType, 120>& board){
std::stringstream ss;
auto moved_board = dumb_move(move, *board);
std::array<PieceType, 120> 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<PieceType, 120> *board){
// and stores any duplicates in the other_moves variable.
PieceType opposite_piece = rev_color(piecetype);
std::vector<int> 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<PieceType, 120> *board){
// This checks if the other team has any valid moves.
// If not, the check sign changes to a hashtag (#).
std::vector<int> 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<PieceType, 120> *board){
return ss.str();
}
void get_all_moves_for_pieces(std::array<PieceType, 6> pieces, std::array<PieceType, 120> *board, std::vector<int> *moves, int en_passant, int castle_perms){
void get_all_moves_for_pieces(std::array<PieceType, 6> pieces, const std::array<PieceType, 120>& board, std::vector<int>& moves, int en_passant, int castle_perms){
for (PieceType pt : pieces){
for (int pos_of : get_poss_of(pt, board)){
std::vector<int> 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());
}
}
}

@ -6,8 +6,8 @@
#include <math.h>
// Returns a list of positions with PieceType pt
int get_pos_of(PieceType pt, std::array<PieceType, 120> const *board);
std::vector<int> get_poss_of(PieceType pt, std::array<PieceType, 120> const *board);
int get_pos_of(PieceType pt, const std::array<PieceType, 120>& board);
std::vector<int> get_poss_of(PieceType pt, const std::array<PieceType, 120>& board);
// Convert a Position number into a pair of x y coordiinates
std::pair<int, int> 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<PieceType, 120> const *board);
Color get_color(int pn, const std::array<PieceType, 120>& 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<PieceType, 120> *pt,std::vector<int> *moves);
void get_possible_movers(Position pn, const std::array<PieceType, 120>& pt ,std::vector<int>& 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<PieceType, 120> *pt,std::vector<int> *moves);
void get_possible_moves(Position pn, const std::array<PieceType, 120>& pt, std::vector<int>& moves);
// This functions removes moves that put your own king in check.
void filter_checked_moves(int pos, std::array<PieceType, 120> *board, std::vector<int> *moves);
void filter_checked_moves(int pos, const std::array<PieceType, 120>& board, std::vector<int>& 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<PieceType, 120> *board, std::vector<int> *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<PieceType, 120>& board, std::vector<int>& 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<PieceType, 120> *pt, std::vector<int> *moves, bool recursive=true, int en_passant=Position::NA, int castle_perms=0);
std::vector<int> get_all_moves(int pos, std::array<PieceType, 120> board, bool recursive=true, int en_passant=Position::NA, int castle_perms=0);
void get_all_moves(int pos, const std::array<PieceType, 120>& pt, std::vector<int>& moves, bool recursive=true, int en_passant=Position::NA, int castle_perms=0);
std::vector<int> get_all_moves(int pos, const std::array<PieceType, 120>& 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<PieceType, 120> dumb_move(int move, std::array<PieceType, 120> board);
void dumb_move(int move, const std::array<PieceType, 120>& board, std::array<PieceType, 120>& new_board);
std::array<PieceType, 120> dumb_move(int move, const std::array<PieceType, 120>& board);
// Decides if there this piece in position is in check
bool is_attacked(int pos, std::array<PieceType, 120> board);
bool king_checked(std::array<PieceType, 120> *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<PieceType, 120>& board);
bool is_attacked(int pos, const std::array<PieceType, 120>& board);
bool king_checked(const std::array<PieceType, 120>& 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<PieceType, 120> *board);
std::string to_notation(int move, const std::array<PieceType, 120>& 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<PieceType, 6> pieces, std::array<PieceType, 120> *board, std::vector<int> *moves, int en_passant=0, int castle_perms=0);
void get_all_moves_for_pieces(std::array<PieceType, 6> pieces, const std::array<PieceType, 120>& board, std::vector<int>& moves, int en_passant=0, int castle_perms=0);
void remove_chars_from_string(std::string &std, std::string to_remove);

@ -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]"){

@ -6,66 +6,66 @@
#include <constants.h>
#include <functions.h>
std::vector<int> get_to_squares(std::vector<int> moves){
std::vector<int> get_to_squares(const std::vector<int>& moves){
std::vector<int> transformed;
for (int mv : moves){
transformed.push_back(get_to_sq(mv));
}
return transformed;
}
std::vector<int> get_from_squared(std::vector<int> moves){
std::vector<int> get_from_squared(const std::vector<int>& moves){
std::vector<int> transformed;
for (int mv : moves){
transformed.push_back(get_from_sq(mv));
}
return transformed;
}
std::vector<int> get_captured_pieces(std::vector<int> moves){
std::vector<int> get_captured_pieces(const std::vector<int>& moves){
std::vector<int> transformed;
for (int mv : moves){
transformed.push_back(get_captured_pc(mv));
}
return transformed;
}
std::vector<int> get_promoted_pieces(std::vector<int> moves){
std::vector<int> get_promoted_pieces(const std::vector<int>& moves){
std::vector<int> transformed;
for (int mv : moves){
transformed.push_back(get_promoted_to_pc(mv));
}
return transformed;
}
std::vector<int> get_en_passant_flags(std::vector<int> moves){
std::vector<int> get_en_passant_flags(const std::vector<int>& moves){
std::vector<int> transformed;
for (int mv : moves){
transformed.push_back(get_en_pass_flag(mv));
}
return transformed;
}
std::vector<int> get_pawn_start_flags(std::vector<int> moves){
std::vector<int> get_pawn_start_flags(const std::vector<int>& moves){
std::vector<int> transformed;
for (int mv : moves){
transformed.push_back(get_pawn_st_flag(mv));
}
return transformed;
}
std::vector<int> get_castle_flags(std::vector<int> moves){
std::vector<int> get_castle_flags(const std::vector<int>& moves){
std::vector<int> transformed;
for (int mv : moves){
transformed.push_back(get_castle_flag(mv));
}
return transformed;
}
std::vector<int> get_checked_flags(std::vector<int> moves){
std::vector<int> get_checked_flags(const std::vector<int>& moves){
std::vector<int> transformed;
for (int mv : moves){
transformed.push_back(get_check_flag(mv));
}
return transformed;
}
std::vector<std::string> get_notations(std::vector<int> moves, std::array<PieceType, 120> board){
std::vector<std::string> get_notations(const std::vector<int>& moves, const std::array<PieceType, 120>& board){
std::vector<std::string> notations;
for (int move : moves){
notations.push_back(to_notation(move, &board));
notations.push_back(to_notation(move, board));
}
return notations;
}

@ -5,13 +5,13 @@
#include <array>
#include <constants.h>
std::vector<int> get_from_squares(std::vector<int> moves);
std::vector<int> get_to_squares(std::vector<int> moves);
std::vector<int> get_captured_pieces(std::vector<int> moves);
std::vector<int> get_promoted_pieces(std::vector<int> moves);
std::vector<int> get_en_passant_flags(std::vector<int> moves);
std::vector<int> get_pawn_start_flags(std::vector<int> moves);
std::vector<int> get_castle_flags(std::vector<int> moves);
std::vector<int> get_checked_flags(std::vector<int> moves);
std::vector<std::string> get_notations(std::vector<int> moves, std::array<PieceType, 120> board);
std::vector<int> get_from_squares(const std::vector<int>& moves);
std::vector<int> get_to_squares(const std::vector<int>& moves);
std::vector<int> get_captured_pieces(const std::vector<int>& moves);
std::vector<int> get_promoted_pieces(const std::vector<int>& moves);
std::vector<int> get_en_passant_flags(const std::vector<int>& moves);
std::vector<int> get_pawn_start_flags(const std::vector<int>& moves);
std::vector<int> get_castle_flags(const std::vector<int>& moves);
std::vector<int> get_checked_flags(const std::vector<int>& moves);
std::vector<std::string> get_notations(const std::vector<int>& moves, const std::array<PieceType, 120>& board);
#endif

Loading…
Cancel
Save