Half-way done switching to bitwise moves.

master
Tait Hoyem 5 years ago
parent 0422768eb0
commit 20c87a3988

@ -0,0 +1,185 @@
#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 (is_valid_position(pos)){
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, not_blocked);
}
/*
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, not_blocked);
}
/*
_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,54 +1,18 @@
#include "bitwise.h"
// Get first 6 bits of int
int get_from_sq(int mv){
return (mv & 0x3f);
}
// Get bits 7-12 of int
int get_to_sq(int mv){
return ((mv >> 6) & 0x3f);
}
// Get bits 13-16 of int
int get_captured_pc(int mv){
return ((mv >> 12) & 0xf);
}
// Get bits 17-20 of int
int get_promoted_to_pc(int mv){
return ((mv >> 16) & 0xf);
}
// Get 21st bit of int
int get_en_pass_flag(int mv){
return ((mv >> 20) & 0x1);
}
// Get 22nd bit of int
int get_pawn_st_flag(int mv){
return ((mv >> 21) & 0x1);
}
// Get 23rd bit of int
int get_castle_flag(int mv){
return ((mv >> 22) & 0x1);
}
// 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.
int get_rank(int position){
return (position >> 3);
}
// Get first 3 bits of number
int get_file(int position){
return (position & 7);
}
// 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.
bool is_valid_position(int position){
return !(position & 0x40);
}

@ -34,17 +34,39 @@
*/
// Redefine as functions for fun :shrug:
int get_from_sq(int mv);
int get_to_sq(int mv);
int get_captured_pc(int mv);
int get_promoted_to_pc(int mv);
int get_en_pass_flag(int mv);
int get_pawn_st_flag(int mv);
int get_castle_flag(int mv);
inline int get_from_sq(int mv){
return (mv & 0x3f);
}
inline int get_to_sq(int mv){
return ((mv >> 6) & 0x3f);
}
inline int get_captured_pc(int mv){
return ((mv >> 12) & 0xf);
}
inline int get_promoted_to_pc(int mv){
return ((mv >> 16) & 0xf);
}
inline int get_en_pass_flag(int mv){
return ((mv >> 20) & 0x1);
}
inline int get_pawn_st_flag(int mv){
return ((mv >> 21) & 0x1);
}
inline int get_castle_flag(int mv){
return ((mv >> 22) & 0x1);
}
int get_rank(int position);
int get_file(int position);
bool is_valid_position(int position);
inline int get_rank(int position){
return (position >> 3);
}
inline int get_file(int position){
return (position & 7);
}
inline bool is_valid_position(int position){
return !(position & 0x40);
}
inline bool is_invalid_position(int position){
return (position & 0x40);
}
#endif

@ -0,0 +1,16 @@
#include "bitwise_constants.h"
#include <array>
#include <iostream>
int main(){
for (int y=0;y<12;y++){
for (int x=0;x<10;x++){
int cord = (y*10) + x;
int val = DEFAULT_BOARD[cord];
val==-1?std::cout << '!':std::cout << CHESS_CHARS[val];
std::cout << std::hex << y << "," << x << " ";
}
std::cout << std::endl;
}
return 0;
}

@ -0,0 +1,76 @@
#ifndef BITWISE_CONSTANTS_H
#define BITWISE_CONSTANTS_H
#include <array>
#include <iostream>
enum Color {
NO_COLOR,
WHITE,
BLACK
};
enum PieceType {
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
};
enum Rank{
RANK1,
RANK2,
RANK3,
RANK4,
RANK5,
RANK6,
RANK7,
RANK8
};
enum File {
FILE1,
FILE2,
FILE3,
FILE4,
FILE5,
FILE6,
FILE7,
FILE8
};
std::array<int, 120> DEFAULT_BOARD = {
NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
NA, B_ROOK, B_KNIGHT, B_BISHOP, B_QUEEN, B_KING, B_BISHOP, B_KNIGHT, B_ROOK, NA,
NA, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, NA,
NA, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NA,
NA, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NA,
NA, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NA,
NA, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NA,
NA, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, NA,
NA, W_ROOK, W_KNIGHT, W_BISHOP, W_QUEEN, W_KING, W_BISHOP, W_KNIGHT, W_ROOK, NA,
NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
};
char CHESS_CHARS[13] = {
' ',
'P', 'N', 'B', 'R', 'Q', 'K',
'p', 'n', 'b', 'r', 'q', 'k'
};
#endif

@ -0,0 +1,207 @@
#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> board){
return get_color(board[pair_to_pos(x, y)]);
}
Color get_color(Position pn, std::array<PieceType, 120> 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> *board){
for (int pn = Position::A8; pn!=Position::H1; pn++){
if ((*board)[pn] == pt){
return pn;
}
}
return Position::NA;
}
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(Position pn, 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 = pn + (*p_pn >> 6);
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(Position pn, std::array<PieceType, 120>* board, std::unordered_set<int>* moves, bool recursive, int en_passant){
PieceType pt = (*board)[pn];
int pos = pn;
int x = pos_to_pair(pn).first;
int y = pos_to_pair(pn).second;
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(pn, pt, board, moves);
}
}
std::array<PieceType, 120> dumb_move(Position from, Position to, std::array<PieceType, 120> board){
PieceType piece = board[from];
board[to] = piece;
board[from] = PieceType::NONE;
return board;
}

@ -0,0 +1,50 @@
#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
std::vector<Position> get_pos_of(PieceType pt, std::array<PieceType, 120>);
// 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> *board);
Color get_color(Position pn, std::array<PieceType, 120> *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);
// Get all moves for piece in Position pn.
void get_all_moves(Position pn, std::array<PieceType, 120> *pt,std::unordered_set<int> *moves, 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);

@ -1,5 +1,6 @@
defualt: all.out
bitwise: bitwise.out
bitwise_functions: bitwise_main.out
catch_main.o:
g++ -w -c -o catch_main.o catch_main.cpp
@ -10,6 +11,9 @@ custom_printing.o:
bitwise.out: catch_main.o
g++ -I../src/ -o bitwise.out ../src/bitwise.cpp catch_main.o bitwise_tests.cpp
bitwise_main.out: catch_main.o
g++ -I../src/ -o bitwise_functions.out ../src/bitwise.cpp catch_main.o ../src/bitwise_functions.cpp bitwise_main.cpp
# TODO: Allw all.out to contain bitwise tests
all.out: catch_main.o custom_printing.o
g++ -std=c++11 -ggdb -w -I../src/ -o all.out ../src/functions.cpp catch_main.o custom_printing.o tests_main.cpp

@ -0,0 +1,157 @@
#include "catch.hpp"
#include "test_boards.h"
#include "valid_moves.h"
#include "custom_printing.cpp"
#include <sstream>
#include <bitwise_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…
Cancel
Save