Merge branch 'develop'

master
Tait Hoyem 4 years ago
commit fde67f42cd

@ -1,15 +1,19 @@
#CC=g++-4.2
#
#a.out: main.o SerialComm.o
# g++ main.o SerialComm.o -lboost_system -lboost_filesystem -lboost_serialization -lpthread -std=c++11
#chess.out: functions.o
# g++ chess.o functions.o -std=c++11
#
#main.o: main.cpp
# g++ -c -std=c++11 main.cpp
#chess.o: chess.cpp
# g++ -c -std=c++11 chess.cpp
#
#functions.o: functions.cpp functions.h
# g++ -c -std=c++11 functions.cpp
#
#SerialComm.o: SerialComm.cpp SerialComm.hpp
# g++ -c -std=c++11 SerialComm.cpp
default: build
release: optimized
optimized:
g++ -std=c++11 -O2 -Wall -o chess.out functions.cpp chess.cpp
build:
g++ -o chess.out chess.cpp -std=c++11
g++ -Wall -o chess_unoptimized.out functions.cpp chess.cpp -std=c++11

@ -0,0 +1,172 @@
#include "constants.h"
#include <vector>
#include <array>
#include <iostream>
const std::vector<int> ROOK_PIECE_OFFSETS = {-1, -10, 1, 10};
const std::vector<int> BISHOP_PIECE_OFFSETS = {-11, -9, 9, 11};
const std::vector<int> KNIGHT_PIECE_OFFSETS = {-12, -21, -19, -8, 8, 12, 19, 21};
const std::vector<int> KING_PIECE_OFFSETS = {-11, -10, -9, 9, 10, 11};
inline Position _pair_to_pos_unsafe(int x, int y){
return static_cast<Position>(std::abs(y-7)*8 + x);
}
// This function returns true if the color of the piece on tile (x,y) is the Color c
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){
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, 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;
} 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.push_back(make_move(from, pos, board[pos]));
*is_not_blocked = false;
} else {
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, 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;
} 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.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));
}
}
}
}
// 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, 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]));
}
}
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));
} 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));
}
}
// 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, 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);
} else {
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));
}
}
}
// 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, 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){
*is_not_blocked = false;
} else if (double_move){
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]));
}
}
}
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);
}
bool* left_castle = new bool(true);
bool* right_castle = new bool(true);
if (pc == Color::WHITE){
_king_add_if_not_blocked(pos+1, pos, pns, board, pc, rc, right_castle, 0);
_king_add_if_not_blocked(pos-1, pos, pns, board, pc, rc, left_castle, 0);
// THe right castle doesn't need to know if pos-/+ something is blank, because there is only
// ... 2 blank squares between the king and the rook.
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){
_king_add_if_not_blocked(pos-2, pos, pns, board, pc, rc, left_castle, 1);
}
} else {
_king_add_if_not_blocked(pos+1, pos, pns, board, pc, rc, right_castle, 0);
_king_add_if_not_blocked(pos-1, pos, pns, board, pc, rc, left_castle, 0);
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){
_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, 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;
int offset1 = pc==Color::WHITE?-10:10;
int default_pawn_rank = pc==Color::WHITE?Rank::RANK2:Rank::RANK7;
int promotion_rank = pc==Color::WHITE?Rank::RANK7:Rank::RANK2;
int is_promoting_if_forward = get_rank(pos) == promotion_rank?1:0;
bool *free_to_double_move = new bool(true);
_pawn_add_if_not_blocked(pos+offset1, pos, pns, board, pc, rc, free_to_double_move, false, is_promoting_if_forward);
if (get_rank(pos) == default_pawn_rank){ // If on second/seventh rank
_pawn_add_if_not_blocked(pos+offset2, pos, pns, board, pc, rc, free_to_double_move, true, is_promoting_if_forward);
}
// 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, pos, pns, board, pc, rc, en_passant, is_promoting_if_forward);
_pawn_diag_add_if_not_blocked(pos+offset1-1, pos, pns, board, pc, rc, en_passant, is_promoting_if_forward);
}

@ -0,0 +1,127 @@
#ifndef BITWISE_H
#define BITWISE_H
#include "constants.h"
#include <vector>
// Using macros for ease of use, can also use functons, but I don't see the point.
/*
* From (Position): 7 bits (2^7 == 128) possibilities
* To (Position): same as above
* Captured piece, if any: 4 bits (16) possibilities
* Promoted to, if any: 4 bits (16) possibilities
* en passant flag: 1 bit
* pawn starting move flag: 1 bit
* castle move flag: 1 bit
*
* 0000 0000 0000 0000 0000 0111 1111 -> From square position (& 0x7F)
* 0000 0000 0000 0011 1111 1000 0000 -> To square position (>> 7 & 0x7F)
* 0000 0000 0011 1100 0000 0000 0000 -> captured piece, if any (>> 14 & 0xF)
* 0000 0011 1100 0000 0000 0000 0000 -> if prmoted, what to? (>> 18 & 0xF)
* 0000 0100 0000 0000 0000 0000 0000 -> en passant (& 0x400000)
* 0000 1000 0000 0000 0000 0000 0000 -> pawn starting move (& 0x800000)
* 0001 0000 0000 0000 0000 0000 0000 -> castle move (& 0x1000000)
* 0010 0000 0000 0000 0000 0000 0000 -> check flag (& 0x2000000)
* */
// No offset becuase at beginning of int
#define FROM_MASK 0x7F
#define TO_MASK 0x7F
#define TO_SHIFT 7
#define CAPTURED_MASK 0xF
#define CAPTURED_SHIFT 14
#define PROMOTED_MASK 0xF
#define PROMOTED_SHIFT 18
#define EN_PASS_MASK 0x1
#define EN_PASS_SHIFT 22
#define PAWN_ST_MASK 0x1
#define PAWN_ST_SHIFT 23
#define CASTLE_MASK 0x1
#define CASTLE_SHIFT 24
inline int get_from_sq(int mv){
return (mv & FROM_MASK);
}
inline int get_to_sq(int mv){
return ((mv >> TO_SHIFT) & TO_MASK);
}
inline int get_captured_pc(int mv){
return ((mv >> CAPTURED_SHIFT) & CAPTURED_MASK);
}
inline int get_promoted_to_pc(int mv){
return ((mv >> PROMOTED_SHIFT) & PROMOTED_MASK);
}
inline int get_en_pass_flag(int mv){
return ((mv >> EN_PASS_SHIFT) & EN_PASS_MASK);
}
inline int get_pawn_st_flag(int mv){
return ((mv >> PAWN_ST_SHIFT) & PAWN_ST_MASK);
}
inline int get_castle_flag(int mv){
return ((mv >> CASTLE_SHIFT) & CASTLE_MASK);
}
inline int get_check_flag(int mv){
return ((mv >> 25) & 0x1);
}
inline bool is_valid_position(int position){
return DEFAULT_BOARD[position] != PieceType::INV;
}
// bitwise OR (|) with any int to "add" them together
inline int set_from_sq(int sq){
return sq;
}
inline int set_to_sq(int sq){
return (sq << 7);
}
inline int set_captured_pc(int pc){
return (pc << 14);
}
inline int set_promoted_pc(int pc){
return (pc << 16);
}
inline int set_en_passant_flag(){
return (1 << 20);
}
inline int set_pawn_start_flag(){
return (1 << 21);
}
inline int set_castle_flag(){
return (1 << 22);
}
inline int make_move(int from){
return from;
}
inline int make_move(int from, int to){
return from | (to << 7);
}
inline int make_move(int from, int to, PieceType captured){
return from | (to << 7) | ((int) captured << 14);
}
inline int make_move(int from, int to, PieceType captured, PieceType promotion){
return from | (to << 7) | ((int) captured << 14) | ((int) promotion << 18);
}
inline int make_move(int from, int to, PieceType captured, PieceType promotion, int en_passant){
return from | (to << 7) | ((int) captured << 14) | ((int) promotion << 18) | (en_passant << 22);
}
inline int make_move(int from, int to, PieceType captured, PieceType promotion, int en_passant, int pawn_start){
return from | (to << 7) | ((int) captured << 14) | ((int) promotion << 18) | (en_passant << 22) | (pawn_start << 23);
}
inline int make_move(int from, int to, PieceType captured, PieceType promotion, int en_passant, int pawn_start, int castle_move){
return from | (to << 7) | ((int) captured << 14) | ((int) promotion << 18) | (en_passant << 22) | (pawn_start << 23) | (castle_move << 24);
}
inline int make_move(int from, int to, PieceType captured, PieceType promotion, int en_passant, int pawn_start, int castle_move, int check_flag){
return from | (to << 7) | ((int) captured << 14) | ((int) promotion << 18) | (en_passant << 22) | (pawn_start << 23) | (castle_move << 24) | (check_flag << 25);
}
#endif

@ -1,18 +1,219 @@
#include <iostream>
#include <stdio.h>
#include <string>
#include "bitwise.h"
#include "constants.h"
#include "functions.h"
#include "color.hpp"
// See constants.h for CHESS_CHARS, and DEFAULT_BOARD
using namespace std;
int main(){
for (int i = 0; i < 8; ++i){
for (int j = 0; j < 8; ++j){
int ix = (i*8) + j;
cout << CHESS_CHARS[DEFAULT_BOARD[ix]];
void print_board(const array<PieceType, 120>& board, vector<int> &highlighted_moves){
for (int i = 2; i < 10; ++i){
cout << 10-i << " |";
for (int j = 1; j < 9; ++j){
int ix = (i*10) + j;
int piece = board[ix];
string piece_string = FANCY_CHESS_CHARS[piece];
string foreground_color = is_white(piece)?"White":"Black";
string background_color = "";
string modifier = "";
for (int move : highlighted_moves){
if (get_to_sq(move) == ix){
if (get_check_flag(move) == 1){
background_color = "Light Red";
} else if (get_captured_pc(move) != 0){
background_color = "Green";
// If a checkmate occors on this move
// Doesn't appear to work in practoce.
} else if (to_notation(move, board).find("#") != string::npos){
background_color = "White";
modifier = "Blink";
} else {
background_color = "Yellow";
}
}
}
cout << color::rize(" ", foreground_color, background_color, modifier);
cout << color::rize(piece_string, foreground_color, background_color, modifier);
cout << color::rize(" ", foreground_color, background_color, modifier);
}
cout << endl;
}
cout << "--------------------------" << endl;
cout << " A B C D E F G H" << endl;
}
// TODO: allow algebraic notation.
int main(){
cout << "Hit h for help!" << endl;
Color whos_turn = Color::WHITE;
array<PieceType, 120> my_board;
copy(DEFAULT_BOARD.begin(), DEFAULT_BOARD.end(),
my_board.begin());
vector<int> all_moves = {};
vector<string> all_moves_notation = {};
int en_passant_square = 0;
int castle_perms = 0xF;
bool reset_en_passant = false;
vector<int> highlighted_moves = {};
while (true){
all_moves = {};
all_moves_notation = {};
array<PieceType, 6> my_pieces = whos_turn==Color::WHITE?Pieces::WHITE:Pieces::BLACK;
// Gets all moves for color who's turn it is.
get_all_moves_for_pieces(my_pieces, my_board, all_moves, en_passant_square, castle_perms);
print_board(my_board, highlighted_moves);
// If there are no moves. The game is over.
// If the king is ALSO in check, then the other team won!
if (all_moves.empty()){
if (king_checked(my_board, whos_turn)){
string winning_team = rev_color(whos_turn)==Color::WHITE?"White":"Black";
cout << "GG! " << winning_team << " won!" << endl;
break;
} else {
cout << "Stalemate, too bad!" << endl;
break;
}
}
// Gets a string from cin called input
string input;
getline(cin, input);
// Gets all moves and stores them in a notation list
// TODO make into own function
bool move_exec = false;
int move_to_exec = 0;
for (int move : all_moves){
string move_notation = to_notation(move, my_board);
all_moves_notation.push_back(move_notation);
if (move_notation == input){
move_exec = true;
move_to_exec = move;
break;
}
}
// Quits
if (input == "q"){
break;
} else if (input == "l"){
for (string notation : all_moves_notation){
cout << notation << " ";
}
cout << endl;
continue;
} else if (input == "c"){
highlighted_moves = {};
} else if (input == "h"){
cout << "Commands:" <<endl;
cout << " h for this help menu" << endl;
cout << " l to list all your moves" << endl;
cout << " l <position> to list all moves for a specific position." << endl;
cout << " these will be highlighted on the board with various colors" << endl;
cout << " Red: Checking move"<< endl;
cout << " Blue: capturing move" << endl;
cout << " Yellow: all other moves" << endl;
cout << " c to clear the highlights" << endl;
}
// If the input did not match any legal move.
if (!move_exec){
int l_pos = input.find("l");
// If input starts with "l".
// It cannot equal only l because that case is taken care of above.
// And it continues to the next loop.
if (l_pos == 0){
string possible_position = input.substr(2, 2);
bool asking_for_specific_moves = false;
for (string pos : POSITION_STRING){
if(pos == possible_position){
asking_for_specific_moves = true;
}
}
// If input matches a position.
if (asking_for_specific_moves){
highlighted_moves = {};
for (int move : all_moves){
if (POSITION_STRING[get_from_sq(move)] == possible_position){
highlighted_moves.push_back(move);
cout << to_notation(move, my_board) << " ";
}
}
cout << endl;
} else {
cout << "Invalid move!" << std::endl;
cout << "These are the only valid moves: ";
for (string notation : all_moves_notation){
cout << notation << " ";
}
cout << endl;
continue;
}
}
// If the input did match a legal move.
} else {
int moving_from_pos = get_from_sq(move_to_exec);
int moving_piece = my_board[moving_from_pos];
// Depending on move, change castle perms, or en_passant square
if (get_pawn_st_flag(move_to_exec) == 1){
int en_pass_offset = whos_turn==Color::WHITE?10:-10;
en_passant_square = get_to_sq(move_to_exec)+en_pass_offset;
reset_en_passant = false;
}
if (moving_piece == W_ROOK){
if (moving_from_pos == Position::A1 &&
((castle_perms & CastlePerms::WQS) == CastlePerms::WQS)){
castle_perms -= CastlePerms::WQS;
} else if (moving_from_pos == Position::H1 &&
((castle_perms & CastlePerms::WKS) == CastlePerms::WKS)){
castle_perms -= CastlePerms::WKS;
}
} else if (moving_piece == B_ROOK){
if (moving_from_pos == Position::H8 &&
((castle_perms & CastlePerms::BKS) == CastlePerms::BKS)){
castle_perms -= CastlePerms::BKS;
} else if (moving_from_pos == Position::A8 &&
((castle_perms & CastlePerms::BQS) == CastlePerms::BQS)){
castle_perms -= CastlePerms::BQS;
}
}
// Removes castle perms after castling
if (is_white(moving_piece) &&
get_castle_flag(move_to_exec)){
castle_perms -= CastlePerms::WQS;
castle_perms -= CastlePerms::WKS;
} else if (is_black(moving_piece) &&
get_castle_flag(move_to_exec)) {
castle_perms -= CastlePerms::BQS;
castle_perms -= CastlePerms::BKS;
}
// This will keep the en passant sqaure for one whole turn.
if (reset_en_passant){
en_passant_square = 0;
reset_en_passant = false;
}
if (en_passant_square != 0){
reset_en_passant = true;
}
// This reverses the whos_turn variable.
// and runs the move on the my_board variable.
my_board = dumb_move(move_to_exec, my_board);
whos_turn = rev_color(whos_turn);
highlighted_moves = {};
}
}
return 0;
}

@ -0,0 +1,146 @@
#if 0
Copyright <2018> <Feng Wang>
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#ifndef BKSDMLDVRLVOKOCTERXUEIKDNCRAQXFWSMBUNVVYFAPNJYHYEBBVBMCDQGBQWGARFUYWEDMFN
#define BKSDMLDVRLVOKOCTERXUEIKDNCRAQXFWSMBUNVVYFAPNJYHYEBBVBMCDQGBQWGARFUYWEDMFN
#ifdef __clang__
#define SUPPRESS_WARNINGS \
_Pragma("clang diagnostic push ") \
_Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
_Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
_Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \
_Pragma("clang diagnostic ignored \"-Wc++98-c++11-c++14-compat\"") \
_Pragma("clang diagnostic ignored \"-Wmissing-variable-declarations\"" )
#define RESTORE_WARNINGS \
_Pragma( "clang diagnostic pop" )
#else
#define SUPPRESS_WARNINGS
#define RESTORE_WARNINGS
#endif
#include <map>
#include <string>
SUPPRESS_WARNINGS
namespace color
{
const static std::map<std::string, std::string> color_foreground =
{
{ "Default", "39" },
{ "Black", "30" },
{ "Red", "31" },
{ "Green", "32" },
{ "Yellow", "33" },
{ "Blue", "34" },
{ "Magenta", "35" },
{ "Cyan", "36" },
{ "Light Gray", "37" },
{ "Dark Gray", "90" },
{ "Light Red", "91" },
{ "Light Green", "92" },
{ "Light Yellow", "93" },
{ "Light Blue", "94" },
{ "Light Magenta", "95" },
{ "Light Cyan", "96" },
{ "White", "97" }
};
const static std::map<std::string, std::string> color_background =
{
{ "Default", "49" },
{ "Black", "40" },
{ "Red", "41" },
{ "Green", "42" },
{ "Yellow", "43" },
{ "Blue", "44" },
{ "Megenta", "45" },
{ "Cyan", "46" },
{ "Light Gray", "47" },
{ "Dark Gray", "100" },
{ "Light Red", "101" },
{ "Light Green", "102" },
{ "Light Yellow", "103" },
{ "Light Blue", "104" },
{ "Light Magenta", "105" },
{ "Light Cyan", "106" },
{ "White", "107" }
};
const static std::map<std::string, std::string> formatting_set =
{
{ "Default", "0" },
{ "Bold", "1" },
{ "Dim", "2" },
{ "Underlined", "4" },
{ "Blink", "5" },
{ "Reverse", "7" },
{ "Hidden", "8" }
};
const static std::map<std::string, std::string> formatting_reset =
{
{ "All", "0" },
{ "Bold", "21" },
{ "Dim", "22" },
{ "Underlined", "24" },
{ "Blink", "25" },
{ "Reverse", "27" },
{ "Hidden", "28" }
};
// Usage:
//
// auto new_message = color::rize( "I am a banana!", "Yellow", "Green" );
// std::cout << new_message << std::endl;
//
inline std::string rize( std::string const& source,
std::string foreground_color = "Default",
std::string background_color = "Default",
std::string set_formatting = "Default",
std::string reset_formatting = "All"
)
{
std::string const control = "\033";
if ( color_foreground.find( foreground_color ) == color_foreground.end() )
foreground_color = "Default";
if ( color_background.find( background_color ) == color_background.end() )
background_color = "Default";
if ( formatting_set.find( set_formatting ) == formatting_set.end() )
set_formatting = "Default";
if ( formatting_reset.find( reset_formatting ) == formatting_reset.end() )
reset_formatting = "All";
std::string ans = control + std::string{"["} +
formatting_set.at( set_formatting ) + std::string{";"} +
color_background.at( background_color ) + std::string{";"} +
color_foreground.at( foreground_color ) + std::string{"m"} +
source +
control + std::string{"["} +
formatting_reset.at( reset_formatting ) + std::string{"m"};
return ans;
}
}//namespace color
RESTORE_WARNINGS
#endif//BKSDMLDVRLVOKOCTERXUEIKDNCRAQXFWSMBUNVVYFAPNJYHYEBBVBMCDQGBQWGARFUYWEDMFN

@ -1,79 +1,129 @@
#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,
BLACK,
WHITE
};
enum CastlePerms {
BQS=0b1,
BKS=0b10,
WQS=0b100,
WKS=0b1000
};
// 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,
};
// 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'
};
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};
}
// 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
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"
const std::array<std::string, 120> 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"
};
// 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{
RANK8,
RANK7,
RANK6,
RANK5,
RANK4,
RANK3,
RANK2,
RANK1
};
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
};
const std::array<Color, 120> BOARD_COLORS = {
NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,
NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,
NO_COLOR, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, NO_COLOR,
NO_COLOR, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, NO_COLOR,
NO_COLOR, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, NO_COLOR,
NO_COLOR, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, NO_COLOR,
NO_COLOR, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, NO_COLOR,
NO_COLOR, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, NO_COLOR,
NO_COLOR, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, NO_COLOR,
NO_COLOR, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, NO_COLOR,
NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,
NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR,NO_COLOR
};
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, 16> CHESS_CHARS = {
' ',
'P', 'N', 'B', 'R', 'Q', 'K',
'p', 'n', 'b', 'r', 'q', 'k',
};
// This returns the same letter weather the team is black or white
const std::array<std::string, 16> CHESS_CHARS_INSENSITIVE = {
" ",
"P", "N", "B", "R", "Q", "K",
"P", "N", "B", "R", "Q", "K",
};
const std::array<std::string, 16> FANCY_CHESS_CHARS = {
" ",
"", "", "", "", "", "",
"", "", "", "", "", "",
};
#endif

@ -1,121 +1,562 @@
#include "bitwise.h"
#include "functions.h"
#include "all_moves_functions.cpp"
#include <algorithm>
#include <cstring>
#include <string>
#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.
/*
*
* These functions use an int to pass a lot of information.
* The notation is like this:
* 0000 0000 0000 0000 0111 1111 -> position of piece
* 0000 0000 0000 0111 1000 0000 -> piece type
* 0000 0000 0111 1000 0000 0000 -> piece of opposite type (eg. opposite of W_KING, is B_KING; B_ROOK, W_ROOK etc...)
* 0000 0000 1000 0000 0000 0000 -> team of the piece (1=white, 0=black)
* 0111 1111 0000 0000 0000 0000 -> new position (if applicable)
*
**/
std::pair<int, int> pos_to_pair(Position pn){
int x,y = 0;
for (x = pn; x >= 8; x = x-8){
++y;
/*
* These functions also use an int for king info. This is so:
* a) I don't have to recompute the info each time I nedd it in a functoin.
* b) So that I don't have the overhead of a struct. (I know, "micro optimizations are the root of all evil", I can't help myself)
* The notation is as follows:
* 0000 0000 0000 0000 0111 1111 -> position of piece
* 0000 0000 0000 0111 1000 0000 -> piece type
* 0000 0011 1111 1000 0000 0000 -> opposite piece position
* 0011 1100 0000 0000 0000 0000 -> piece of opposite type
* 0100 0000 0000 0000 0000 0000 -> team of the piece (1=white, 0=black)
*/
inline int get_piece_pos(int pieceinfo){
return (pieceinfo & 0x7f);
}
inline int get_piece_type(int pieceinfo){
return ((pieceinfo << 7) & 0xf);
}
inline int get_opposite_piece_type(int pieceinfo){
return ((pieceinfo << 11) & 0xf);
}
// TO find out if white/black use:
// get_team_of_piece_type == Color::WHITE/BLACK
inline int get_team_of_piece_type(int pieceinfo){
return ((pieceinfo << 15) & 0x1);
}
inline int get_new_position_of_piece(int pieceinfo){
return ((pieceinfo << 16) & 0xf);
}
/* Move ints contain a lot of information as well. However, these are DIFFERENt from the other dense ints. Moves are universalyl passed by reference (&) to a vector of ints, whereas the above is passed only is 1 int by itself.
* Here is the notation for moves (although it is obscured by the make_move(), get_to/from_sq(), get_captured_pc() etc... functions.
*
* From (Position): 7 bits (2^7 == 128) possibilities
* To (Position): same as above
* Captured piece, if any: 4 bits (16) possibilities
* Promoted to, if any: 4 bits (16) possibilities
* en passant flag: 1 bit
* pawn starting move flag: 1 bit
* castle move flag: 1 bit
*
* 0000 0000 0000 0000 0000 0111 1111 -> From square position (& 0x7F)
* 0000 0000 0000 0011 1111 1000 0000 -> To square position (>> 7 & 0x7F)
* 0000 0000 0011 1100 0000 0000 0000 -> captured piece, if any (>> 14 & 0xF)
* 0000 0011 1100 0000 0000 0000 0000 -> if prmoted, what to? (>> 18 & 0xF)
* 0000 0100 0000 0000 0000 0000 0000 -> en passant (>> 22 &0x1)
* 0000 1000 0000 0000 0000 0000 0000 -> pawn starting move (>> 23 &0x1)
* 0001 0000 0000 0000 0000 0000 0000 -> castle move (>> 24 0x1)
* 0010 0000 0000 0000 0000 0000 0000 -> check flag (>> 25 &0x1)
* */
//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::vector<int> QUEEN_PIECE_OFFSETS = {-1, -10, 1, 10, -11, -9, 9, 11};
Rank get_rank(int pos){
int rank = 0;
while (pos >= 0){
pos -= 10;
rank++;
}
return std::make_pair(x, std::abs(y-7));
return static_cast<Rank>(rank - 3);
}
// 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.");
bool is_white(int pt){
for (auto pn : Pieces::WHITE){
if (pn == pt) return true;
}
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());
return false;
}
bool is_black(int pt){
for (auto pn : Pieces::BLACK){
if (pn == pt) return true;
}
return false;
}
std::vector<Position> get_possible_movers(Position pn, std::array<PieceType, 64> board){
std::vector<Position> pns = {Position::A1};
return pns;
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 pn, const std::array<PieceType, 120>& board){
return get_color(board[pn]);
}
std::vector<Position> get_possible_moves(Position pn, std::array<PieceType, 64> board){
std::vector<Position> pns = {Position::A1};
Color rev_color(Color c){
if (c==Color::NO_COLOR) return Color::NO_COLOR;
return c==Color::WHITE?Color::BLACK:Color::WHITE;
}
PieceType rev_color(PieceType pt){
//return static_cast<PieceType>((~pt) & 0xf);
for (int i=0; i!=Pieces::WHITE.size(); i++){
if (pt == Pieces::WHITE[i]){
return Pieces::BLACK[i];
}
}
for (int i=0; i!=Pieces::BLACK.size(); i++){
if (pt == Pieces::BLACK[i]){
return Pieces::WHITE[i];
}
}
return PieceType::NONE;
}
std::vector<int> get_possible_movers(Position pn, const std::array<PieceType, 120>& board){
std::vector<int> pns = {Position::A1};
return pns;
}
std::vector<Position> get_all_moves(Position pn, std::array<PieceType, 64> board){
PieceType pt = board[pn];
std::vector<Position> pns;
int x = pos_to_pair(pn).first;
int y = pos_to_pair(pn).second;
int dx;
int dy;
switch(pt){
case PieceType::B_ROOK:
case PieceType::W_ROOK:
for (int j = 7; j >= 0; j--){
if (j != y){
pns.push_back(pair_to_pos(std::make_pair(x,j)));
}
for (int i = 0; i < 8; i++){
if (j == y){
pns.push_back(pair_to_pos(std::make_pair(i,y)));
}
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){
return pn;
}
}
return Position::NA;
}
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){
results.push_back(pn);
}
break;
case PieceType::B_BISHOP:
case PieceType::W_BISHOP:
for (int r = 7; r >= 0; r--){
for (int f = 0; f < 8; f++){
for (int i=0; i<8; i++){
if ((f-i == x && r-i == y) ||
(f+i == x && r+i == y) ||
(f-i == x && r+i == y) ||
(f+i == x && r-i == y)){
pns.push_back(pair_to_pos(std::make_pair(f, r)));
break;
}
}
/*
if (((i>x) && (i<8)) && ((j>y) && (j<8)))
{
dx = i-x;
dy = j-y;
if (dx == dy){pns.push_back(pair_to_pos(std::make_pair(x+dx,y+dy)));}
}
if (((i>=0) && (i<x)) && ((j>y) && (j<8)))
{
dx = i+1;
dy = j-y;
if (dx == dy){pns.push_back(pair_to_pos(std::make_pair(x-dx,y+dy)));}
}
if (((i>=0) && (i<x)) && ((j>=0) && (j<y)))
{
dx = i+1;
dy = j+1;
if (dx == dy){pns.push_back(pair_to_pos(std::make_pair(x-dx,y-dy)));}
}
return results;
}
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);
}
}
}
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);
for (int reverse_move : moves){
if (get_captured_pc(reverse_move) == opposite_color_piece){
return true;
}
}
}
return false;
}
bool is_attacked(int pos, const std::array<PieceType, 120>& board){
return would_be_attacked(pos, board[pos], board);
}
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);
}
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);
// If the other team doesn't have a king, don't add any checked flags
if (other_king_pos == Position::NA){
return;
}
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);
}
++move_pn;
}
}
//TODO: Make faster by running from king squar eonly, instead of running on every piece of opposite team.
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;
// If this team doesn't have a king, don't do anything, jsut return.
if (my_king_pos == Position::NA){
return;
}
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;
break;
}
// TODO: Make this more effecient.
// There is no way in hell, this is as complicated as it seems.
// If moved left
// Queenside
if ((get_from_sq(*p_pn) - get_to_sq(*p_pn)) > 0){
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;
}
if (((i>x) && (i<8)) && ((j>=0) && (j<y)))
{
dx = i-x;
dy = j+1;
if (dx == dy){pns.push_back(pair_to_pos(std::make_pair(x+dx,y-dy)));}
// Kingside
} else {
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;
}
if ((i==x) && (j==y))
{
pns.push_back(pair_to_pos(std::make_pair(x,y)));
}*/
}
} else {
// if it is a king, that is in check
// remove all castle moves
if ((pt == PieceType::W_KING ||
pt == PieceType::B_KING) &&
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, 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){
my_king_pos = get_to_sq(*p_pn);
}
if (is_attacked(my_king_pos, moved_board)){
p_pn = pns.erase(p_pn);
} else {
++p_pn;
}
}
break;
}
}
void _get_all_moves_as_if_ray_type(int pos, std::vector<int> offsets, std::vector<int>& moves, const std::array<PieceType, 120>& board, Color color_of_piece, Color color_of_opponent){
for (int offset : offsets){
for (int times = 1; times < 8; ++times){
int true_offset = pos+(offset*times);
if (get_color(board[true_offset]) == color_of_opponent){
moves.push_back(make_move(pos, true_offset, board[true_offset]));
break;
} else if (get_color(board[true_offset]) == color_of_piece ||
board[true_offset] == PieceType::INV){
break;
} else {
moves.push_back(make_move(pos, true_offset, board[true_offset]));
}
}
}
}
void _get_all_moves_as_if_not_ray(int pos, std::vector<int> offsets, std::vector<int>& moves, const std::array<PieceType, 120>& board, Color color_of_piece, Color color_of_opponent){
for (int offset : offsets){
int true_offset = pos+offset;
if (board[true_offset] == PieceType::NONE ||
get_color(board[true_offset]) == color_of_opponent){
moves.push_back(make_move(pos, true_offset, board[true_offset]));
}
}
}
// WARNING: This function depends on the order of the moves being correct.
// The last two king moves MUST be for the king's position +1, and -1 respectively.
// TODO finish function
void _get_all_castle_moves(int pos, int castle_perms, std::vector<int>& moves, const std::array<PieceType, 120>& board, Color color_of_piece, Color color_of_opponent){
if (color_of_piece == Color::WHITE){
} else {
}
}
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){
int piece_info = 0;
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_as_if_ray_type(pos, QUEEN_PIECE_OFFSETS, moves, board, color_of_piece, color_of_opponent);
//_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_as_if_ray_type(pos, ROOK_PIECE_OFFSETS, moves, board, color_of_piece, color_of_opponent);
//_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_as_if_ray_type(pos, BISHOP_PIECE_OFFSETS, 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_KNIGHT:
case PieceType::W_KNIGHT:
_get_all_moves_as_if_not_ray(pos, KNIGHT_PIECE_OFFSETS, moves, board, color_of_piece, color_of_opponent);
//_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_as_if_not_ray(pos, KING_PIECE_OFFSETS, moves, board, color_of_piece, color_of_opponent);
// if (castle_perms != 0){
// _get_all_castle_moves();
// }
_get_all_moves_king(pos, moves, board, color_of_piece, color_of_opponent, castle_perms);
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;
}
return pns;
if (recursive){
filter_checked_moves(pt, board, moves);
add_checked_flags(pt, board, moves);
}
}
std::array<PieceType, 64> dumb_move(Position from, Position to, std::array<PieceType, 64> board){
PieceType piece = board[from];
board[to] = piece;
board[from] = PieceType::NONE;
return board;
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, 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;
}
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);
int from = get_from_sq(move);
int to = get_to_sq(move);
PieceType piece = new_board[from];
if (en_passant_flag == 1) {
int diff = to-from;
int other_pawn_pos = 0;
if (diff == -11){
other_pawn_pos = from-1;
} else if (diff == -9){
other_pawn_pos = from+1;
} else if (diff == 11){
other_pawn_pos = from+1;
} else if (diff == 9){
other_pawn_pos = from-1;
}
new_board[other_pawn_pos] = PieceType::NONE;
new_board[to] = piece;
new_board[from] = PieceType::NONE;
} else if(castle_flag == 1){
int diff = to-from;
int rook_from_pos = 0;
int rook_to_pos = 0;
// If castling queenside
if (diff == -2){
rook_from_pos = to-2;
rook_to_pos = from-1;
// If caslting kingside
} else if (diff == 2){
rook_from_pos = to+1;
rook_to_pos = from+1;
}
PieceType rook_pt = new_board[rook_from_pos];
new_board[rook_from_pos] = PieceType::NONE;
new_board[rook_to_pos] = rook_pt;
new_board[from] = PieceType::NONE;
new_board[to] = piece;
} else {
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();){
if (get_captured_pc(*move_pn) == piecetype &&
get_to_sq(*move_pn) != origin){
++move_pn;
} else {
move_pn = moves.erase(move_pn);
}
}
};
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];
}
} else if (moves.size() > 1){
disambig = POSITION_STRING[from];
}
}
std::string to_notation(int move, const std::array<PieceType, 120>& board){
int to = get_to_sq(move);
int from = get_from_sq(move);
// This can be ran right away due to the simplicity of the notation.
if (get_castle_flag(move) == 1){
return to-from<0 ? "O-O-O" : "O-O";
}
PieceType piecetype = board[from];
std::string from_string = POSITION_STRING[from];
int captured_piece = get_captured_pc(move);
int promoting_to = get_promoted_to_pc(move);
// Blank if not pawn
// file if pawn and capture move
std::string pawn_file = "";
// Blank if pawn
// otherwise N/B/R/Q/K corresponding to each piece
// same for black and white
std::string piece_character = "";
// Blank if not a capture
// x if a capture move
std::string capture_character = "";
// Blank if not en passant move
// otherwise e.p.
std::string en_passant = "";
// Black if no check,
// + if check
// # if checkmate
std::string check = "";
// Blank if only this piece can move to the to square
// include file (a-h) if another piece can move to the to square
// includes rank (1-8) if pieces have same file
// includes both (f)(r) if 2+ identical piece can move to the to square
std::string disambig = "";
// Blank if not a pawn promotion move.
// Otherwise is equal to "=P/N/B/R/Q".
std::string promotion;
auto other_pieces = is_white(piecetype)?Pieces::BLACK:Pieces::WHITE;
if (captured_piece != PieceType::NONE){
capture_character = "x";
// Comment #6
// if a pawn is capturing, have the disambiguation be the pawn's file
// stored in a seperate variable because pawn disabiguation by file happens at the start of a notation. For example:
// exf4 as opposed to Qh1xf4
if (piecetype == PieceType::W_PAWN ||
piecetype == PieceType::B_PAWN){
pawn_file = POSITION_STRING[from][0];
}
}
// Pawns do not require this, as their file is ALWAYS enough to identify them,
// and the file is always speicified on a pawn capture.
// (See comment #6)
if (piecetype != PieceType::W_PAWN &&
piecetype != PieceType::B_PAWN){
// Simulated a piece of the same type, and opposite color moving from the to square
// to check if any other pieces can also move here.
// Basically it searches to see if there are duplicate pieces which can move to the same spot.
// 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);
// 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);
piece_character = CHESS_CHARS_INSENSITIVE[piecetype];
_non_pawn_disambiguate(from, to, piecetype, other_moves, disambig);
}
if (get_en_pass_flag(move) == 1){
en_passant = "e.p.";
}
if (get_check_flag(move) == 1){
check = "+";
// This checks if the other team has any valid moves.
// If not, the check sign changes to a hashtag (#).
std::array<PieceType, 120> moved_board;
dumb_move(move, board, moved_board);
std::vector<int> other_moves = {};
get_all_moves_for_pieces(other_pieces, moved_board, other_moves);
if (other_moves.empty()){
check = "#";
}
}
// If promoting, add an equals sign and the piece promoting to.
if (promoting_to != PieceType::NONE){
promotion += "=";
promotion += CHESS_CHARS_INSENSITIVE[promoting_to];
}
// end of checking for multiple pieces
std::string result = "";
result += pawn_file + piece_character + disambig + capture_character + POSITION_STRING[to] + en_passant + promotion + check;
return result;
}
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());
}
}
}
// From StackOverflow (https://stackoverflow.com/questions/5891610/how-to-remove-certain-characters-from-a-string-in-c#5891643)
void remove_chars_from_string(std::string &str, std::string charsToRemove ) {
for ( unsigned int i = 0; i < charsToRemove.length(); ++i ) {
str.erase( remove(str.begin(), str.end(), charsToRemove.at(i)), str.end() );
}
}

@ -1,26 +1,74 @@
#include "constants.h"
#include <string>
#include <vector>
#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);
// Returns a list of positions with PieceType pt
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);
// Check if int is a valid position in enum of Position
// Allow ints, and pairs to be checked.
bool is_valid_position(int pos);
// Returns rank enum value for given pos
Rank get_rank(int pos);
// Checks if given piece matches a certain color.
bool is_white(int pt);
bool is_black(int pt);
Color get_color(int pn, const 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);
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.
std::vector<Position> get_possible_movers(Position pn, std::array<PieceType, 64> pt);
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.
std::vector<Position> get_possible_moves(Position pn, std::array<PieceType, 64> pt);
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, 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, 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, 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);
// Get all moved for piece in Position pn.
std::vector<Position> get_all_moves(Position pn, std::array<PieceType, 64> pt);
// Dumb function to do board moves.
// Does NOT check for valid moves. Only moves PieceType of Pos1 to Pos2, then replaces Pos1 with Piecetype::NONE
std::array<PieceType, 64> dumb_move(Position from, Position to, std::array<PieceType, 64> board);
// Does not check if move is valid, just does it.
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 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, 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, 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);

@ -1,123 +1,193 @@
#include <vector>
#include <constants.h>
const Position B_QUEEN_POS = E4;
const std::array<PieceType, 64> B_QUEEN_BOARD = {
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,
NONE, NONE, NONE, NONE, B_QUEEN, 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
const int B_QUEEN_POS = E4;
const std::array<PieceType, 120> B_QUEEN_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, NONE, NONE, B_QUEEN, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<Position> B_QUEEN_ALL_MOVES = {
A8, E8,
B7, E7, H7,
C6, E6, G6,
D5, E5, F5,
A4, B4, C4, D4, E4, F4, G4, H4,
D3, E3, F3,
C2, E2, G2,
B1, E1, H1
const std::vector<int> B_QUEEN_ALL_MOVES = {
D4, C4, B4, A4,
E5, E6, E7, E8,
F4, G4, H4,
E3, E2, E1,
D5, C6, B7, A8,
F5, G6, H7,
D3, C2, B1,
F3, G2, H1
};
const Position B_BISHOP_POS = D4;
const std::array<PieceType, 64> B_BISHOP_BOARD = {
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,
NONE, NONE, NONE, B_BISHOP, 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
const int B_BISHOP_POS = D4;
const std::array<PieceType, 120> B_BISHOP_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, NONE, B_BISHOP, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<Position> B_BISHOP_ALL_MOVES = {
H8,
A7, G7,
B6, F6,
C5, E5,
D4,
C3, E3,
B2, F2,
A1, G1
const std::vector<int> B_BISHOP_ALL_MOVES = {
C5, B6, A7, E5, F6, G7, H8, C3, B2, A1, E3, F2, G1
};
const Position B_KNIGHT_POS = D5;
const std::array<PieceType, 64> B_KNIGHT_BOARD = {
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, B_KNIGHT, 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, NONE, NONE, NONE, NONE
const int B_KNIGHT_POS = D5;
const std::array<PieceType, 120> B_KNIGHT_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, B_KNIGHT, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<Position> B_KNIGHT_ALL_MOVES = {
C7, E7,
B6, F6,
D5,
B4, F4,
C3, E3
const std::vector<int> B_KNIGHT_ALL_MOVES = {
B6, C7, E7, F6, B4, F4, C3, E3
};
const Position B_ROOK_POS = E5;
const std::array<PieceType, 64> B_ROOK_BOARD = {
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, B_ROOK, 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, NONE, NONE, NONE
const int B_ROOK_POS = E5;
const std::array<PieceType, 120> B_ROOK_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<Position> B_ROOK_ALL_MOVES = {
E8, E7, E6,
A5, B5, C5, D5, E5, F5, G5, H5,
const std::vector<int> B_ROOK_ALL_MOVES = {
D5, C5, B5, A5,
E6, E7, E8,
F5, G5, H5,
E4, E3, E2, E1
};
const Position B_KING_POS = C4;
const std::array<PieceType, 64> B_KING_BOARD = {
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,
NONE, NONE, B_KING, 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
const int B_KING_POS = C4;
const std::array<PieceType, 120> B_KING_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, B_KING, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<Position> B_KING_ALL_MOVES = {
const std::vector<int> B_KING_ALL_MOVES = {
B5, C5, D5,
B4, C4, D4,
B3, C3, D3
B3, C3, D3,
D4, B4
};
const Position B_PAWN_POS = F4;
const std::array<PieceType, 64> B_PAWN_BOARD = {
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,
NONE, NONE, NONE, 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
const int B_PAWN_POS = F4;
const std::array<PieceType, 120> B_PAWN_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, NONE, NONE, NONE, B_PAWN, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<Position> B_PAWN_ALL_MOVES = {
F4,
E3, F3, G3,
F2
const std::vector<int> B_PAWN_ALL_MOVES = {
F3
};
const int B_KNIGHT_SIDE1_POS = B7;
const std::array<PieceType, 120> B_KNIGHT_SIDE1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, B_KNIGHT, 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, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> B_KNIGHT_SIDE1_ALL_MOVES = {
D8,
D6,
A5, C5
};
const int B_KING_SIDE1_POS = A8;
const std::array<PieceType, 120> B_KING_SIDE1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_KING, 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, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> B_KING_SIDE1_ALL_MOVES = {
A7,B7,B8
};
const int B_PAWN_SIDE1_POS = A7;
const std::array<PieceType, 120> B_PAWN_SIDE1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, B_PAWN, 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, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> B_PAWN_SIDE1_ALL_MOVES = {
A6, A5
};

@ -1,4 +1,38 @@
defualt: build
defualt: all.out
bitwise: bitwise.out
release: all_optimized.out
speed_tests: speed_tests.out
build:
g++ -std=c++11 -w -I../src/ -o tests.out ../src/functions.cpp tests_main.cpp
clean:
rm all.out
distclean:
rm *.o
rm *.out
catch_main.o:
g++ -w -c -o catch_main.o catch_main.cpp
custom_printing.o:
g++ -Wall -I../src/ -c -o custom_printing.o custom_printing.cpp
bitwise.out: catch_main.o
g++ -Wall -I../src -o bitwise.out catch_main.o bitwise_tests.cpp
# TODO: Allw all.out to contain bitwise tests
all.out: catch_main.o custom_printing.o
g++ -std=c++11 -ggdb -Wall -I../src/ -o all.out ../src/functions.cpp catch_main.o custom_printing.o test_functions.cpp main.cpp
catch_main_optimized.o:
g++ -w -O2 -c -o catch_main_optimized.o catch_main.cpp
custom_printing_optimized.o:
g++ -Wall -O2 -I../src/ -c -o custom_printing_optimized.o custom_printing.cpp
bitwise_optimized.out: catch_main_optimized.o
g++ -Wall -O2 -I../src -o bitwise_optimized.out catch_main_optimized.o bitwise_tests.cpp
all_optimized.out: catch_main_optimized.o custom_printing_optimized.o
g++ -std=c++11 -O2 -Wall -I../src/ -o all_optimized.out ../src/functions.cpp catch_main_optimized.o custom_printing_optimized.o test_functions.cpp main.cpp
speed_tests.out:
g++ -O2 -Wall -I../src/ -o speed_tests.out ../src/functions.cpp speed.cpp

@ -1,133 +1,209 @@
#include <vector>
#include <constants.h>
const Position W_QUEEN_POS = E4;
const std::array<PieceType, 64> W_QUEEN_BOARD = {
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,
NONE, NONE, NONE, NONE, W_QUEEN, 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
};
const std::array<PieceType, 64> W_QUEEN_BOARD_BLOCKED = {
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, B_PAWN, W_PAWN, B_PAWN, NONE, NONE,
NONE, NONE, NONE, W_KNIGHT, W_QUEEN, B_PAWN, NONE, NONE,
NONE, NONE, NONE, B_QUEEN, B_KNIGHT, W_PAWN, NONE, NONE,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE
};
const std::vector<Position> W_QUEEN_ALL_MOVES = {
A8, E8,
B7, E7, H7,
C6, E6, G6,
D5, E5, F5,
A4, B4, C4, D4, E4, F4, G4, H4,
D3, E3, F3,
C2, E2, G2,
B1, E1, H1
};
const Position W_BISHOP_POS = D4;
const std::array<PieceType, 64> W_BISHOP_BOARD = {
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,
NONE, NONE, NONE, W_BISHOP, 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
};
const std::vector<Position> W_BISHOP_ALL_MOVES = {
H8,
A7, G7,
B6, F6,
C5, E5,
D4,
C3, E3,
B2, F2,
A1, G1
};
const Position W_KNIGHT_POS = D5;
const std::array<PieceType, 64> W_KNIGHT_BOARD = {
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_KNIGHT, 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, NONE, NONE, NONE, NONE
};
const std::vector<Position> W_KNIGHT_ALL_MOVES = {
C7, E7,
B6, F6,
D5,
B4, F4,
C3, E3
};
const Position W_ROOK_POS = E5;
const std::array<PieceType, 64> W_ROOK_BOARD = {
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_ROOK, 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, NONE, NONE, NONE
};
const std::vector<Position> W_ROOK_ALL_MOVES = {
E8, E7, E6,
A5, B5, C5, D5, E5, F5, G5, H5,
const int W_QUEEN_POS = E4;
const std::array<PieceType, 120> W_QUEEN_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, NONE, NONE, W_QUEEN, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::array<PieceType, 120> W_QUEEN_BOARD_BLOCKED = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, B_PAWN, W_PAWN, B_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, W_KNIGHT, W_QUEEN, B_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, B_QUEEN, B_KNIGHT, W_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> W_QUEEN_ALL_MOVES = {
D4, C4, B4, A4,
E5, E6, E7, E8,
F4, G4, H4,
E3, E2, E1,
D5, C6, B7, A8,
F5,
G6, H7, D3, C2, B1, F3, G2, H1
};
const int W_BISHOP_POS = D4;
const std::array<PieceType, 120> W_BISHOP_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, NONE, W_BISHOP, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> W_BISHOP_ALL_MOVES = {
C5, B6, A7, E5, F6, G7, H8, C3, B2, A1, E3, F2, G1
};
const int W_KNIGHT_POS = D5;
const std::array<PieceType, 120> W_KNIGHT_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, W_KNIGHT, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const int W_KNIGHT_SIDE1_POS = B7;
const std::array<PieceType, 120> W_KNIGHT_SIDE1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, W_KNIGHT, 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, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> W_KNIGHT_SIDE1_ALL_MOVES = {
D8,
D6,
A5, C5
};
const std::vector<int> W_KNIGHT_ALL_MOVES = {
B6, C7, E7, F6, B4, F4, C3, E3
};
const int W_ROOK_POS = E5;
const std::array<PieceType, 120> W_ROOK_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, W_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> W_ROOK_ALL_MOVES = {
D5, C5, B5, A5,
E6, E7, E8,
F5, G5, H5,
E4, E3, E2, E1
};
const Position W_KING_POS = C4;
const std::array<PieceType, 64> W_KING_BOARD = {
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,
NONE, NONE, W_KING, 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
const int W_KING_POS = C4;
const std::array<PieceType, 120> W_KING_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, W_KING, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<Position> W_KING_ALL_MOVES = {
const int W_KING_SIDE1_POS = A8;
const std::array<PieceType, 120> W_KING_SIDE1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, W_KING, 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, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> W_KING_SIDE1_ALL_MOVES = {
A7,B7,
B8
};
const std::vector<int> W_KING_ALL_MOVES = {
B5, C5, D5,
B4, C4, D4,
B3, C3, D3
B3, C3, D3,
D4, B4
};
const Position W_PAWN_POS = F4;
const std::array<PieceType, 64> W_PAWN_BOARD = {
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,
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, NONE, NONE, NONE, NONE, NONE, NONE
const int W_PAWN_POS = F4;
const std::array<PieceType, 120> W_PAWN_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, NONE, NONE, NONE, W_PAWN, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> W_PAWN_ALL_MOVES = {
F5
};
const std::vector<Position> W_PAWN_ALL_MOVES = {
F6,
E5, F5, G5,
F4
const int W_PAWN_SIDE1_POS = A8;
const std::array<PieceType, 120> W_PAWN_SIDE1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, W_PAWN, 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, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> W_PAWN_SIDE1_ALL_MOVES;

@ -0,0 +1,92 @@
#include <bitwise.h>
#include <constants.h>
#include "catch.hpp"
/*
* From (Position): 6 bits (2^6 == 64) possibilities
* To (Position): same as above
* Captured piece, if any: 4 bits (16) possibilities
* Promoted to, if any: 4 bits (16) possibilities
* en passant flag: 1 bit
* pawn starting move flag: 1 bit
* castle move flag: 1 bit
*
* (32-bit int, room to exapnd if neccessary)
* 0000 0000 0000 0000 0000 0000 0111 1111 -> From square position (& 0x7F)
* 0000 0000 0000 0000 0011 1111 1000 0000 -> To square position (>> 7 & 0x3F8)
* 0000 0000 0000 0011 1100 0000 0000 0000 -> captured piece, if any (>> 14 & 0xF)
* 0000 0000 0011 1100 0000 0000 0000 0000 -> if prmoted, what to? (>> 18 & 0xF)
* 0000 0000 0100 0000 0000 0000 0000 0000 -> en passant (& 0x400000)
* 0000 0000 1000 0000 0000 0000 0000 0000 -> pawn starting move (& 0x800000)
* 0000 0001 0000 0000 0000 0000 0000 0000 -> castle move (& 0x1000000)
* */
// This is testing position G1
const unsigned int MOVE_G1 = Position::G1;
// This is testing position H1
const unsigned int MOVE_H1 = Position::H1;
// This is testing a move with no flags from G1 to H1
const unsigned int MOVE_G1_TO_H1 = 0b1100010'1100001;
// This is testing a move with no flags from H1 to G1
const unsigned int MOVE_H1_TO_G1 = 0b1100001'1100010;
// Move from H1 to G1 and capture
const unsigned int MOVE_H1_TO_G1_CAPTURE_B_KNIGHT = 0b0010'1100001'1100010;
// Move from H1 to G1 and promote
const unsigned int MOVE_H1_TO_G1_PROMOTE_TO_QUEEN = 0b0101'0000'1100001'1100010;
// Move from H1 to G1 and en passant
const unsigned int MOVE_H1_TO_G1_EN_PASSANT = 0b1'0000'0000'1100001'1100010;
// Move from H1 to G1 and its the starting move for a pawn
const unsigned int MOVE_H1_TO_G1_PAWN_START = 0b1'0'0000'0000'1100001'1100010;
// Move from H1 to G1 and castle
const unsigned int MOVE_H1_TO_G1_AND_CASTLE = 0b1'0'0'0000'0000'1100001'1100010;
// Want:
// From: E4 (65)
// To: D3 (74)
// (these 2 combine together) (33)
// Captures: B_PAWM (7)
// Promoted: NONE (0)
// en passant: true (1)
// pawn starting move: false (0)
// castle move: false (0)
// total value: (?)
const unsigned int GET_ALL_INT = 0b0'0'1'0000'0001'1001010'1000001;
TEST_CASE("Test that bitwise operators return appropriate values. Move.from", "[bitwise_from_pos]"){
CHECK(get_from_sq(MOVE_G1) == Position::G1);
CHECK(get_from_sq(MOVE_H1) == Position::H1);
CHECK(get_to_sq(MOVE_G1_TO_H1) == Position::H1);
CHECK(get_from_sq(MOVE_G1_TO_H1) == Position::G1);
CHECK(get_to_sq(MOVE_H1_TO_G1) == Position::G1);
CHECK(get_from_sq(MOVE_H1_TO_G1) == Position::H1);
CHECK(get_captured_pc(MOVE_H1_TO_G1_CAPTURE_B_KNIGHT) == PieceType::B_KNIGHT);
CHECK(get_promoted_to_pc(MOVE_H1_TO_G1_PROMOTE_TO_QUEEN) == PieceType::B_QUEEN);
CHECK(get_en_pass_flag(MOVE_H1_TO_G1_EN_PASSANT) == 1);
CHECK(get_pawn_st_flag(MOVE_H1_TO_G1_PAWN_START) == 1);
CHECK(get_castle_flag(MOVE_H1_TO_G1_AND_CASTLE) == 1);
CHECK(get_from_sq(GET_ALL_INT) == Position::E4);
CHECK(get_to_sq(GET_ALL_INT) == Position::D3);
CHECK(get_captured_pc(GET_ALL_INT) == PieceType::B_PAWN);
CHECK(get_promoted_to_pc(GET_ALL_INT) == PieceType::NONE);
CHECK(get_en_pass_flag(GET_ALL_INT) == 1);
CHECK(get_pawn_st_flag(GET_ALL_INT) == 0);
CHECK(get_castle_flag(GET_ALL_INT) == 0);
}
TEST_CASE("Test that is_valid_position works properly", "[is_valid_position]"){
CHECK_FALSE(is_valid_position(0));
CHECK(is_valid_position(Position::A8));
CHECK(is_valid_position(Position::H1));
}

@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

@ -0,0 +1,86 @@
#include "catch.hpp"
#include <constants.h>
#include <sstream>
#include <vector>
// 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<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::vector<int>> {
static std::string convert(std::vector<int> const& uo_poss){
std::vector<int> 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 = 2; i < 10; ++i){
ss << 8-(i-2) << "|";
for (int j = 1; j < 9; ++j){
int index = (i*10)+j;
// This part loops through all positions in the list and checks if it contains the current index.
bool part_of_poss = false;
for (int 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-2);
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();
}
};
}

@ -0,0 +1,315 @@
#include "catch.hpp"
#include "test_boards.h"
#include "valid_moves.h"
#include "custom_printing.cpp"
#include "test_functions.h"
#include <bitwise.h>
#include <sstream>
#include <functions.h>
const std::array<PieceType, 120> DUMB_MOVE_1 = {
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, W_PAWN, 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, NONE, 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
};
TEST_CASE("Test that the get_to_squares works, this is required!", "[get_to_squares]"){
std::vector<int> to_squares = {Position::H1};
std::vector<int> moves = {0b11000100000000};
REQUIRE(get_to_squares(moves) == to_squares);
}
TEST_CASE("Test that get_rank() works)", "[get_rank]"){
CHECK(get_rank(Position::F3) == Rank::RANK3);
CHECK(get_rank(Position::G1) == Rank::RANK1);
}
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);
}
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);
}
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 reversing color on pieve", "[rev_color]"){
CHECK(rev_color(PieceType::B_KING) == W_KING);
CHECK(rev_color(PieceType::B_QUEEN) == W_QUEEN);
CHECK(rev_color(PieceType::B_ROOK) == W_ROOK);
CHECK(rev_color(PieceType::B_BISHOP) == W_BISHOP);
CHECK(rev_color(PieceType::B_KNIGHT) == W_KNIGHT);
CHECK(rev_color(PieceType::B_PAWN) == W_PAWN);
CHECK(rev_color(PieceType::W_KING) == B_KING);
CHECK(rev_color(PieceType::W_QUEEN) == B_QUEEN);
CHECK(rev_color(PieceType::W_ROOK) == B_ROOK);
CHECK(rev_color(PieceType::W_BISHOP) == B_BISHOP);
CHECK(rev_color(PieceType::W_KNIGHT) == B_KNIGHT);
CHECK(rev_color(PieceType::W_PAWN) == B_PAWN);
}
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]"){
int move_int = Position::B2 + (Position::B5 << 7);
CHECK(dumb_move(move_int, DEFAULT_BOARD) == DUMB_MOVE_1);
}
TEST_CASE("Test that invalid position ints return false", "[is_valid_position]"){
CHECK(is_valid_position(Position::A8));
CHECK(is_valid_position(Position::H1));
CHECK_FALSE(is_valid_position(((int) Position::H1) + 1));
}
TEST_CASE("Test all possible and impossible moves for black pieces", "[get_all_moves][black]"){
CHECK(get_to_squares(get_all_moves(B_KING_POS, B_KING_BOARD)) == B_KING_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(B_QUEEN_POS, B_QUEEN_BOARD)) == B_QUEEN_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(B_ROOK_POS, B_ROOK_BOARD)) == B_ROOK_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(B_BISHOP_POS, B_BISHOP_BOARD)) == B_BISHOP_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(B_KNIGHT_POS, B_KNIGHT_BOARD)) == B_KNIGHT_ALL_MOVES);
CHECK(get_to_squares(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_to_squares(get_all_moves(W_KING_POS, W_KING_BOARD)) == W_KING_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(W_QUEEN_POS, W_QUEEN_BOARD)) == W_QUEEN_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(W_ROOK_POS, W_ROOK_BOARD)) == W_ROOK_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(W_BISHOP_POS, W_BISHOP_BOARD)) == W_BISHOP_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(W_KNIGHT_POS, W_KNIGHT_BOARD)) == W_KNIGHT_ALL_MOVES);
CHECK(get_to_squares(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_to_squares(get_all_moves(W_KNIGHT_SIDE1_POS, W_KNIGHT_SIDE1_BOARD)) == W_KNIGHT_SIDE1_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(W_KING_SIDE1_POS, W_KING_SIDE1_BOARD)) == W_KING_SIDE1_ALL_MOVES);
CHECK(get_to_squares(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_to_squares(get_all_moves(B_KNIGHT_SIDE1_POS, B_KNIGHT_SIDE1_BOARD)) == B_KNIGHT_SIDE1_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(B_KING_SIDE1_POS, B_KING_SIDE1_BOARD)) == B_KING_SIDE1_ALL_MOVES);
CHECK(get_to_squares(get_all_moves(B_PAWN_SIDE1_POS, B_PAWN_SIDE1_BOARD)) == B_PAWN_SIDE1_ALL_MOVES);
}
TEST_CASE("Tests is_king_checked works", "[is_attacked]"){
auto king_checked_moves = get_all_moves(KING_CHECK_TEST_POS, KING_CHECK_TEST_BOARD);
auto rook_checked_moves = get_all_moves(ROOK_CHECK_TEST_POS, KING_CHECK_TEST_BOARD);
CHECK(get_to_squares(king_checked_moves) == KING_CHECK_TEST_MOVES);
CHECK(get_to_squares(rook_checked_moves) == KING_CHECK_ROOK_MOVES);
CHECK(is_attacked(KING_CHECK_TEST_POS, KING_CHECK_TEST_BOARD));
CHECK(is_attacked(BLACK_CHECK_POS1, BLACK_CHECK_BOARD1));
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);
auto pawn_diag_moves = get_all_moves(PAWN_DIAG_TEST1_POS, PAWN_DIAG_TEST1_BOARD);
std::vector<int> pawn_start_flags = {0, 1, 0};
CHECK(get_to_squares(pawn_diag_moves) == PAWN_DIAG_TEST1_MOVES);
CHECK(get_pawn_start_flags(pawn_diag_moves) == pawn_start_flags);
}
TEST_CASE("Tests for en pessant squares.", "[get_all_moves]"){
auto en_pass_moves = get_all_moves(EN_PASSANT_TEST_POS, EN_PASSANT_TEST_BOARD, true, EN_PASSANT_SQUARE);
std::vector<int> en_passant_flags = {0, 1};
CHECK(get_to_squares(en_pass_moves) == EN_PASSANT_TEST_MOVES);
CHECK(get_en_passant_flags(en_pass_moves) == en_passant_flags);
CHECK(get_to_squares(get_all_moves(NO_EN_PASSANT_TEST_POS, NO_EN_PASSANT_TEST_BOARD)) == NO_EN_PASSANT_TEST_MOVES);
}
TEST_CASE("Test for pawn promotions.", "[get_all_moves]"){
auto prom_moves = get_all_moves(PROM_PAWN_POS, PROM_PAWN_BOARD);
CHECK(get_to_squares(prom_moves) == PROM_PAWN_MOVES);
CHECK(get_promoted_pieces(prom_moves) == PROM_PAWN_PROMS);
auto bprom_moves = get_all_moves(PROM_BPAWN_POS, PROM_BPAWN_BOARD);
CHECK(get_to_squares(bprom_moves) == PROM_BPAWN_MOVES);
CHECK(get_promoted_pieces(bprom_moves) == PROM_BPAWN_PROMS);
}
TEST_CASE("Test that the captures moves are returned", "[get_all_moves]"){
auto knight_moves = get_all_moves(KNIGHT_BLOCKED1_POS, KNIGHT_BLOCKED1_BOARD);
auto bishop_moves = get_all_moves(BISHOP_BLOCKED1_POS, BISHOP_BLOCKED1_BOARD);
auto rook_moves = get_all_moves(ROOK_BLOCKED1_POS, ROOK_BLOCKED1_BOARD);
auto pawn_moves = get_all_moves(PAWN_DIAG_TEST1_POS, PAWN_DIAG_TEST1_BOARD);
auto king_moves = get_all_moves(KING_CHECK_TEST_POS, KING_CHECK_TEST_BOARD);
auto rook_check_moves = get_all_moves(ROOK_CHECK_MOVED_POS, ROOK_CHECK_MOVED_BOARD);
CHECK(get_captured_pieces(knight_moves) == KNIGHT_BLOCKED1_CAPTS);
CHECK(get_captured_pieces(bishop_moves) == BISHOP_BLOCKED1_CAPTS);
CHECK(get_captured_pieces(rook_moves) == ROOK_BLOCKED1_CAPTS);
CHECK(get_captured_pieces(pawn_moves) == PAWN_DIAG_TEST1_CAPTS);
CHECK(get_captured_pieces(king_moves) == KING_CHECK_TEST_CAPTS);
CHECK(get_captured_pieces(rook_check_moves) == ROOK_CHECK_MOVED_CAPTURES);
}
TEST_CASE("Test that being blocked, stops moves from generating", "[get_all_moves]"){
auto knight_moves = get_all_moves(KNIGHT_BLOCKED1_POS, KNIGHT_BLOCKED1_BOARD);
auto bishop_moves = get_all_moves(BISHOP_BLOCKED1_POS, BISHOP_BLOCKED1_BOARD);
auto rook_moves = get_all_moves(ROOK_BLOCKED1_POS, ROOK_BLOCKED1_BOARD);
CHECK(get_to_squares(knight_moves) == KNIGHT_BLOCKED1_MOVES);
CHECK(get_to_squares(bishop_moves) == BISHOP_BLOCKED1_MOVES);
CHECK(get_to_squares(rook_moves) == ROOK_BLOCKED1_MOVES);
}
TEST_CASE("Test for castling moves.", "[get_all_moves]"){
std::vector<int> cast_flags = {0, 0, 0, 0, 0, 1, 1};
auto cast_moves = get_all_moves(CASTLING_POS, CASTLING_BOARD, true, 0, 0xF);
CHECK(get_to_squares(cast_moves) == CASTLING_MOVES);
CHECK(get_castle_flags(cast_moves) == cast_flags);
auto bcast_moves = get_all_moves(BCASTLING_POS, CASTLING_BOARD, true, 0, 0xF);
CHECK(get_to_squares(bcast_moves) == BCASTLING_MOVES);
CHECK(get_castle_flags(bcast_moves) == cast_flags);
// Check refuses castle
std::vector<int> checked_cast_flags = {0, 0, 0};
auto bcast_checked_moves = get_all_moves(BCASTLING_POS, CASTLING_CHECK_BOARD, true, 0, 0xF);
CHECK(get_to_squares(bcast_checked_moves) == BCASTLING_CHECK_MOVES);
CHECK(get_castle_flags(bcast_checked_moves) == checked_cast_flags);
// Check that castling moves are not allowed when the rook is blocked.
auto blocked_castling_moves = get_all_moves(CASTLE_BLOCKED_POS, CASTLE_BLOCKED_BOARD, true, 0, 0xF);
CHECK(get_to_squares(blocked_castling_moves) == CASTLE_BLOCKED_MOVES);
auto blocked_castling_qmoves = get_all_moves(CASTLE_BLOCKED_QPOS, CASTLE_BLOCKED_QBOARD, true, 0, 0xF);
CHECK(get_to_squares(blocked_castling_qmoves) == CASTLE_BLOCKED_QMOVES);
}
TEST_CASE("Test that en passant moves are properly handled by dumb_move", "dumb_move"){
CHECK(dumb_move(make_move(EN_PASSANT_CHECK_POS, EN_PASSANT_EN_PASSANT_SQUARE, PieceType::B_PAWN, PieceType::NONE, 1), EN_PASSANT_CHECK_BOARD) == EN_PASSANT_CHECK_MOVED_BOARD);
CHECK(dumb_move(make_move(EN_PASSANT_CHECK_POS1, EN_PASSANT_EN_PASSANT_SQUARE1, PieceType::B_PAWN, PieceType::NONE, 1), EN_PASSANT_CHECK_BOARD1) == EN_PASSANT_CHECK_MOVED_BOARD1);
CHECK(dumb_move(make_move(EN_PASSANT_CHECK_POS2, EN_PASSANT_EN_PASSANT_SQUARE2, PieceType::B_PAWN, PieceType::NONE, 1), EN_PASSANT_CHECK_BOARD2) == EN_PASSANT_CHECK_MOVED_BOARD2);
CHECK(dumb_move(make_move(EN_PASSANT_CHECK_POS3, EN_PASSANT_EN_PASSANT_SQUARE3, PieceType::B_PAWN, PieceType::NONE, 1), EN_PASSANT_CHECK_BOARD3) == EN_PASSANT_CHECK_MOVED_BOARD3);
}
TEST_CASE("Test that castle moves are poperly handled by dumb_mobe", "[dumb_move]"){
CHECK(dumb_move(make_move(CASTLE_FROM_POS, CASTLE_TO_POS, PieceType::NONE, PieceType::NONE, 0, 0, 1), CASTLE_BOARD) == CASTLE_BOARD_WK);
CHECK(dumb_move(make_move(CASTLE_FROM_QPOS, CASTLE_TO_QPOS, PieceType::NONE, PieceType::NONE, 0, 0, 1), CASTLE_BOARD) == CASTLE_BOARD_WQ);
CHECK(dumb_move(make_move(BCASTLE_FROM_POS, BCASTLE_TO_POS, PieceType::NONE, PieceType::NONE, 0, 0, 1), CASTLE_BOARD) == CASTLE_BOARD_BK);
CHECK(dumb_move(make_move(BCASTLE_FROM_QPOS, BCASTLE_TO_QPOS, PieceType::NONE, PieceType::NONE, 0, 0, 1), CASTLE_BOARD) == CASTLE_BOARD_BQ);
}
TEST_CASE("Test that algebraic notation conversion is working.", "[to_notation]"){
auto knight_moves = get_all_moves(KNIGHT_BLOCKED1_POS, KNIGHT_BLOCKED1_BOARD);
auto bishop_moves = get_all_moves(BISHOP_BLOCKED1_POS, BISHOP_BLOCKED1_BOARD);
auto rook_moves = get_all_moves(ROOK_BLOCKED1_POS, ROOK_BLOCKED1_BOARD);
auto pawn_moves = get_all_moves(PAWN_DIAG_TEST1_POS, PAWN_DIAG_TEST1_BOARD);
auto king_moves = get_all_moves(KING_CHECK_TEST_POS, KING_CHECK_TEST_BOARD);
auto king_castle_moves = get_all_moves(CASTLING_POS, CASTLE_BOARD, true, 0, 0xF);
auto king_bcastle_moves = get_all_moves(BCASTLING_POS, CASTLE_BOARD, true, 0, 0xF);
auto en_passant_moves = get_all_moves(EN_PASSANT_TEST_POS, EN_PASSANT_TEST_BOARD, true, EN_PASSANT_SQUARE, 0);
auto pawn_prom_moves = get_all_moves(PROM_PAWN_POS, PROM_PAWN_BOARD);
auto bpawn_prom_moves = get_all_moves(PROM_BPAWN_POS, PROM_BPAWN_BOARD);
CHECK(get_notations(knight_moves, KNIGHT_BLOCKED1_BOARD) == KNIGHT_BLOCKED1_NOTATION);
CHECK(get_notations(bishop_moves, BISHOP_BLOCKED1_BOARD) == BISHOP_BLOCKED1_NOTATION);
CHECK(get_notations(rook_moves, ROOK_BLOCKED1_BOARD) == ROOK_BLOCKED1_NOTATION);
CHECK(get_notations(pawn_moves, PAWN_DIAG_TEST1_BOARD) == PAWN_DIAG_TEST1_NOTATION);
CHECK(get_notations(king_moves, KING_CHECK_TEST_BOARD) == KING_CHECK_TEST_NOTATION);
CHECK(get_notations(king_castle_moves, CASTLE_BOARD) == CASTLING_MOVES_NOTATION);
CHECK(get_notations(king_bcastle_moves, CASTLE_BOARD) == BCASTLING_MOVES_NOTATION);
CHECK(get_notations(en_passant_moves, EN_PASSANT_TEST_BOARD) == EN_PASSANT_TEST_NOTATION);
CHECK(get_notations(pawn_prom_moves, PROM_PAWN_BOARD) == PROM_PAWN_NOTATION);
CHECK(get_notations(bpawn_prom_moves, PROM_BPAWN_BOARD) == PROM_BPAWN_NOTATION);
}
TEST_CASE("Test for disambiguating moves in algebraic notation", "[to_notation]"){
auto brook1_moves = get_all_moves(DISAMB_BROOK1_POS, DISAMB_BOARD);
auto brook2_moves = get_all_moves(DISAMB_BROOK2_POS, DISAMB_BOARD);
auto wrook1_moves = get_all_moves(DISAMB_WROOK1_POS, DISAMB_BOARD);
auto wrook2_moves = get_all_moves(DISAMB_WROOK2_POS, DISAMB_BOARD);
auto bishop1_moves = get_all_moves(DISAMB_BISHOP1_POS, DISAMB_BOARD);
auto bishop2_moves = get_all_moves(DISAMB_BISHOP2_POS, DISAMB_BOARD);
auto queen1_moves = get_all_moves(DISAMB_QUEEN1_POS, DISAMB_BOARD);
auto queen2_moves = get_all_moves(DISAMB_QUEEN2_POS, DISAMB_BOARD);
auto queen3_moves = get_all_moves(DISAMB_QUEEN3_POS, DISAMB_BOARD);
CHECK(get_notations(brook1_moves, DISAMB_BOARD) == DISAMB_BROOK1_NOTATION);
CHECK(get_notations(brook2_moves, DISAMB_BOARD) == DISAMB_BROOK2_NOTATION);
CHECK(get_notations(wrook1_moves, DISAMB_BOARD) == DISAMB_WROOK1_NOTATION);
CHECK(get_notations(wrook2_moves, DISAMB_BOARD) == DISAMB_WROOK2_NOTATION);
CHECK(get_notations(bishop1_moves, DISAMB_BOARD) == DISAMB_BISHOP1_NOTATION);
CHECK(get_notations(bishop2_moves, DISAMB_BOARD) == DISAMB_BISHOP2_NOTATION);
CHECK(get_notations(queen1_moves, DISAMB_BOARD) == DISAMB_QUEEN1_NOTATION);
CHECK(get_notations(queen2_moves, DISAMB_BOARD) == DISAMB_QUEEN2_NOTATION);
CHECK(get_notations(queen3_moves, DISAMB_BOARD) == DISAMB_QUEEN3_NOTATION);
}
TEST_CASE("Test for disambiguating moves, and checkmate mark (#)", "[to_notation]"){
auto check_rook_moves = get_all_moves(CHECKMATE_ROOK_POS, CHECKMATE_ROOK_BOARD);
CHECK(get_notations(check_rook_moves, CHECKMATE_ROOK_BOARD) == CHECKMATE_ROOK_NOTATION);
}
TEST_CASE("Do extra (random board tests) on notation and move generation", "[to_notation][get_all_moves]"){
auto knight_moves = get_all_moves(KNIGHT_EXTRA1_POS, EXTRA1_BOARD);
auto knight_moves2 = get_all_moves(KNIGHT_EXTRA2_POS, EXTRA2_BOARD);
CHECK(get_notations(knight_moves, EXTRA1_BOARD) == KNIGHT_EXTRA1_NOTATION);
CHECK(get_notations(knight_moves2, EXTRA2_BOARD) == KNIGHT_EXTRA2_NOTATION);
CHECK(get_to_squares(knight_moves2) == KNIGHT_EXTRA2_MOVES);
}
TEST_CASE("Test for promotions on empty squares", "[get_all_moves]"){
auto pawn_prom = get_all_moves(PAWN_PROM_BLANK_POS, PAWN_PROM_BLANK_BOARD);
CHECK(get_notations(pawn_prom, PAWN_PROM_BLANK_BOARD) == PAWN_PROM_BLANK_NOTATION);
}
TEST_CASE("Tests for check on square of queenside capture", "[get_all_moves]"){
auto cannot_queenside = get_all_moves(CASTLE_CHECK1_POS, CASTLE_CHECK1_BOARD, true, 0, 0xF);
auto cannot_queenside2 = get_all_moves(CASTLE_CHECK2_POS, CASTLE_CHECK2_BOARD, true, 0, 0xF);
auto cannot_queenside3 = get_all_moves(CASTLE_CHECK3_POS, CASTLE_CHECK3_BOARD, true, 0, 0xF);
auto cannot_queenside4 = get_all_moves(CASTLE_CHECK4_POS, CASTLE_CHECK4_BOARD, true, 0, 0xF);
CHECK(get_notations(cannot_queenside, CASTLE_CHECK1_BOARD) == CASTLE_CHECK1_NOTATION);
CHECK(get_notations(cannot_queenside2, CASTLE_CHECK2_BOARD) == CASTLE_CHECK2_NOTATION);
CHECK(get_notations(cannot_queenside3, CASTLE_CHECK3_BOARD) == CASTLE_CHECK3_NOTATION);
CHECK(get_notations(cannot_queenside4, CASTLE_CHECK4_BOARD) == CASTLE_CHECK4_NOTATION);
}
TEST_CASE("Test that king check detection is working correctly.", "[king_checked]"){
auto rook_check_moved_board = ROOK_CHECK_MOVED_BOARD;
CHECK(king_checked(rook_check_moved_board, Color::WHITE));
}
TEST_CASE("Test for add_checked_flags is working correctly.", "[get_all_moves][add_checked_flags]"){
auto rook_checked_flags = get_all_moves(ROOK_CHECK_POS, ROOK_CHECK_BOARD);
CHECK(get_notations(rook_checked_flags, ROOK_CHECK_BOARD) == ROOK_CHECK_NOTATION);
CHECK(get_checked_flags(rook_checked_flags) == ROOK_CHECK_FLAGS);
}
TEST_CASE("Test that kings cannot move backwards into check", "[get_all_moves]"){
auto king_back_checked = get_all_moves(BACK_CHECK_POS, BACK_CHECK_BOARD);
CHECK(get_to_squares(king_back_checked) == BACK_CHECK_KING_MOVES);
}

@ -0,0 +1,50 @@
#include "valid_moves.h"
#include <functions.h>
#include <constants.h>
#include <bitwise.h>
#include <chrono>
#include <iostream>
#include <vector>
#include <array>
using namespace std;
using namespace std::chrono;
#define TEST_FUNCTION(pre_func, function_with_params, number_of_times_to_run, test_number){\
high_resolution_clock::time_point ts_(test_number) = high_resolution_clock::now();\
for (int i = 0; i < (number_of_times_to_run); ++i){\
(pre_func);\
(functions_with_params);\
}\
high_resolution_clock::time_print te_(test_number) = high_resolution_clock::now();\
auto duration = duration_cast<microseconds>(te_(test_number) - ts_(test_number)).count();\
cout << "Function (functions_with_params) ran (number_of_times_to_run) times in " << duration_(test_number) << " micro seconds" << endl;
// TODO make complete, add complex scenarios.
// Test every function on their edge cases.
int main(){
// Get all moves
high_resolution_clock::time_point t1 = high_resolution_clock::now();
for (int i = 0; i < 10000000; i++){
vector<int> moves = {};
get_all_moves(Position::E8, DEFAULT_BOARD, moves);
}
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>( t2 - t1 ).count();
cout << "10,000,000 iterations of get_all_moves took " << duration << " micro seconds" << endl;
// to_notation (Rook)
high_resolution_clock::time_point t3 = high_resolution_clock::now();
std::vector<int> checkmate_rook_moves;
get_all_moves(CHECKMATE_ROOK_POS, CHECKMATE_ROOK_BOARD, checkmate_rook_moves);
for (int i = 0; i < 1000000; i++){
for (int mv : checkmate_rook_moves){
string notation = to_notation(mv, CHECKMATE_ROOK_BOARD);
}
}
high_resolution_clock::time_point t4 = high_resolution_clock::now();
auto duration2 = duration_cast<microseconds>( t4 - t3 ).count();
cout << "~15,000,000 iterations of to_notation took " << duration2 << " micro seconds" << endl;
}

@ -0,0 +1,71 @@
#include "test_functions.h"
#include <bitwise.h>
#include <vector>
#include <algorithm>
#include <array>
#include <constants.h>
#include <functions.h>
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(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(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(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(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(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(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(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(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));
}
return notations;
}

@ -0,0 +1,17 @@
#ifndef TEST_FUNCTIONS_H
#define TEST_FUNCTOPMS_H
#include <string>
#include <vector>
#include <array>
#include <constants.h>
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

@ -1,150 +0,0 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "test_boards.h"
#include <sstream>
#include <functions.h>
// 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 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, 64>> {
static std::string convert(std::array<PieceType, 64> const& board){
std::stringstream ss;
ss << "{" << std::endl;
for (int i = 0; i < 8; ++i){
for (int j = 0; j < 8; ++j){
int index = (i*8)+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::vector<Position>> {
static std::string convert(std::vector<Position> const& poss){
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();
}
};
}
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 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)));
}
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 what pieces may move where functon", "[get_possible_movers]"){
std::vector<Position> H1_possible_movers = {Position::H2, Position::G1};
CHECK(get_possible_movers(Position::H3, DEFAULT_BOARD) == H1_possible_movers);
}
TEST_CASE("Test where this piece may move to", "[get_possible_moves]"){
std::vector<Position> white_right_knight_possible_moves = {Position::H3, Position::F3};
std::vector<Position> black_A_pawn_possible_moves = {Position::A6,Position::A5};
CHECK(get_possible_moves(Position::G1, DEFAULT_BOARD) == white_right_knight_possible_moves);
CHECK(get_possible_moves(Position::A7, DEFAULT_BOARD) == black_A_pawn_possible_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);
}

@ -0,0 +1,939 @@
#include <vector>
#include <string>
#include <constants.h>
/// This is for possible moves on a default board
const std::vector<int> DEFAULT_B_A_PAWN_POSSIBLE_MOVES = {
A6, A5
};
const std::vector<int> DEFAULT_W_A_PAWN_POSSIBLE_MOVES = {
A3, A4
};
const std::vector<int> DEFAULT_W_R_KNIGHT_POSSIBLE_MOVES = {
H3, F3
};
// EMPTY
const std::vector<int> DEFAULT_W_R_ROOK_POSSIBLE_MOVES = {};
const std::vector<int> B_PAWNS_SQUARES = {
A7, B7, C7, D7, E7, F7, G7, H7
};
// END of default selections
const int KNIGHT_BLOCKED1_POS = B8;
const std::array<PieceType, 120> KNIGHT_BLOCKED1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, B_KNIGHT, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, B_PAWN, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, W_PAWN, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
// Should NOT inclde D7
const std::vector<int> KNIGHT_BLOCKED1_MOVES = {
A6, C6
};
const std::vector<int> KNIGHT_BLOCKED1_CAPTS = {
NONE, W_PAWN
};
const std::vector<std::string> KNIGHT_BLOCKED1_NOTATION = {
"Na6", "Nxc6"
};
const int BISHOP_BLOCKED1_POS = D5;
const std::array<PieceType, 120> BISHOP_BLOCKED1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, B_QUEEN, NONE , B_PAWN , NONE, W_KING, NONE, NONE, INV,
INV, NONE, NONE , NONE , NONE , NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE , W_ROOK, W_BISHOP, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE , NONE , NONE , NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE , NONE , NONE , NONE, B_KING, NONE, NONE, INV,
INV, NONE, NONE , NONE , NONE , NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE , NONE , NONE , NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
// Should NOT include A8, H8, G2, or H1
const std::vector<int> BISHOP_BLOCKED1_MOVES = {
C6, B7,
E6,
C4, B3, A2,
E4, F3
};
const std::vector<int> BISHOP_BLOCKED1_CAPTS = {
NONE, B_QUEEN,
NONE,
NONE, NONE, NONE,
NONE, B_KING,
};
const std::vector<std::string> BISHOP_BLOCKED1_NOTATION = {
"Bc6+", "Bxb7+",
"Be6",
"Bc4", "Bb3", "Ba2",
"Be4+", "Bxf3+"
};
// Should NOT include B2 (black queen) as it is obstructed by the bishop on D5
const std::vector<int> BISHOP_BLOCKED1_CAN_MOVE_TO_B_KING = {
D5
};
const int BISHOP_BLOCKED1_KING_POS = F3;
const int ROOK_BLOCKED1_POS = B7;
const std::array<PieceType, 120> ROOK_BLOCKED1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, W_ROOK, NONE , B_PAWN , NONE, B_KING, NONE, NONE, INV,
INV, NONE, NONE , NONE , NONE , NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE , B_BISHOP, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE , NONE , NONE , NONE, NONE, NONE, NONE, INV,
INV, NONE, W_KING , 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
// Should NOT include E-H2 or B3-1
const std::vector<int> ROOK_BLOCKED1_MOVES = {
A7,
B8,
C7, D7,
B6, B5, B4
};
const std::vector<int> ROOK_BLOCKED1_CAPTS = {
NONE,
NONE,
NONE, B_PAWN,
NONE, NONE, NONE
};
const std::vector<std::string> ROOK_BLOCKED1_NOTATION = {
"Ra7",
"Rb8",
"Rc7", "Rxd7+",
"Rb6", "Rb5", "Rb4"
};
const int PAWN_DIAG_TEST1_POS = E7;
const std::array<PieceType, 120> PAWN_DIAG_TEST1_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, W_QUEEN, 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, NONE, 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::vector<int> PAWN_DIAG_TEST1_MOVES = {
E6, E5, D6
};
const std::vector<int> PAWN_DIAG_TEST1_CAPTS = {
NONE, NONE, W_QUEEN
};
const std::vector<std::string> PAWN_DIAG_TEST1_NOTATION = {
"e6", "e5", "exd6"
};
// For testing the invalidating of moves because of putting own king in check
const int ROOK_CHECK_TEST_POS = D5;
const std::array<PieceType, 120> ROOK_CHECK_TEST_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, W_KING, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, W_QUEEN, B_ROOK, NONE, B_KING, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> ROOK_CHECK_TEST_MOVES = {
C5, E5
};
const int PAWN_CHECK_TEST_POS = E7;
const std::array<PieceType, 120> PAWN_CHECK_TEST_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, W_PAWN, 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, W_QUEEN, NONE, NONE, NONE,INV,
INV, W_PAWN, W_PAWN, W_PAWN, NONE, W_PAWN, W_PAWN, W_PAWN, W_PAWN,INV,
INV, W_ROOK, W_KNIGHT, W_BISHOP, NONE, 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::vector<int> PAWN_CHECK_TEST_MOVES = {E6, E5};
// These boards tests for en pessent squares.
const int EN_PASSANT_SQUARE = E6;
const int EN_PASSANT_TEST_POS = D5;
const std::array<PieceType, 120> EN_PASSANT_TEST_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, NONE, B_PAWN, B_PAWN, B_PAWN, B_PAWN,INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,INV,
INV, NONE, NONE, NONE, W_PAWN, B_PAWN, 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, NONE, 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::vector<int> EN_PASSANT_TEST_MOVES = {
D6, E6
};
const std::vector<std::string> EN_PASSANT_TEST_NOTATION = {
"d6", "dxe6e.p."
};
// Test pawn promotion
const int PROM_PAWN_POS = G7;
const std::array<PieceType, 120> PROM_PAWN_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, NONE, B_PAWN, B_PAWN, W_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, NONE, 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::vector<int> PROM_PAWN_MOVES = {
H8, H8, H8, H8,
F8, F8, F8, F8
};
const std::vector<int> PROM_PAWN_PROMS = {
W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN,
W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN
};
const std::vector<std::string> PROM_PAWN_NOTATION = {
"gxh8=N","gxh8=B","gxh8=R","gxh8=Q",
"gxf8=N","gxf8=B","gxf8=R","gxf8=Q"
};
// Black pawn promotion
const int PROM_BPAWN_POS = B2;
const std::array<PieceType, 120> PROM_BPAWN_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, NONE, 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, B_PAWN, W_PAWN, NONE, 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::vector<int> PROM_BPAWN_MOVES = {
C1, C1, C1, C1,
A1, A1, A1, A1
};
const std::vector<int> PROM_BPAWN_PROMS = {
B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN,
B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN
};
const std::vector<std::string> PROM_BPAWN_NOTATION = {
"bxc1=N","bxc1=B","bxc1=R","bxc1=Q",
"bxa1=N","bxa1=B","bxa1=R","bxa1=Q"
};
const int NO_EN_PASSANT_TEST_POS = D5;
const std::array<PieceType, 120> NO_EN_PASSANT_TEST_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, NONE, B_PAWN, B_PAWN, B_PAWN, B_PAWN, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, W_PAWN, B_PAWN, 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, NONE, 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::vector<int> NO_EN_PASSANT_TEST_MOVES = {D6};
// Castling tests
const int CASTLING_POS = E1;
const int BCASTLING_POS = E8;
const std::array<PieceType, 120> CASTLING_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, B_KING, NONE, NONE, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, W_KING, NONE, NONE, 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::vector<int> CASTLING_MOVES = {
D2, E2, F2, F1,
D1, G1, C1
};
const std::vector<int> BCASTLING_MOVES = {
D7, E7, F7, F8, D8, G8, C8
};
const std::vector<std::string> CASTLING_MOVES_NOTATION = {
"Kd2", "Ke2", "Kf2", "Kf1",
"Kd1", "O-O", "O-O-O"
};
const std::vector<std::string> BCASTLING_MOVES_NOTATION = {
"Kd7", "Ke7", "Kf7",
"Kf8", "Kd8", "O-O", "O-O-O"
};
const std::array<PieceType, 120> CASTLING_CHECK_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, B_KING, NONE, NONE, B_ROOK, INV,
INV, NONE, NONE, NONE, NONE, W_BISHOP, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, W_KING, NONE, NONE, 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<PieceType, 120> BLACK_CHECK_BOARD1 = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, NONE, B_KING, NONE, B_ROOK, INV,
INV, NONE, NONE, NONE, NONE, W_BISHOP, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, W_KING, NONE, NONE, 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<PieceType, 120> BLACK_CHECK_BOARD2 = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, B_KING, NONE, NONE, NONE, B_ROOK, INV,
INV, NONE, NONE, NONE, NONE, W_BISHOP, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, W_KING, NONE, NONE, W_ROOK, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const int BLACK_CHECK_POS1 = D8;
const int BLACK_CHECK_POS2 = F8;
const std::vector<int> BCASTLING_CHECK_MOVES = {
D7, E7, F7
};
// Check that the dumb_move function actually moves the rook and the king to the right squares.
const int CASTLE_FROM_POS = E1;
const int CASTLE_TO_POS = G1;
const int BCASTLE_FROM_POS = E8;
const int BCASTLE_TO_POS = G8;
const int CASTLE_FROM_QPOS = E1;
const int CASTLE_TO_QPOS = C1;
const int BCASTLE_FROM_QPOS = E8;
const int BCASTLE_TO_QPOS = C8;
const std::array<PieceType, 120> CASTLE_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, B_KING, NONE, NONE, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, W_KING, NONE, NONE, 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<PieceType, 120> CASTLE_BOARD_WK = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, B_KING, NONE, NONE, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, NONE, W_ROOK, W_KING, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::array<PieceType, 120> CASTLE_BOARD_BK = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, NONE, B_ROOK, B_KING, 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, 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_ROOK, NONE, NONE, NONE, W_KING, NONE, NONE, 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<PieceType, 120> CASTLE_BOARD_WQ = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, B_KING, NONE, NONE, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, W_KING, W_ROOK, NONE, NONE, NONE, 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<PieceType, 120> CASTLE_BOARD_BQ = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, B_KING, B_ROOK, NONE, NONE, NONE, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, W_KING, NONE, NONE, W_ROOK, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
// Check that castling is disallowed when there is a piece blocking the rook queenside.
const int CASTLE_BLOCKED_POS = E1;
const std::array<PieceType, 120> CASTLE_BLOCKED_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, B_KING, NONE, NONE, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, W_KNIGHT, NONE, NONE, W_KING, NONE, NONE, 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::vector<int> CASTLE_BLOCKED_MOVES = {
D2, E2, F2,
F1, D1, G1
};
const int CASTLE_BLOCKED_QPOS = E8;
const std::array<PieceType, 120> CASTLE_BLOCKED_QBOARD = {
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, NONE, NONE, B_KING, NONE, NONE, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, W_KNIGHT, NONE, NONE, W_KING, NONE, NONE, 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::vector<int> CASTLE_BLOCKED_QMOVES = {
D7, E7, F7,
F8, D8, G8
};
// Check tests for king
const int KING_CHECK_TEST_POS = D6;
const int KING_CHECK_ROOK_POS = D5;
const std::array<PieceType, 120> KING_CHECK_TEST_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, W_KING, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, B_ROOK, NONE, NONE, B_KING, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, W_KING, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> KING_CHECK_TEST_MOVES = {
C7, E7,
D5,
E6, C6
};
const std::vector<int> KING_CHECK_TEST_CAPTS = {
NONE, NONE,
B_ROOK,
NONE, NONE
};
const std::vector<std::string> KING_CHECK_TEST_NOTATION = {
"Kc7", "Ke7",
"Kxd5",
"Ke6", "Kc6"
};
const std::vector<int> KING_CHECK_ROOK_MOVES = {
C5, B5, A5,
D6, E5, F5,
D4, D3, D2, D1
};
// This checks that en passant moves are handled correctly
// by the dumb_move method.
const int EN_PASSANT_EN_PASSANT_SQUARE = D7;
const int EN_PASSANT_CHECK_POS = E6;
const std::array<PieceType, 120> EN_PASSANT_CHECK_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, B_QUEEN, NONE, NONE, B_PAWN, W_PAWN, NONE, NONE, W_KING, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, B_KING, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::array<PieceType, 120> EN_PASSANT_CHECK_MOVED_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, W_PAWN, NONE, NONE, NONE, NONE, INV,
INV, B_QUEEN, NONE, NONE, NONE, NONE, NONE, NONE, W_KING, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, B_KING, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> EN_PASSANT_CHECKED_MOVES = {
E7
};
const int EN_PASSANT_EN_PASSANT_SQUARE1 = F7;
const int EN_PASSANT_CHECK_POS1 = E6;
const std::array<PieceType, 120> EN_PASSANT_CHECK_BOARD1 = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, W_PAWN, B_PAWN, 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, W_KING, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, B_KING, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::array<PieceType, 120> EN_PASSANT_CHECK_MOVED_BOARD1 = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, W_PAWN, 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, NONE, NONE, W_KING, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, B_KING, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const int EN_PASSANT_EN_PASSANT_SQUARE2 = D2;
const int EN_PASSANT_CHECK_POS2 = C3;
const std::array<PieceType, 120> EN_PASSANT_CHECK_BOARD2 = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, W_KING, NONE, NONE, NONE, NONE, NONE, B_KING, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, B_PAWN, W_PAWN, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::array<PieceType, 120> EN_PASSANT_CHECK_MOVED_BOARD2 = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, W_KING, NONE, NONE, NONE, NONE, NONE, B_KING, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, B_PAWN, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const int EN_PASSANT_EN_PASSANT_SQUARE3 = D2;
const int EN_PASSANT_CHECK_POS3 = E3;
const std::array<PieceType, 120> EN_PASSANT_CHECK_BOARD3 = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, B_KING, NONE, W_KING, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, W_PAWN, B_PAWN, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::array<PieceType, 120> EN_PASSANT_CHECK_MOVED_BOARD3 = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, B_KING, NONE, W_KING, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, B_PAWN, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
// This tests for disambiguating moves with algebraic notation
const int DISAMB_BISHOP1_POS = D6;
const int DISAMB_BISHOP2_POS = A7;
const int DISAMB_BROOK1_POS = D8;
const int DISAMB_BROOK2_POS = H8;
const int DISAMB_WROOK1_POS = A5;
const int DISAMB_WROOK2_POS = A1;
const int DISAMB_QUEEN1_POS = E4;
const int DISAMB_QUEEN2_POS = H4;
const int DISAMB_QUEEN3_POS = H1;
const std::array<PieceType, 120> DISAMB_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, B_ROOK, NONE, NONE, NONE, B_ROOK, INV,
INV, B_BISHOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, B_BISHOP, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, W_QUEEN, NONE, NONE, W_QUEEN, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, W_ROOK, NONE, NONE, NONE, NONE, NONE, NONE, W_QUEEN, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<std::string> DISAMB_BROOK1_NOTATION = {"Rc8", "Rb8", "Ra8", "Rde8", "Rdf8", "Rdg8", "Rd7"};
const std::vector<std::string> DISAMB_BROOK2_NOTATION = {"Rhg8", "Rhf8", "Rhe8", "Rh7", "Rh6", "Rh5", "Rxh4"};
const std::vector<std::string> DISAMB_WROOK1_NOTATION = {"Ra6", "Rxa7", "Rb5", "Rc5", "Rd5", "Re5", "Rf5", "Rg5", "Rh5", "R5a4", "R5a3", "R5a2"};
const std::vector<std::string> DISAMB_WROOK2_NOTATION = {"R1a2", "R1a3", "R1a4", "Rb1", "Rc1", "Rd1", "Re1", "Rf1", "Rg1"};
const std::vector<std::string> DISAMB_BISHOP1_NOTATION = {"Bc7", "Bdb8", "Be7", "Bf8", "Bdc5", "Bb4", "Ba3", "Be5", "Bf4", "Bg3", "Bh2"};
const std::vector<std::string> DISAMB_BISHOP2_NOTATION = {"Bab8", "Bb6", "Bac5", "Bd4", "Be3", "Bf2", "Bg1"};
const std::vector<std::string> DISAMB_QUEEN1_NOTATION = {"Qd4", "Qc4", "Qb4", "Qa4", "Qe5", "Qe6", "Qee7", "Qe8", "Qef4", "Qeg4", "Qe3", "Qe2", "Qe4e1", "Qd5", "Qc6", "Qb7", "Qa8", "Qf5", "Qg6", "Qeh7", "Qd3", "Qc2", "Qeb1", "Qef3", "Qeg2"};
const std::vector<std::string> DISAMB_QUEEN2_NOTATION = {"Qhg4", "Qhf4", "Qh5", "Qh6", "Qhh7", "Qxh8", "Q4h3", "Q4h2", "Qg5", "Qf6", "Qhe7", "Qxd8", "Qg3", "Qf2", "Qh4e1"};
const std::vector<std::string> DISAMB_QUEEN3_NOTATION = {"Qg1", "Qf1", "Qh1e1", "Qd1", "Qc1", "Qhb1", "Q1h2", "Q1h3", "Qhg2", "Qhf3"};
// CHeck that converting moves to algebraic notation have checkmate marks (#)
const int CHECKMATE_ROOK_POS = D8;
const std::array<PieceType, 120> CHECKMATE_ROOK_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, B_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, B_ROOK, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, W_KING, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<std::string> CHECKMATE_ROOK_NOTATION = {
"Rc8", "Rdb8", "Ra8",
"Re8", "Rf8", "Rg8+", "Rh8",
"Rd7", "Rd6", "Rd5", "Rd4", "Rd3", "Rdd2", "Rd1#"
};
// Extra checks on valid moves
const int KNIGHT_EXTRA1_POS = G5;
const std::array<PieceType, 120> EXTRA1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, B_BISHOP, B_QUEEN, B_KING, B_BISHOP, B_KNIGHT, B_ROOK, INV,
INV, NONE, B_PAWN, B_PAWN, B_PAWN, NONE, NONE, B_PAWN, B_PAWN, INV,
INV, NONE, NONE, W_KNIGHT, NONE, NONE, B_PAWN, NONE, NONE, INV,
INV, B_PAWN, NONE, NONE, NONE, B_PAWN, W_PAWN, W_KNIGHT, 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, NONE, W_PAWN, W_PAWN, INV,
INV, W_ROOK, W_KNIGHT, W_BISHOP, W_QUEEN, W_KING, W_BISHOP, NONE, 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::vector<std::string> KNIGHT_EXTRA1_NOTATION = {
"Ne6", "Nf7", "Nxh7", "Ne4", "Nf3", "Nh3"
};
const int KNIGHT_EXTRA2_POS = D4;
const std::array<PieceType, 120> EXTRA2_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, NONE, B_PAWN, B_PAWN, B_PAWN, INV,
INV, NONE, NONE, NONE, NONE, B_PAWN, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, W_KNIGHT, 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::vector<int> KNIGHT_EXTRA2_MOVES = {
B5, C6, E6, F5, B3, F3
};
const std::vector<std::string> KNIGHT_EXTRA2_NOTATION = {
"Nb5", "Nc6", "Nxe6", "Nf5", "Nb3", "Ndf3"
};
const std::array<PieceType, 120> EXTRA3_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, W_KNIGHT, 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
};
// Tests that a pawn has promotion moves, even if there are only blank sqaures to move to.
const int PAWN_PROM_BLANK_POS = D7;
const std::array<PieceType, 120> PAWN_PROM_BLANK_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, W_PAWN, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, B_ROOK, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, B_KING, NONE, W_KING, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<std::string> PAWN_PROM_BLANK_NOTATION = {
"d8=N", "d8=B", "d8=R", "d8=Q"
};
// This is another test for castling.
// As of the writing of this, the castling works even if the king is in check
// in the square it moves to... WTF?
const int CASTLE_CHECK1_POS = E8;
const std::array<PieceType, 120> CASTLE_CHECK1_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, B_KING, B_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, B_PAWN, B_PAWN, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, W_BISHOP, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, W_KING, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<std::string> CASTLE_CHECK1_NOTATION = {
"Kd8"
};
const int CASTLE_CHECK2_POS = E8;
const std::array<PieceType, 120> CASTLE_CHECK2_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, NONE, B_KING, B_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, B_QUEEN, B_PAWN, B_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, W_KNIGHT, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, W_KING, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<std::string> CASTLE_CHECK2_NOTATION = {
"Kd8"
};
const int CASTLE_CHECK3_POS = E8;
const std::array<PieceType, 120> CASTLE_CHECK3_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, B_PAWN, B_KING, NONE, NONE, B_ROOK, INV,
INV, NONE, NONE, NONE, B_QUEEN, B_PAWN, B_PAWN, 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, W_ROOK, 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, W_KING, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<std::string> CASTLE_CHECK3_NOTATION = {
"Kf8"
};
const int CASTLE_CHECK4_POS = E8;
const std::array<PieceType, 120> CASTLE_CHECK4_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, B_ROOK, NONE, NONE, B_PAWN, B_KING, NONE, NONE, B_ROOK, INV,
INV, NONE, NONE, NONE, B_QUEEN, B_PAWN, B_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, W_KNIGHT, W_ROOK, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, W_KING, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<std::string> CASTLE_CHECK4_NOTATION = {
"Kf8"
};
// This is a check that moves are being marked as "check moves" poperly
const int ROOK_CHECK_POS = H3;
const int ROOK_CHECK_MOVED_POS = H1;
const int ROOK_CHECK_KING_POS = G1;
const std::array<PieceType, 120> ROOK_CHECK_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, B_PAWN, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, B_PAWN, B_ROOK, INV,
INV, NONE, NONE, NONE, NONE, NONE, W_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, W_ROOK, W_KING, NONE, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::array<PieceType, 120> ROOK_CHECK_MOVED_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, NONE, NONE, NONE, NONE, NONE, NONE, NONE, B_PAWN, INV,
INV, NONE, NONE, NONE, NONE, NONE, NONE, B_PAWN, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, W_PAWN, NONE, NONE, INV,
INV, NONE, NONE, NONE, NONE, NONE, W_ROOK, W_KING, B_ROOK, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<std::string> ROOK_CHECK_NOTATION = {
"Rh2", "Rh1+"
};
const std::vector<int> ROOK_CHECK_MOVED_MOVES = {
H3, H2, G1
};
const std::vector<int> ROOK_CHECK_MOVED_CAPTURES = {
W_KING, NONE, NONE
};
const std::vector<int> ROOK_CHECK_FLAGS = {
0, 1
};
// This tests that kings cannot move backward into check from check
const int BACK_CHECK_POS = E6;
const std::array<PieceType, 120> BACK_CHECK_BOARD = {
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, 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, B_KING, 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, W_ROOK, 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, INV, INV, INV, INV, INV, INV, INV, INV, INV,
INV, INV, INV, INV, INV, INV, INV, INV, INV, INV
};
const std::vector<int> BACK_CHECK_KING_MOVES = {
D7, F7,
D5, F5,
F6, D6
};
Loading…
Cancel
Save