parent
580c43a8e8
commit
f18240cf5a
@ -1,183 +0,0 @@
|
||||
#include "bitwise_constants.h"
|
||||
#include <unordered_set>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
const std::array<int, 4> ROOK_PIECE_OFFSETS = {-1, -10, 1, 10};
|
||||
const std::array<int, 4> BISHOP_PIECE_OFFSETS = {-11, -9, 9, 11};
|
||||
const std::array<int, 8> KNIGHT_PIECE_OFFSETS = {-12, -21, -19, -8, 8, 12, 19, 21};
|
||||
const std::array<int, 8> KING_PIECE_OFFSETS = {-11, -10, -9, -1, 1, 9, 10, 11};
|
||||
|
||||
|
||||
inline Position _pair_to_pos_unsafe(int x, int y){
|
||||
return static_cast<Position>(std::abs(y-7)*8 + x);
|
||||
}
|
||||
|
||||
void _push_if_valid_pos(int pos, std::unordered_set<int> *pns){
|
||||
if (is_valid_position(pos)){
|
||||
pns->insert(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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]);
|
||||
}
|
||||
|
||||
Color _rev_color(Color c){
|
||||
return c==Color::WHITE ? Color::BLACK : Color::WHITE;
|
||||
}
|
||||
|
||||
// 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, std::unordered_set<int> *pns, 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;
|
||||
} else {
|
||||
if (_xy_is_color(pos, board, color_of_piece)){
|
||||
*is_not_blocked = false;
|
||||
} else if (_xy_is_color(pos, board, color_of_opposite)){
|
||||
pns->insert(pos);
|
||||
*is_not_blocked = false;
|
||||
} else {
|
||||
pns->insert(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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, std::unordered_set<int> *pns, std::array<PieceType, 120> *board, Color color_of_piece, Color color_of_opposite){
|
||||
if (_xy_is_color(pos, board, color_of_piece)){
|
||||
return;
|
||||
} else {
|
||||
pns->insert(pos);
|
||||
}
|
||||
}
|
||||
|
||||
// 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, std::unordered_set<int> *pns, std::array<PieceType, 120> *board, Color color_of_piece, Color color_of_opposite, int en_passant){
|
||||
if (is_valid_position(pos) && (_xy_is_color(pos, board, color_of_opposite) ||
|
||||
pos == en_passant)){
|
||||
pns->insert(pos);
|
||||
}
|
||||
}
|
||||
// This is a specialized functions for the pawn's inability to take going forward.
|
||||
// Notice the lack of insertion where there usually is when (x,y) is a different color.
|
||||
void _pawn_add_if_not_blocked(int pos, std::unordered_set<int> *pns, 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;
|
||||
} else {
|
||||
if (_xy_is_color(pos, board, color_of_piece)){
|
||||
*is_not_blocked = false;
|
||||
} else if (_xy_is_color(pos, board, color_of_opposite)){
|
||||
*is_not_blocked = false;
|
||||
} else {
|
||||
pns->insert(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _get_all_moves_rook(int pos, std::unordered_set<int> *pns, 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++){
|
||||
_add_if_not_blocked(pos+(rk_off*offset), pns, board, pc, rc, not_blocked);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bool* not_blocked_addx = new bool(true);
|
||||
bool* not_blocked_minx = new bool(true);
|
||||
bool* not_blocked_addy = new bool(true);
|
||||
bool* not_blocked_miny = new bool(true);
|
||||
for (int offset=1; offset<8; offset++){
|
||||
_add_if_not_blocked(x+offset, y, pns, board, pc, rc, not_blocked_addx);
|
||||
_add_if_not_blocked(x, y+offset, pns, board, pc, rc, not_blocked_addy);
|
||||
_add_if_not_blocked(x-offset, y, pns, board, pc, rc, not_blocked_minx);
|
||||
_add_if_not_blocked(x, y-offset, pns, board, pc, rc, not_blocked_miny);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void _get_all_moves_bishop(int pos, std::unordered_set<int> *pns, 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++){
|
||||
_add_if_not_blocked(pos+(bs_off*offset), pns, board, pc, rc, not_blocked);
|
||||
}
|
||||
}
|
||||
/*
|
||||
bool* not_blocked_addx_addy = new bool(true);
|
||||
bool* not_blocked_addx_miny = new bool(true);
|
||||
bool* not_blocked_minx_addy = new bool(true);
|
||||
bool* not_blocked_minx_miny = new bool(true);
|
||||
|
||||
for (int offset=1; offset<8; offset++){
|
||||
int xpoff = x+offset;
|
||||
int ypoff = y+offset;
|
||||
int xnoff = x-offset;
|
||||
int ynoff = y-offset;
|
||||
_add_if_not_blocked(xpoff, ypoff, pns, board, pc, rc, not_blocked_addx_addy);
|
||||
_add_if_not_blocked(xpoff, ynoff, pns, board, pc, rc, not_blocked_addx_miny);
|
||||
_add_if_not_blocked(xnoff, ypoff, pns, board, pc, rc, not_blocked_minx_addy);
|
||||
_add_if_not_blocked(xnoff, ynoff, pns, board, pc, rc, not_blocked_minx_miny);
|
||||
}
|
||||
*/
|
||||
}
|
||||
void _get_all_moves_knight(int pos, std::unordered_set<int> *pns, std::array<PieceType, 120>* board, Color pc, Color rc){
|
||||
for (int kn_off : KNIGHT_PIECE_OFFSETS){
|
||||
bool* not_blocked = new bool(true);
|
||||
_add_if_not_blocked(pos+kn_off, pns, board, pc, rc);
|
||||
}
|
||||
/*
|
||||
for (int xo=1;xo<=2;xo++){
|
||||
int yo=(xo==1)?2:1;
|
||||
_add_if_not_blocked(x+xo, y+yo, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x-xo, y+yo, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x+xo, y-yo, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x-xo, y-yo, pns, board, pc, rc);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void _get_all_moves_king(int pos, std::unordered_set<int> *pns, std::array<PieceType, 120>* board, Color pc, Color rc){
|
||||
for (int kn_off : KING_PIECE_OFFSETS){
|
||||
bool* not_blocked = new bool(true);
|
||||
_add_if_not_blocked(pos+kn_off, pns, board, pc, rc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
_add_if_not_blocked(x+1, y+1, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x+1, y-1, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x-1, y+1, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x-1, y-1, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x, y+1, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x, y-1, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x+1, y, pns, board, pc, rc);
|
||||
_add_if_not_blocked(x-1, y, pns, board, pc, rc);
|
||||
*/
|
||||
}
|
||||
|
||||
void _get_all_moves_pawn(int pos, std::unordered_set<int> *pns, 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;
|
||||
int offset1 = pc==Color::WHITE?10:-10;
|
||||
int default_pawn_rank = pc==Color::WHITE?Rank::RANK2:Rank::RANK7;
|
||||
|
||||
bool *free_to_double_move = new bool(true);
|
||||
_pawn_add_if_not_blocked(pos+offset1, pns, board, pc, rc, free_to_double_move);
|
||||
if (get_rank(pos) == default_pawn_rank){ // If on second/seventh rank
|
||||
_pawn_add_if_not_blocked(pos+offset2, pns, board, pc, rc, free_to_double_move);
|
||||
}
|
||||
// pos+offset1 is 1 rank up (or down) depending on color.
|
||||
// Adding, or removing one will shift it over by one square, hence diagnoals.
|
||||
_pawn_diag_add_if_not_blocked(pos+offset1+1, pns, board, pc, rc, en_passant);
|
||||
_pawn_diag_add_if_not_blocked(pos+offset1-1, pns, board, pc, rc, en_passant);
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
#include "bitwise.h"
|
||||
|
||||
// Get first 6 bits of int
|
||||
// Get bits 7-12 of int
|
||||
// Get bits 13-16 of int
|
||||
// Get bits 17-20 of int
|
||||
// Get 21st bit of int
|
||||
// Get 22nd bit of int
|
||||
// Get 23rd bit of int
|
||||
|
||||
// Get last 3 bits of number (the rank).
|
||||
// Techincally this gets all bits 4-32/64 but I'm just assuming it won't be larger than 63 before the shift.
|
||||
|
||||
// Get first 3 bits of number
|
||||
// if the position has a 7th bit we know it's off the board.
|
||||
|
||||
// it indicates that is it off the board.
|
||||
// ASSUMING position <= 128 but if it was that big that'd be weird.
|
@ -1,95 +0,0 @@
|
||||
#ifndef BT_CONST_H
|
||||
#define BT_CONST_H
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
enum Color {
|
||||
NO_COLOR,
|
||||
WHITE,
|
||||
BLACK
|
||||
};
|
||||
|
||||
enum PieceType {
|
||||
INV=-1,
|
||||
NONE,
|
||||
B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING,
|
||||
W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING
|
||||
};
|
||||
namespace Pieces{
|
||||
const std::array<PieceType, 6> WHITE = {W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING};
|
||||
const std::array<PieceType, 6> BLACK = {B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING};
|
||||
}
|
||||
enum Position {
|
||||
NA=-1,
|
||||
A8=21, B8, C8, D8, E8, F8, G8, H8,
|
||||
A7=31, B7, C7, D7, E7, F7, G7, H7,
|
||||
A6=41, B6, C6, D6, E6, F6, G6, H6,
|
||||
A5=51, B5, C5, D5, E5, F5, G5, H5,
|
||||
A4=61, B4, C4, D4, E4, F4, G4, H4,
|
||||
A3=71, B3, C3, D3, E3, F3, G3, H3,
|
||||
A2=81, B2, C2, D2, E2, F2, G2, H2,
|
||||
A1=91, B1, C1, D1, E1, F1, G1, H1
|
||||
};
|
||||
|
||||
// Access with POSITION_STRING[Position]
|
||||
const std::vector<std::string> POSITION_STRING = {
|
||||
"INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV",
|
||||
"INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV",
|
||||
"INV", "A8", "B8", "C8", "D8", "E8", "F8", "G8", "H8", "INV",
|
||||
"INV", "A7", "B7", "C7", "D7", "E7", "F7", "G7", "H7", "INV",
|
||||
"INV", "A6", "B6", "C6", "D6", "E6", "F6", "G6", "H6", "INV",
|
||||
"INV", "A5", "B5", "C5", "D5", "E5", "F5", "G5", "H5", "INV",
|
||||
"INV", "A4", "B4", "C4", "D4", "E4", "F4", "G4", "H4", "INV",
|
||||
"INV", "A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3", "INV",
|
||||
"INV", "A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2", "INV",
|
||||
"INV", "A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1", "INV",
|
||||
"INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV",
|
||||
"INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV"
|
||||
};
|
||||
|
||||
enum Rank{
|
||||
RANK1,
|
||||
RANK2,
|
||||
RANK3,
|
||||
RANK4,
|
||||
RANK5,
|
||||
RANK6,
|
||||
RANK7,
|
||||
RANK8
|
||||
};
|
||||
|
||||
enum File {
|
||||
FILE1,
|
||||
FILE2,
|
||||
FILE3,
|
||||
FILE4,
|
||||
FILE5,
|
||||
FILE6,
|
||||
FILE7,
|
||||
FILE8
|
||||
};
|
||||
|
||||
const std::array<PieceType, 120> DEFAULT_BOARD = {
|
||||
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
|
||||
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
|
||||
INV, B_ROOK, B_KNIGHT, B_BISHOP, B_QUEEN, B_KING, B_BISHOP, B_KNIGHT, B_ROOK, INV,
|
||||
INV, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, INV,
|
||||
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
|
||||
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
|
||||
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
|
||||
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
|
||||
INV, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, INV,
|
||||
INV, W_ROOK, W_KNIGHT, W_BISHOP, W_QUEEN, W_KING, W_BISHOP, W_KNIGHT, W_ROOK, INV,
|
||||
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
|
||||
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV
|
||||
};
|
||||
|
||||
const std::array<char, 13> CHESS_CHARS = {
|
||||
' ',
|
||||
'P', 'N', 'B', 'R', 'Q', 'K',
|
||||
'p', 'n', 'b', 'r', 'q', 'k'
|
||||
};
|
||||
#endif
|
||||
|
@ -1,234 +0,0 @@
|
||||
#include "bitwise.h"
|
||||
#include "bitwise_functions.h"
|
||||
#include "all_moves_bitwise_functions.cpp"
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
// TODO implement functions.h functions.
|
||||
// NOTE tests will NOT run unless you implement these functions.
|
||||
|
||||
|
||||
std::pair<int, int> pos_to_pair(Position pn){
|
||||
int x,y = 0;
|
||||
for (x = pn; x >= 8; x = x-8){
|
||||
++y;
|
||||
}
|
||||
return std::make_pair(x, std::abs(y-7));
|
||||
}
|
||||
|
||||
// TODO find way to make function arbitary to board size as to allow wide game chess variants. Do much later. Not important now.
|
||||
Position pair_to_pos(std::pair<int, int> pr){
|
||||
if (pr.first > 7 || pr.first < 0
|
||||
|| pr.second > 7 || pr.second < 0) {
|
||||
throw std::invalid_argument("Cannot use any pairs with values > 7 or < 0.");
|
||||
}
|
||||
int int_val = std::abs(pr.second - 7)*8 + pr.first;
|
||||
if (int_val >= 0 && int_val < 64) {
|
||||
return static_cast<Position>(int_val);
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << "Something went terribly wrong. x and y < 8 && x and y >= 0 but abs(y-7)*8 + x < 0 or >= 64. It equalled: " << int_val;
|
||||
throw std::invalid_argument(ss.str());
|
||||
}
|
||||
}
|
||||
Position pair_to_pos(int x, int y){
|
||||
return pair_to_pos(std::make_pair(x, y));
|
||||
}
|
||||
|
||||
bool is_valid_position(std::pair<int, int> pos){
|
||||
return (pos.first < 8 && pos.second < 8 &&
|
||||
pos.first >= 0 && pos.second >=0);
|
||||
}
|
||||
bool is_valid_position(int x, int y){
|
||||
return (x < 8 && x >= 0 &&
|
||||
y < 8 && y >= 0);
|
||||
}
|
||||
|
||||
bool is_white(PieceType pt){
|
||||
for (auto pn : Pieces::WHITE){
|
||||
if (pn == pt) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool is_black(PieceType pt){
|
||||
for (auto pn : Pieces::BLACK){
|
||||
if (pn == pt) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Color get_color(PieceType pt){
|
||||
if (is_white(pt)) return Color::WHITE;
|
||||
if (is_black(pt)) return Color::BLACK;
|
||||
return Color::NO_COLOR;
|
||||
}
|
||||
|
||||
Color get_color(int x, int y, std::array<PieceType, 120> const *board){
|
||||
return get_color((*board)[pair_to_pos(x, y)]);
|
||||
}
|
||||
Color get_color(Position pn, std::array<PieceType, 120> const *board){
|
||||
return get_color((*board)[pn]);
|
||||
}
|
||||
|
||||
Color rev_color(Color c){
|
||||
if (c==Color::NO_COLOR) return Color::NO_COLOR;
|
||||
return c==Color::WHITE?Color::BLACK:Color::WHITE;
|
||||
}
|
||||
|
||||
std::unordered_set<int> get_possible_movers(Position pn, std::array<PieceType, 120> board){
|
||||
std::unordered_set<int> pns = {Position::A1};
|
||||
return pns;
|
||||
}
|
||||
|
||||
std::unordered_set<int> get_possible_moves(Position pn, std::array<PieceType, 120> board){
|
||||
std::unordered_set<int> pns = {Position::A1};
|
||||
get_all_moves(pn, &board, &pns);
|
||||
return pns;
|
||||
}
|
||||
|
||||
int get_pos_of(PieceType pt, std::array<PieceType, 120> const *board){
|
||||
for (int pn = Position::A8; pn!=Position::H1; pn++){
|
||||
if ((*board)[pn] == pt){
|
||||
return pn;
|
||||
}
|
||||
}
|
||||
return Position::NA;
|
||||
}
|
||||
|
||||
std::unordered_set<int> get_poss_of(PieceType pt, std::array<PieceType, 120> const *board){
|
||||
std::unordered_set<int> results;
|
||||
for (int pn = Position::A8; pn!=Position::H1; pn++){
|
||||
if ((*board)[pn] == pt){
|
||||
results.insert(pn);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
void get_poss_of(PieceType pt, std::array<PieceType, 120>* board, std::vector<Position>* pns){
|
||||
for (int pn = Position::A8; pn!=Position::H1; pn++){
|
||||
if ((*board)[pn] == pt){
|
||||
pns->push_back(static_cast<Position>(pn));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Make faster by running from king squar eonly, instead of running on every piece of opposite team.
|
||||
void filter_checked_moves(int pos, PieceType pt, std::array<PieceType, 120> *board, std::unordered_set<int> *pns){
|
||||
PieceType my_king = is_white(pt)?PieceType::W_KING:PieceType::B_KING;
|
||||
int my_king_pos = get_pos_of(my_king, board);
|
||||
int attackers = 0;
|
||||
for (auto p_pn= pns->begin(); p_pn!=pns->end();){
|
||||
// Make move
|
||||
int move_int = pos + (*p_pn >> 7);
|
||||
std::array<PieceType, 120> moved_board = dumb_move(move_int, *board);
|
||||
// Get all piecetypes of other team
|
||||
std::array<PieceType, 6> other_team = is_white(pt)?Pieces::BLACK:Pieces::WHITE;
|
||||
bool checks_king = false;
|
||||
// go through each piece of other team
|
||||
for (PieceType other_p : other_team) {
|
||||
checks_king = false;
|
||||
// For every place the piecetype is
|
||||
// NEW CODE
|
||||
// for (Position psn : get_all_moves(my_king_pos, moved_board, false)){
|
||||
//
|
||||
// }
|
||||
// \NEW CODE
|
||||
std::vector<Position> psns;
|
||||
get_poss_of(other_p, &moved_board, &psns);
|
||||
for (auto psn : psns){
|
||||
std::unordered_set<int> other_moves;
|
||||
get_all_moves(psn, &moved_board, &other_moves, false);
|
||||
// for every position the piece can mvoe to
|
||||
for (int cp : other_moves){
|
||||
if (get_to_sq(cp) == my_king_pos){
|
||||
checks_king = true;
|
||||
attackers++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checks_king){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checks_king){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checks_king){
|
||||
p_pn = pns->erase(p_pn);
|
||||
} else {
|
||||
++p_pn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_all_moves(int pos, std::array<PieceType, 120>* board, std::unordered_set<int>* moves, bool recursive, int en_passant){
|
||||
PieceType pt = (*board)[pos];
|
||||
Color color_of_piece = get_color(pt);
|
||||
Color color_of_opponent = rev_color(color_of_piece);
|
||||
switch(pt){
|
||||
case PieceType::B_QUEEN:
|
||||
case PieceType::W_QUEEN:
|
||||
_get_all_moves_rook(pos, moves, board, color_of_piece, color_of_opponent);
|
||||
_get_all_moves_bishop(pos, moves, board, color_of_piece, color_of_opponent);
|
||||
break;
|
||||
case PieceType::B_ROOK:
|
||||
case PieceType::W_ROOK:
|
||||
_get_all_moves_rook(pos, moves, board, color_of_piece, color_of_opponent);
|
||||
break;
|
||||
case PieceType::B_BISHOP:
|
||||
case PieceType::W_BISHOP:
|
||||
_get_all_moves_bishop(pos, moves, board, color_of_piece, color_of_opponent);
|
||||
break;
|
||||
case PieceType::B_KNIGHT:
|
||||
case PieceType::W_KNIGHT:
|
||||
_get_all_moves_knight(pos, moves, board, color_of_piece, color_of_opponent);
|
||||
break;
|
||||
case PieceType::B_KING:
|
||||
case PieceType::W_KING:
|
||||
_get_all_moves_king(pos, moves, board, color_of_piece, color_of_opponent);
|
||||
break;
|
||||
case PieceType::B_PAWN:
|
||||
case PieceType::W_PAWN:
|
||||
_get_all_moves_pawn(pos, moves, board, color_of_piece, color_of_opponent, en_passant);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (recursive){
|
||||
filter_checked_moves(pos, pt, board, moves);
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_set<int> get_all_moves(int pos, std::array<PieceType, 120> board, bool recursive, int en_passant){
|
||||
std::unordered_set<int> moves;
|
||||
get_all_moves(pos, &board, &moves, recursive, en_passant);
|
||||
return moves;
|
||||
}
|
||||
|
||||
std::array<PieceType, 120> dumb_move(int move, std::array<PieceType, 120> board){
|
||||
int from = get_from_sq(move);
|
||||
int to = get_to_sq(move);
|
||||
PieceType piece = board[from];
|
||||
board[to] = piece;
|
||||
board[from] = PieceType::NONE;
|
||||
return board;
|
||||
}
|
||||
|
||||
std::unordered_set<int> get_to_squares(std::unordered_set<int> moves){
|
||||
std::unordered_set<int> to_squares;
|
||||
for (int move : moves){
|
||||
to_squares.insert(get_to_sq(move));
|
||||
}
|
||||
return to_squares;
|
||||
}
|
||||
std::unordered_set<int> get_from_squared(std::unordered_set<int> moves){
|
||||
std::unordered_set<int> from_squares;
|
||||
return from_squares;
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
#include "bitwise_constants.h"
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <math.h>
|
||||
|
||||
// Convert pair of x y coordinates to Position enum member.
|
||||
// If pr contains values above 7, or below 0 it will fail with an InvalidArgument exception.
|
||||
Position pair_to_pos(std::pair<int, int> pr);
|
||||
Position pair_to_pos(int x, int y);
|
||||
|
||||
// Returns a list of positions with PieceType pt
|
||||
int get_pos_of(PieceType pt, std::array<PieceType, 120> const *board);
|
||||
std::unordered_set<int> get_poss_of(PieceType pt, std::array<PieceType, 120> const *board);
|
||||
|
||||
// Convert a Position number into a pair of x y coordiinates
|
||||
std::pair<int, int> pos_to_pair(Position pn);
|
||||
|
||||
// Check if int is a valid position in enum of Position
|
||||
// Allow ints, and pairs to be checked.
|
||||
bool is_valid_position(int pos);
|
||||
bool is_valid_position(std::pair<int, int> pos);
|
||||
bool is_valid_position(int x, int y);
|
||||
|
||||
// Checks if given piece matches a certain color.
|
||||
bool is_white(PieceType pt);
|
||||
bool is_black(PieceType pt);
|
||||
|
||||
Color get_color(int x, int y, std::array<PieceType, 120> const *board);
|
||||
Color get_color(Position pn, std::array<PieceType, 120> const *board);
|
||||
Color get_color(PieceType pt);
|
||||
// NO_COLOR returns NO_COLOR
|
||||
// WHITE returns BLACK
|
||||
// BLACK returns WHITE
|
||||
Color rev_color(Color c);
|
||||
|
||||
// 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::unordered_set<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::unordered_set<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::unordered_set<int> *moves);
|
||||
|
||||
// Get all moves for piece in Position pn.
|
||||
void get_all_moves(int pos, std::array<PieceType, 120> *pt,std::unordered_set<int> *moves, bool recursive=true, int en_passant=Position::NA);
|
||||
std::unordered_set<int> get_all_moves(int pos, std::array<PieceType, 120> board, bool recursive=true, int en_passant=Position::NA);
|
||||
|
||||
// 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);
|
||||
|
||||
// Allow the developer to get only certain pieces of the part of a move in a list.
|
||||
// This will return a vector (or unordered_set) of elements with only a certain part of the move revealed bit bit-switching.
|
||||
std::unordered_set<int> get_from_squares(std::unordered_set<int> moves);
|
||||
std::unordered_set<int> get_to_squares(std::unordered_set<int> moves);
|
||||
|
@ -1,88 +1,95 @@
|
||||
#ifndef CHESS_CONSTANTS_H
|
||||
#define CHESS_CONSTANTS_H
|
||||
#ifndef BT_CONST_H
|
||||
#define BT_CONST_H
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
enum Color {
|
||||
NO_COLOR,
|
||||
WHITE,
|
||||
BLACK
|
||||
};
|
||||
|
||||
// Access with PieceType::ANY_FOLLOWING_OPTION
|
||||
enum PieceType {
|
||||
INV=-1,
|
||||
NONE,
|
||||
W_PAWN,
|
||||
W_KNIGHT,
|
||||
W_BISHOP,
|
||||
W_ROOK,
|
||||
W_QUEEN,
|
||||
W_KING,
|
||||
B_PAWN,
|
||||
B_KNIGHT,
|
||||
B_BISHOP,
|
||||
B_ROOK,
|
||||
B_QUEEN,
|
||||
B_KING
|
||||
B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING,
|
||||
W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING
|
||||
};
|
||||
|
||||
namespace Pieces {
|
||||
const std::array<PieceType, 6> BLACK = {B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING};
|
||||
namespace Pieces{
|
||||
const std::array<PieceType, 6> WHITE = {W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING};
|
||||
const std::array<PieceType, 6> BLACK = {B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING};
|
||||
}
|
||||
|
||||
enum Color {
|
||||
NO_COLOR, BLACK, WHITE
|
||||
};
|
||||
|
||||
// Access with CHESS_CHARS[PieceType] to get the character for the piece.
|
||||
const std::array<char, 13> CHESS_CHARS = {
|
||||
' ',
|
||||
'p', 'n', 'b', 'r', 'q', 'k',
|
||||
'P', 'N', 'B', 'R', 'Q', 'K'
|
||||
};
|
||||
|
||||
// This allows reference to DEFAULT_BOARD (or more likely, a copy of it.
|
||||
enum Position{
|
||||
A8, B8, C8, D8, E8, F8, G8, H8, A7, B7, C7, D7, E7, F7, G7, H7, A6, B6, C6, D6, E6, F6, G6, H6, A5, B5, C5, D5, E5, F5, G5, H5, A4, B4, C4, D4, E4, F4, G4, H4, A3, B3, C3, D3, E3, F3, G3, H3, A2, B2, C2, D2, E2, F2, G2, H2, A1, B1, C1, D1, E1, F1, G1, H1, NA
|
||||
enum Position {
|
||||
NA=-1,
|
||||
A8=21, B8, C8, D8, E8, F8, G8, H8,
|
||||
A7=31, B7, C7, D7, E7, F7, G7, H7,
|
||||
A6=41, B6, C6, D6, E6, F6, G6, H6,
|
||||
A5=51, B5, C5, D5, E5, F5, G5, H5,
|
||||
A4=61, B4, C4, D4, E4, F4, G4, H4,
|
||||
A3=71, B3, C3, D3, E3, F3, G3, H3,
|
||||
A2=81, B2, C2, D2, E2, F2, G2, H2,
|
||||
A1=91, B1, C1, D1, E1, F1, G1, H1
|
||||
};
|
||||
|
||||
// This allows the printing of Position enum variables in the tests. It matches the variables to strings.
|
||||
// Variable names are discarded at compile time to optimize.
|
||||
// Access with POSITION_STRING[Position]
|
||||
const std::vector<std::string> POSITION_STRING = {
|
||||
"A8", "B8", "C8", "D8", "E8", "F8", "G8", "H8", "A7", "B7", "C7", "D7", "E7", "F7", "G7", "H7", "A6", "B6", "C6", "D6", "E6", "F6", "G6", "H6", "A5", "B5", "C5", "D5", "E5", "F5", "G5", "H5", "A4", "B4", "C4", "D4", "E4", "F4", "G4", "H4", "A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3", "A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2", "A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"
|
||||
"INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV",
|
||||
"INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV",
|
||||
"INV", "A8", "B8", "C8", "D8", "E8", "F8", "G8", "H8", "INV",
|
||||
"INV", "A7", "B7", "C7", "D7", "E7", "F7", "G7", "H7", "INV",
|
||||
"INV", "A6", "B6", "C6", "D6", "E6", "F6", "G6", "H6", "INV",
|
||||
"INV", "A5", "B5", "C5", "D5", "E5", "F5", "G5", "H5", "INV",
|
||||
"INV", "A4", "B4", "C4", "D4", "E4", "F4", "G4", "H4", "INV",
|
||||
"INV", "A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3", "INV",
|
||||
"INV", "A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2", "INV",
|
||||
"INV", "A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1", "INV",
|
||||
"INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV",
|
||||
"INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV", "INV"
|
||||
};
|
||||
|
||||
// Access with normal ways of accessing an array.
|
||||
// OR like so DEFAULT_BOARD[Position::G1] would equal PieceType::W_KNIGHT
|
||||
const std::array<PieceType, 64> DEFAULT_BOARD = {
|
||||
B_ROOK, B_KNIGHT, B_BISHOP, B_QUEEN, B_KING, B_BISHOP, B_KNIGHT, B_ROOK,
|
||||
B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN,
|
||||
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN,
|
||||
W_ROOK, W_KNIGHT, W_BISHOP, W_QUEEN, W_KING, W_BISHOP, W_KNIGHT, W_ROOK
|
||||
enum Rank{
|
||||
RANK1,
|
||||
RANK2,
|
||||
RANK3,
|
||||
RANK4,
|
||||
RANK5,
|
||||
RANK6,
|
||||
RANK7,
|
||||
RANK8
|
||||
};
|
||||
|
||||
enum File {
|
||||
FILE1,
|
||||
FILE2,
|
||||
FILE3,
|
||||
FILE4,
|
||||
FILE5,
|
||||
FILE6,
|
||||
FILE7,
|
||||
FILE8
|
||||
};
|
||||
|
||||
namespace Rank{
|
||||
const int A[8] = {A1, A2, A3, A4, A5, A6, A7, A8};
|
||||
const int B[8] = {B1, B2, B3, B4, B5, B6, B7, B8};
|
||||
const int C[8] = {C1, C2, C3, C4, C5, C6, C7, C8};
|
||||
const int D[8] = {D1, D2, D3, D4, D5, D6, D7, D8};
|
||||
const int E[8] = {E1, E2, E3, E4, E5, E6, E7, E8};
|
||||
const int F[8] = {F1, F2, F3, F4, F5, F6, F7, F8};
|
||||
const int G[8] = {G1, G2, G3, G4, G5, G6, G7, G8};
|
||||
const int H[8] = {H1, H2, H3, H4, H5, H6, H7, H8};
|
||||
}
|
||||
const std::array<PieceType, 120> DEFAULT_BOARD = {
|
||||
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
|
||||
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
|
||||
INV, B_ROOK, B_KNIGHT, B_BISHOP, B_QUEEN, B_KING, B_BISHOP, B_KNIGHT, B_ROOK, INV,
|
||||
INV, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, INV,
|
||||
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
|
||||
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
|
||||
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
|
||||
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
|
||||
INV, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, INV,
|
||||
INV, W_ROOK, W_KNIGHT, W_BISHOP, W_QUEEN, W_KING, W_BISHOP, W_KNIGHT, W_ROOK, INV,
|
||||
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
|
||||
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV
|
||||
};
|
||||
|
||||
namespace File{
|
||||
const int ONE[8] = {A1, B1, C1, D1, E1, F1, G1, H1};
|
||||
const int TWO[8] = {A2, B2, C2, D2, E2, F2, G2, H2};
|
||||
const int THREE[8] = {A3, B3, C3, D3, E3, F3, G3, H3};
|
||||
const int FOUR[8] = {A4, B4, C4, D4, E4, F4, G4, H4};
|
||||
const int FIVE[8] = {A5, B5, C5, D5, E5, F5, G5, H5};
|
||||
const int SIX[8] = {A6, B6, C6, D6, E6, F6, G6, H6};
|
||||
const int SEVEN[8] = {A7, B7, C7, D7, E7, F7, G7, H7};
|
||||
const int EIGHT[8] = {A8, B8, C8, D8, E8, F8, G8, H8};
|
||||
}
|
||||
const std::array<char, 13> CHESS_CHARS = {
|
||||
' ',
|
||||
'P', 'N', 'B', 'R', 'Q', 'K',
|
||||
'p', 'n', 'b', 'r', 'q', 'k'
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1,95 +0,0 @@
|
||||
#include "catch.hpp"
|
||||
#include <bitwise_constants.h>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
// For some retarted reason, I need to implement the printing of pairs, otherwise in the test outputs they show up as {?}
|
||||
// Also override default printing for Positions so it prints the value (e.g. 32), then, in parenthasies, the location (e.g. A4).
|
||||
// Example: A4(32)
|
||||
namespace Catch {
|
||||
template<>
|
||||
struct StringMaker<std::pair<int, int>> {
|
||||
static std::string convert(std::pair<int, int> const& p){
|
||||
std::stringstream ss;
|
||||
ss << "{ " << p.first << ", " << p.second << " }";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct StringMaker<Position> {
|
||||
static std::string convert(Position const& p){
|
||||
std::stringstream ss;
|
||||
ss << (int) p << "(" << POSITION_STRING[p] << ")";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
// This override makes sure that Color enum variables are printed properly
|
||||
template<>
|
||||
struct StringMaker<Color> {
|
||||
static std::string convert(Color const& c){
|
||||
std::stringstream ss;
|
||||
if (c==Color::WHITE) ss << "white";
|
||||
if (c==Color::BLACK) ss << "black";
|
||||
if (c==Color::NO_COLOR) ss << "N/A";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
// This prints all board comparisons in a readable fashion. Using the string name of the pieces, and newlines to seperate them.
|
||||
template<>
|
||||
struct StringMaker<std::array<PieceType, 120>> {
|
||||
static std::string convert(std::array<PieceType, 120> const& board){
|
||||
std::stringstream ss;
|
||||
ss << "{" << std::endl;
|
||||
for (int i = 2; i < 10; ++i){
|
||||
for (int j = 1; j < 9; ++j){
|
||||
int index = (i*10)+j;
|
||||
ss << CHESS_CHARS[board[index]] << ", ";
|
||||
}
|
||||
ss << std::endl;
|
||||
}
|
||||
ss << "}" << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
// This overrides vectors of positions. I want it to print a board with the positions that are selected so we can see a representation of what positions are selected.
|
||||
template<>
|
||||
struct StringMaker<std::unordered_set<Position>> {
|
||||
static std::string convert(std::unordered_set<Position> const& uo_poss){
|
||||
std::vector<Position> poss(uo_poss.begin(), uo_poss.end());
|
||||
std::stringstream ss;
|
||||
std::string files = " A B C D E F G H";
|
||||
ss << "{ {" << std::endl;
|
||||
ss << files << std::endl;
|
||||
for (int i = 0; i < 8; ++i){
|
||||
ss << 8-i << "|";
|
||||
for (int j = 0; j < 8; ++j){
|
||||
int index = (i*8)+j;
|
||||
// This part loops through all positions in the list and checks if it contains the current index.
|
||||
bool part_of_poss = false;
|
||||
for (Position p : poss){
|
||||
if (index == p) {
|
||||
part_of_poss = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Justin, this is how this oporator works.
|
||||
// (if) part_of_poss ?(then) do this :(else) do that.
|
||||
part_of_poss ? ss << "* " : ss << " ";
|
||||
}
|
||||
ss << "|" << 8-i;
|
||||
ss << std::endl;
|
||||
}
|
||||
ss << files << std::endl;
|
||||
ss << "}" << std::endl;
|
||||
ss << "," << std::endl;
|
||||
ss << "{ ";
|
||||
for (int pi = 0; pi < poss.size(); ++pi){
|
||||
pi == poss.size()-1 ? ss << poss[pi] << "(" << POSITION_STRING[poss[pi]] << ")" : ss << poss[pi] << "(" << POSITION_STRING[poss[pi]] << "), ";
|
||||
}
|
||||
ss << " } }" << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
#include "catch.hpp"
|
||||
#include "test_boards.h"
|
||||
#include "valid_moves.h"
|
||||
#include "custom_bitwise_printing.cpp"
|
||||
#include <sstream>
|
||||
#include <bitwise_functions.h>
|
||||
#include <functions.h>
|
||||
|
||||
|
||||
const std::array<PieceType, 120> DUMB_MOVE_1 = {
|
@ -1,157 +0,0 @@
|
||||
#include "catch.hpp"
|
||||
#include "test_boards.h"
|
||||
#include "valid_moves.h"
|
||||
#include "custom_printing.cpp"
|
||||
#include <sstream>
|
||||
#include <functions.h>
|
||||
|
||||
|
||||
const std::array<PieceType, 64> TEST_MOVES = {
|
||||
W_QUEEN, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
NONE, NONE, B_KNIGHT
|
||||
};
|
||||
|
||||
const std::array<PieceType, 64> DUMB_MOVE_1 = {
|
||||
B_ROOK, B_KNIGHT, B_BISHOP, B_QUEEN, B_KING, B_BISHOP, B_KNIGHT, B_ROOK,
|
||||
B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN,
|
||||
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
NONE, W_PAWN, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
|
||||
W_PAWN, NONE, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN,
|
||||
W_ROOK, W_KNIGHT, W_BISHOP, W_QUEEN, W_KING, W_BISHOP, W_KNIGHT, W_ROOK
|
||||
};
|
||||
|
||||
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_pos_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(2, 7, DUMB_MOVE_1) == Color::BLACK);
|
||||
CHECK(get_color(3, 3, DUMB_MOVE_1) == Color::NO_COLOR);
|
||||
CHECK(get_color(2, 1, 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);
|
||||
CHECK(get_color(PieceType::W_KING) == Color::WHITE);
|
||||
CHECK(get_color(PieceType::B_KING) == Color::BLACK);
|
||||
}
|
||||
|
||||
TEST_CASE("Test reversing color", "[rev_color]"){
|
||||
CHECK(rev_color(Color::NO_COLOR) == Color::NO_COLOR);
|
||||
CHECK(rev_color(Color::WHITE) == Color::BLACK);
|
||||
CHECK(rev_color(Color::BLACK) == Color::WHITE);
|
||||
}
|
||||
|
||||
TEST_CASE("Test that is_black, and is_white are working", "[is_black][is_white]"){
|
||||
CHECK(is_white(DUMB_MOVE_1[Position::A2]));
|
||||
CHECK(is_black(DUMB_MOVE_1[Position::F7]));
|
||||
CHECK_FALSE(is_white(DUMB_MOVE_1[Position::B2]));
|
||||
CHECK_FALSE(is_black(DUMB_MOVE_1[Position::B5]));
|
||||
|
||||
// Test that NONE squares return false
|
||||
CHECK_FALSE(is_white(DUMB_MOVE_1[Position::F4]));
|
||||
CHECK_FALSE(is_black(DUMB_MOVE_1[Position::F4]));
|
||||
}
|
||||
|
||||
TEST_CASE("Test that dumb moves can be made.", "[dumb_move]"){
|
||||
CHECK(dumb_move(Position::B2, Position::B5, DEFAULT_BOARD) == DUMB_MOVE_1);
|
||||
}
|
||||
|
||||
TEST_CASE("Test convert method to go from X and Y to board position", "[pair_to_pos]"){
|
||||
CHECK(pair_to_pos(std::make_pair(2, 3)) == Position::C4);
|
||||
CHECK(pair_to_pos(std::make_pair(7, 0)) == Position::H1);
|
||||
CHECK(pair_to_pos(std::make_pair(0, 0)) == Position::A1);
|
||||
CHECK(pair_to_pos(std::make_pair(7, 7)) == Position::H8);
|
||||
CHECK_THROWS(pair_to_pos(std::make_pair(8, 2)));
|
||||
CHECK_THROWS(pair_to_pos(std::make_pair(-1, 1)));
|
||||
|
||||
CHECK(pair_to_pos(2, 3) == Position::C4);
|
||||
CHECK(pair_to_pos(7, 0) == Position::H1);
|
||||
CHECK(pair_to_pos(0, 0) == Position::A1);
|
||||
CHECK(pair_to_pos(7, 7) == Position::H8);
|
||||
CHECK_THROWS(pair_to_pos(8, 2));
|
||||
CHECK_THROWS(pair_to_pos(-1, 1));
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Test convert method to go from a board position to an x and y", "[pos_to_pair]"){
|
||||
CHECK(pos_to_pair(Position::A3) == std::make_pair(0, 2));
|
||||
CHECK(pos_to_pair(Position::A4) == std::make_pair(0, 3));
|
||||
CHECK(pos_to_pair(Position::B2) == std::make_pair(1, 1));
|
||||
CHECK(pos_to_pair(Position::H8) == std::make_pair(7, 7));
|
||||
}
|
||||
|
||||
TEST_CASE("Test that invalid position ints return false", "[is_valid_position]"){
|
||||
CHECK(is_valid_position(0)); // 0=A8
|
||||
CHECK(is_valid_position(63)); // 63=H1
|
||||
CHECK_FALSE(is_valid_position(-1)); // -1 is out of bounds
|
||||
CHECK_FALSE(is_valid_position(64)); // 64 is out of bounds
|
||||
|
||||
CHECK(is_valid_position(std::make_pair(0, 0))); // 0-7,0-7 should be valid
|
||||
CHECK(is_valid_position(std::make_pair(7, 7)));
|
||||
CHECK_FALSE(is_valid_position(std::make_pair(-1, 5))); // should fail
|
||||
CHECK_FALSE(is_valid_position(std::make_pair(5, 8))); // should fail
|
||||
|
||||
CHECK(is_valid_position(0, 0)); // 0-7,0-7 should be valid
|
||||
CHECK(is_valid_position(7, 7));
|
||||
CHECK_FALSE(is_valid_position(-1, 5)); // should fail
|
||||
CHECK_FALSE(is_valid_position(5, 8)); // should fail
|
||||
}
|
||||
|
||||
TEST_CASE("Test what pieces may move where functon", "[get_possible_movers]"){
|
||||
std::unordered_set<Position> H1_possible_movers = {Position::H2, Position::G1};
|
||||
CHECK(get_possible_movers(BISHOP_BLOCKED1_KING_POS, BISHOP_BLOCKED1_BOARD) == BISHOP_BLOCKED1_CAN_MOVE_TO_B_KING);
|
||||
CHECK(get_possible_movers(Position::H3, DEFAULT_BOARD) == H1_possible_movers);
|
||||
}
|
||||
|
||||
TEST_CASE("Test where this piece may move to", "[get_possible_moves]"){
|
||||
CHECK(get_possible_moves(Position::G1, DEFAULT_BOARD) == DEFAULT_W_R_KNIGHT_POSSIBLE_MOVES);
|
||||
CHECK(get_possible_moves(Position::A7, DEFAULT_BOARD) == DEFAULT_B_A_PAWN_POSSIBLE_MOVES);
|
||||
CHECK(get_possible_moves(Position::A2, DEFAULT_BOARD) == DEFAULT_W_A_PAWN_POSSIBLE_MOVES);
|
||||
CHECK(get_possible_moves(KNIGHT_BLOCKED1_POS, KNIGHT_BLOCKED1_BOARD) == KNIGHT_BLOCKED1_MOVES);
|
||||
CHECK(get_possible_moves(BISHOP_BLOCKED1_POS, BISHOP_BLOCKED1_BOARD) == BISHOP_BLOCKED1_MOVES);
|
||||
CHECK(get_possible_moves(ROOK_BLOCKED1_POS, ROOK_BLOCKED1_BOARD) == ROOK_BLOCKED1_MOVES);
|
||||
}
|
||||
|
||||
TEST_CASE("Test all possible and impossible moves for black pieces", "[get_all_moves][black]"){
|
||||
CHECK(get_all_moves(B_KING_POS, B_KING_BOARD) == B_KING_ALL_MOVES);
|
||||
CHECK(get_all_moves(B_QUEEN_POS, B_QUEEN_BOARD) == B_QUEEN_ALL_MOVES);
|
||||
CHECK(get_all_moves(B_ROOK_POS, B_ROOK_BOARD) == B_ROOK_ALL_MOVES);
|
||||
CHECK(get_all_moves(B_BISHOP_POS, B_BISHOP_BOARD) == B_BISHOP_ALL_MOVES);
|
||||
CHECK(get_all_moves(B_KNIGHT_POS, B_KNIGHT_BOARD) == B_KNIGHT_ALL_MOVES);
|
||||
CHECK(get_all_moves(B_PAWN_POS, B_PAWN_BOARD) == B_PAWN_ALL_MOVES);
|
||||
}
|
||||
TEST_CASE("Test all possible and impossible moves for whtie pieces", "[get_all_moves][white]"){
|
||||
CHECK(get_all_moves(W_KING_POS, W_KING_BOARD) == W_KING_ALL_MOVES);
|
||||
CHECK(get_all_moves(W_QUEEN_POS, W_QUEEN_BOARD) == W_QUEEN_ALL_MOVES);
|
||||
CHECK(get_all_moves(W_ROOK_POS, W_ROOK_BOARD) == W_ROOK_ALL_MOVES);
|
||||
CHECK(get_all_moves(W_BISHOP_POS, W_BISHOP_BOARD) == W_BISHOP_ALL_MOVES);
|
||||
CHECK(get_all_moves(W_KNIGHT_POS, W_KNIGHT_BOARD) == W_KNIGHT_ALL_MOVES);
|
||||
CHECK(get_all_moves(W_PAWN_POS, W_PAWN_BOARD) == W_PAWN_ALL_MOVES);
|
||||
}
|
||||
|
||||
TEST_CASE("Test all moves for white in edge cases.", "[get_all_moves][white]"){
|
||||
CHECK(get_all_moves(W_KNIGHT_SIDE1_POS, W_KNIGHT_SIDE1_BOARD) == W_KNIGHT_SIDE1_ALL_MOVES);
|
||||
CHECK(get_all_moves(W_KING_SIDE1_POS, W_KING_SIDE1_BOARD) == W_KING_SIDE1_ALL_MOVES);
|
||||
CHECK(get_all_moves(W_PAWN_SIDE1_POS, W_PAWN_SIDE1_BOARD) == W_PAWN_SIDE1_ALL_MOVES);
|
||||
}
|
||||
TEST_CASE("Test all moves for black in edge cases.", "[get_all_moves][black]"){
|
||||
CHECK(get_all_moves(B_KNIGHT_SIDE1_POS, B_KNIGHT_SIDE1_BOARD) == B_KNIGHT_SIDE1_ALL_MOVES);
|
||||
CHECK(get_all_moves(B_KING_SIDE1_POS, B_KING_SIDE1_BOARD) == B_KING_SIDE1_ALL_MOVES);
|
||||
CHECK(get_all_moves(B_PAWN_SIDE1_POS, B_PAWN_SIDE1_BOARD) == B_PAWN_SIDE1_ALL_MOVES);
|
||||
}
|
||||
|
||||
TEST_CASE("Test that moves that put king in check are not returned", "[get_all_moves]"){
|
||||
CHECK(get_all_moves(ROOK_CHECK_TEST_POS, ROOK_CHECK_TEST_BOARD) == ROOK_CHECK_TEST_MOVES);
|
||||
CHECK(get_all_moves(PAWN_CHECK_TEST_POS, PAWN_CHECK_TEST_BOARD) == PAWN_CHECK_TEST_MOVES);
|
||||
CHECK(get_all_moves(PAWN_DIAG_TEST1_POS, PAWN_DIAG_TEST1_BOARD) == PAWN_DIAG_TEST1_MOVES);
|
||||
}
|
||||
|
||||
TEST_CASE("Tests for en pessant squares.", "[get_all_moves]"){
|
||||
CHECK(get_all_moves(EN_PASSANT_TEST_POS, EN_PASSANT_TEST_BOARD, false, EN_PASSANT_SQUARE) == EN_PASSANT_TEST_MOVES);
|
||||
CHECK(get_all_moves(NO_EN_PASSANT_TEST_POS, NO_EN_PASSANT_TEST_BOARD) == NO_EN_PASSANT_TEST_MOVES);
|
||||
}
|
Loading…
Reference in new issue