Add en passant as possible moves. Cannot move yet due to dumb_move being.. dumb. Seperate custom printing out of main test file.

master
Tait Hoyem 5 years ago
parent fb8481bf6b
commit 792d0cc5ee

@ -42,8 +42,9 @@ void _add_if_not_blocked(int x, int y, std::unordered_set<Position> *pns, std::a
// 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 x, int y, std::unordered_set<Position> *pns, std::array<PieceType, 64> board, Color color_of_piece, Color color_of_opposite){
if (is_valid_position(x, y) && _xy_is_color(x, y, board, color_of_opposite)){
void _pawn_diag_add_if_not_blocked(int x, int y, std::unordered_set<Position> *pns, std::array<PieceType, 64> board, Color color_of_piece, Color color_of_opposite, Position en_passant){
if (is_valid_position(x, y) && (_xy_is_color(x, y, board, color_of_opposite) ||
pair_to_pos(x, y) == en_passant)){
pns->insert(pair_to_pos(x, y));
}
}
@ -113,18 +114,19 @@ void _get_all_moves_king(int x, int y, std::unordered_set<Position> *pns, std::a
_add_if_not_blocked(x+1, y, pns, board, pc, rc);
_add_if_not_blocked(x-1, y, pns, board, pc, rc);
}
void _get_all_moves_pawn(int x, int y, std::unordered_set<Position> *pns, std::array<PieceType, 64> board, Color pc, Color rc){
void _get_all_moves_pawn(int x, int y, std::unordered_set<Position> *pns, std::array<PieceType, 64> board, Color pc, Color rc, Position en_passant){
// if it's white use different offsets, and pawn starting rank
int offset2 = pc==Color::WHITE?2:-2;
int offset1 = pc==Color::WHITE?1:-1;
int pawn_rank = pc==Color::WHITE?1:6;
int default_pawn_rank = pc==Color::WHITE?1:6;
bool *free_to_double_move = new bool(true);
_pawn_add_if_not_blocked(x, y+offset1, pns, board, pc, rc, free_to_double_move);
if (y == pawn_rank){ // If on second rank
if (y == default_pawn_rank){ // If on second/seventh rank
_pawn_add_if_not_blocked(x, y+offset2, pns, board, pc, rc, free_to_double_move);
}
_pawn_diag_add_if_not_blocked(x+1, y+offset1, pns, board, pc, rc);
_pawn_diag_add_if_not_blocked(x-1, y+offset1, pns, board, pc, rc);
_pawn_diag_add_if_not_blocked(x+1, y+offset1, pns, board, pc, rc, en_passant);
_pawn_diag_add_if_not_blocked(x-1, y+offset1, pns, board, pc, rc, en_passant);
}

@ -40,7 +40,7 @@ const std::array<char, 13> CHESS_CHARS = {
// 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
A8, B8, C8, D8, E8, F8, G8, H8, A7, B7, C7, D7, E7, F7, G7, H7, A6, B6, C6, D6, E6, F6, G6, H6, A5, B5, C5, D5, E5, F5, G5, H5, A4, B4, C4, D4, E4, F4, G4, H4, A3, B3, C3, D3, E3, F3, G3, H3, A2, B2, C2, D2, E2, F2, G2, H2, A1, B1, C1, D1, E1, F1, G1, H1, NA
};
// This allows the printing of Position enum variables in the tests. It matches the variables to strings.

@ -101,7 +101,7 @@ std::unordered_set<Position> get_possible_moves(Position pn, std::array<PieceTyp
return get_all_moves(pn, board);
}
std::unordered_set<Position> get_all_moves(Position pn, std::array<PieceType, 64> board, bool recursive){
std::unordered_set<Position> get_all_moves(Position pn, std::array<PieceType, 64> board, bool recursive, Position en_passant){
PieceType pt = board[pn];
std::unordered_set<Position> pns;
int x = pos_to_pair(pn).first;
@ -132,7 +132,7 @@ std::unordered_set<Position> get_all_moves(Position pn, std::array<PieceType, 64
break;
case PieceType::B_PAWN:
case PieceType::W_PAWN:
_get_all_moves_pawn(x, y, &pns, board, color_of_piece, color_of_opponent);
_get_all_moves_pawn(x, y, &pns, board, color_of_piece, color_of_opponent, en_passant);
break;
default:
break;

@ -43,7 +43,7 @@ std::unordered_set<Position> get_possible_movers(Position pn, std::array<PieceTy
std::unordered_set<Position> get_possible_moves(Position pn, std::array<PieceType, 64> pt);
// Get all moves for piece in Position pn.
std::unordered_set<Position> get_all_moves(Position pn, std::array<PieceType, 64> pt, bool recursive=true);
std::unordered_set<Position> get_all_moves(Position pn, std::array<PieceType, 64> pt, bool recursive=true, Position en_pessant=Position::NA);
// Get all moves for a list of Pieces given as std::vector<Position>
// I'm not testing this because it's literally just a for loop and the above function.
std::vector<std::unordered_set<Position>> get_all_moves_vec(std::vector<Position> v_pns, std::array<PieceType, 64> board);

@ -3,5 +3,8 @@ defualt: build
catch_main.o:
g++ -w -c -o catch_main.o catch_main.cpp
build: catch_main.o
g++ -std=c++11 -ggdb -w -I../src/ -o tests.out ../src/functions.cpp catch_main.o tests_main.cpp
custom_printing.o:
g++ -w -I../src/ -c -o custom_printing.o custom_printing.cpp
build: catch_main.o custom_printing.o
g++ -std=c++11 -ggdb -w -I../src/ -o tests.out ../src/functions.cpp catch_main.o custom_printing.o tests_main.cpp

@ -0,0 +1,95 @@
#include "catch.hpp"
#include <constants.h>
#include <sstream>
#include <unordered_set>
// For some retarted reason, I need to implement the printing of pairs, otherwise in the test outputs they show up as {?}
// Also override default printing for Positions so it prints the value (e.g. 32), then, in parenthasies, the location (e.g. A4).
// Example: A4(32)
namespace Catch {
template<>
struct StringMaker<std::pair<int, int>> {
static std::string convert(std::pair<int, int> const& p){
std::stringstream ss;
ss << "{ " << p.first << ", " << p.second << " }";
return ss.str();
}
};
template<>
struct StringMaker<Position> {
static std::string convert(Position const& p){
std::stringstream ss;
ss << (int) p << "(" << POSITION_STRING[p] << ")";
return ss.str();
}
};
// This override makes sure that Color enum variables are printed properly
template<>
struct StringMaker<Color> {
static std::string convert(Color const& c){
std::stringstream ss;
if (c==Color::WHITE) ss << "white";
if (c==Color::BLACK) ss << "black";
if (c==Color::NO_COLOR) ss << "N/A";
return ss.str();
}
};
// This prints all board comparisons in a readable fashion. Using the string name of the pieces, and newlines to seperate them.
template<>
struct StringMaker<std::array<PieceType, 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::unordered_set<Position>> {
static std::string convert(std::unordered_set<Position> const& uo_poss){
std::vector<Position> poss(uo_poss.begin(), uo_poss.end());
std::stringstream ss;
std::string files = " A B C D E F G H";
ss << "{ {" << std::endl;
ss << files << std::endl;
for (int i = 0; i < 8; ++i){
ss << 8-i << "|";
for (int j = 0; j < 8; ++j){
int index = (i*8)+j;
// This part loops through all positions in the list and checks if it contains the current index.
bool part_of_poss = false;
for (Position p : poss){
if (index == p) {
part_of_poss = true;
break;
}
}
// Justin, this is how this oporator works.
// (if) part_of_poss ?(then) do this :(else) do that.
part_of_poss ? ss << "* " : ss << " ";
}
ss << "|" << 8-i;
ss << std::endl;
}
ss << files << std::endl;
ss << "}" << std::endl;
ss << "," << std::endl;
ss << "{ ";
for (int pi = 0; pi < poss.size(); ++pi){
pi == poss.size()-1 ? ss << poss[pi] << "(" << POSITION_STRING[poss[pi]] << ")" : ss << poss[pi] << "(" << POSITION_STRING[poss[pi]] << "), ";
}
ss << " } }" << std::endl;
return ss.str();
}
};
}

@ -1,98 +1,10 @@
#include "catch.hpp"
#include "test_boards.h"
#include "valid_moves.h"
#include "custom_printing.cpp"
#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 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, 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::unordered_set<Position>> {
static std::string convert(std::unordered_set<Position> const& uo_poss){
std::vector<Position> poss(uo_poss.begin(), uo_poss.end());
std::stringstream ss;
std::string files = " A B C D E F G H";
ss << "{ {" << std::endl;
ss << files << std::endl;
for (int i = 0; i < 8; ++i){
ss << 8-i << "|";
for (int j = 0; j < 8; ++j){
int index = (i*8)+j;
// This part loops through all positions in the list and checks if it contains the current index.
bool part_of_poss = false;
for (Position p : poss){
if (index == p) {
part_of_poss = true;
break;
}
}
// Justin, this is how this oporator works.
// (if) part_of_poss ?(then) do this :(else) do that.
part_of_poss ? ss << "* " : ss << " ";
}
ss << "|" << 8-i;
ss << std::endl;
}
ss << files << std::endl;
ss << "}" << std::endl;
ss << "," << std::endl;
ss << "{ ";
for (int pi = 0; pi < poss.size(); ++pi){
pi == poss.size()-1 ? ss << poss[pi] << "(" << POSITION_STRING[poss[pi]] << ")" : ss << poss[pi] << "(" << POSITION_STRING[poss[pi]] << "), ";
}
ss << " } }" << std::endl;
return ss.str();
}
};
}
const std::array<PieceType, 64> TEST_MOVES = {
W_QUEEN, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
@ -237,5 +149,9 @@ TEST_CASE("Test that moves that put king in check are not returned", "[get_all_m
CHECK(get_all_moves(ROOK_CHECK_TEST_POS, ROOK_CHECK_TEST_BOARD) == ROOK_CHECK_TEST_MOVES);
CHECK(get_all_moves(PAWN_CHECK_TEST_POS, PAWN_CHECK_TEST_BOARD) == PAWN_CHECK_TEST_MOVES);
CHECK(get_all_moves(PAWN_DIAG_TEST1_POS, PAWN_DIAG_TEST1_BOARD) == PAWN_DIAG_TEST1_MOVES);
}
TEST_CASE("Tests for en pessant squares.", "[get_all_moves]"){
CHECK(get_all_moves(EN_PASSANT_TEST_POS, EN_PASSANT_TEST_BOARD, false, EN_PASSANT_SQUARE) == EN_PASSANT_TEST_MOVES);
CHECK(get_all_moves(NO_EN_PASSANT_TEST_POS, NO_EN_PASSANT_TEST_BOARD) == NO_EN_PASSANT_TEST_MOVES);
}

@ -124,3 +124,34 @@ const std::array<PieceType, 64> PAWN_CHECK_TEST_BOARD = {
W_ROOK, W_KNIGHT, W_BISHOP, NONE, W_KING, W_BISHOP, W_KNIGHT, W_ROOK
};
const std::unordered_set<Position> PAWN_CHECK_TEST_MOVES = {E6, E5};
// These boards tests for en pessent squares.
const Position EN_PASSANT_SQUARE = E6;
const Position EN_PASSANT_TEST_POS = D5;
const std::array<PieceType, 64> EN_PASSANT_TEST_BOARD = {
B_ROOK, B_KNIGHT, B_BISHOP, B_QUEEN, B_KING, B_BISHOP, B_KNIGHT, B_ROOK,
B_PAWN, B_PAWN, B_PAWN, NONE, B_PAWN, B_PAWN, B_PAWN, B_PAWN,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
NONE, NONE, NONE, W_PAWN, B_PAWN, 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, NONE, W_PAWN, W_PAWN, W_PAWN, W_PAWN,
W_ROOK, W_KNIGHT, W_BISHOP, W_QUEEN, W_KING, W_BISHOP, W_KNIGHT, W_ROOK
};
const std::unordered_set<Position> EN_PASSANT_TEST_MOVES = {
E6, D6
};
const Position NO_EN_PASSANT_TEST_POS = D5;
const std::array<PieceType, 64> NO_EN_PASSANT_TEST_BOARD = {
B_ROOK, B_KNIGHT, B_BISHOP, B_QUEEN, B_KING, B_BISHOP, B_KNIGHT, B_ROOK,
B_PAWN, B_PAWN, B_PAWN, NONE, B_PAWN, B_PAWN, B_PAWN, B_PAWN,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
NONE, NONE, NONE, W_PAWN, B_PAWN, 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, NONE, W_PAWN, W_PAWN, W_PAWN, W_PAWN,
W_ROOK, W_KNIGHT, W_BISHOP, W_QUEEN, W_KING, W_BISHOP, W_KNIGHT, W_ROOK
};
const std::unordered_set<Position> NO_EN_PASSANT_TEST_MOVES = {D6};

Loading…
Cancel
Save