Skip to content

Commit

Permalink
Merge pull request #126 from dmeybohm/revert-125-revert-124-consolida…
Browse files Browse the repository at this point in the history
…te-en-passant

Revert "Revert "Consolidate en passant state to 5 bits""
  • Loading branch information
dmeybohm authored May 10, 2024
2 parents 5fa686d + 2854504 commit e4d3244
Show file tree
Hide file tree
Showing 12 changed files with 96 additions and 107 deletions.
10 changes: 4 additions & 6 deletions engine/src/board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,14 @@ namespace wisdom
string castled_black = castledString (Color::Black);

string both_castled = castled_white + castled_black;
if (both_castled.length() == 0)
if (both_castled.empty())
both_castled = "-";

output += both_castled;

auto en_passant_targets = getEnPassantTargets();
if (en_passant_targets[Color_Index_White] != nullopt)
output += " " + wisdom::asString (*en_passant_targets[Color_Index_White]) + " ";
else if (en_passant_targets[Color_Index_Black] != nullopt)
output += " " + wisdom::asString (*en_passant_targets[Color_Index_Black]) + " ";
auto en_passant_target = getEnPassantTarget();
if (en_passant_target != nullopt)
output += " " + wisdom::asString (en_passant_target->coord) + " ";
else
output += " - ";

Expand Down
18 changes: 6 additions & 12 deletions engine/src/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ namespace wisdom

[[nodiscard]] auto isEnPassantVulnerable (Color who) const noexcept -> bool
{
return my_code.enPassantTarget (who) != nullopt;
auto target = my_code.enPassantTarget();
return target.has_value() && target->vulnerable_color == who;
}

[[nodiscard]] auto getCurrentTurn() const -> Color
Expand All @@ -156,17 +157,10 @@ namespace wisdom
}

[[nodiscard]] auto
getEnPassantTarget (Color who) const noexcept
-> optional<Coord>
getEnPassantTarget() const noexcept
-> optional<EnPassantTarget>
{
return my_code.enPassantTarget (who);
}

[[nodiscard]] auto
getEnPassantTargets() const noexcept
-> EnPassantTargets
{
return my_code.enPassantTargets();
return my_code.enPassantTarget();
}

[[nodiscard]] auto getBoardCode() const -> BoardCode
Expand Down Expand Up @@ -194,7 +188,7 @@ namespace wisdom
auto applyForEnPassant (Color who, Coord src, Coord dst) noexcept -> ColoredPiece;
void updateEnPassantEligibility (Color who, ColoredPiece src_piece, Move move) noexcept;
void setEnPassantTarget (Color who, Coord target) noexcept;
void clearEnPassantTargets() noexcept;
void clearEnPassantTarget() noexcept;

[[nodiscard]] auto getCastlingRookMove (Move move, Color who) const -> Move;
void applyForCastlingMove (
Expand Down
5 changes: 4 additions & 1 deletion engine/src/board_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ namespace wisdom

void BoardBuilder::setEnPassantTarget (Color vulnerable_color, const string& coord_str)
{
my_en_passant_targets[colorIndex (vulnerable_color)] = coordParse (coord_str);
my_en_passant_target = {
.coord = coordParse (coord_str),
.vulnerable_color = vulnerable_color
};
}

void BoardBuilder::setCastling (Color who, CastlingEligibility state)
Expand Down
20 changes: 9 additions & 11 deletions engine/src/board_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ namespace wisdom

static auto fromDefaultPosition() -> BoardBuilder;

static auto fromRandomPosition() -> BoardBuilder;

[[nodiscard]] static constexpr auto emptySquares() -> array<ColoredPiece, Num_Squares>
[[nodiscard]] static constexpr auto emptySquares()
-> array<ColoredPiece, Num_Squares>
{
array<ColoredPiece, Num_Squares> result {};
std::fill (std::begin (result), std::end (result), Piece_And_Color_None);
Expand Down Expand Up @@ -88,9 +87,11 @@ namespace wisdom
return my_current_turn;
}

[[nodiscard]] auto getEnPassantTargets() const -> array<optional<Coord>, Num_Players>
[[nodiscard]] auto
getEnPassantTarget() const
-> optional<EnPassantTarget>
{
return my_en_passant_targets;
return my_en_passant_target;
}

[[nodiscard]] auto getCastleState (Color who) const -> CastlingEligibility
Expand Down Expand Up @@ -141,15 +142,12 @@ namespace wisdom
nullopt
};

array<optional<Coord>, Num_Players> my_en_passant_targets {
nullopt,
nullopt
};

array<optional<Coord>, Num_Players> my_king_positions {
array<optional<Coord>, Num_Players> my_king_positions {
nullopt,
nullopt
};

optional<EnPassantTarget> my_en_passant_target { nullopt };
};

}
30 changes: 14 additions & 16 deletions engine/src/board_code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,17 @@ namespace wisdom
auto current_turn = board.getCurrentTurn();
setCurrentTurn (current_turn);

auto en_passant_targets = board.getEnPassantTargets();
if (en_passant_targets[Color_Index_White] != nullopt)
auto en_passant_target = board.getEnPassantTarget();
if (en_passant_target != nullopt)
{
setEnPassantTarget (Color::White, *en_passant_targets[Color_Index_White]);
}
else if (en_passant_targets[Color_Index_Black] != nullopt)
{
setEnPassantTarget (Color::Black, *en_passant_targets[Color_Index_Black]);
setEnPassantTarget (
en_passant_target->vulnerable_color,
en_passant_target->coord
);
}
else
{
clearEnPassantTargets ();
clearEnPassantTarget();
}

setCastleState (Color::White, board.getCastlingEligibility (Color::White));
Expand All @@ -69,18 +68,17 @@ namespace wisdom
auto current_turn = builder.getCurrentTurn();
result.setCurrentTurn (current_turn);

auto en_passant_targets = builder.getEnPassantTargets();
if (en_passant_targets[Color_Index_White] != nullopt)
{
result.setEnPassantTarget (Color::White, *en_passant_targets[Color_Index_White]);
}
else if (en_passant_targets[Color_Index_Black] != nullopt)
auto en_passant_target = builder.getEnPassantTarget();
if (en_passant_target.has_value())
{
result.setEnPassantTarget (Color::Black, *en_passant_targets[Color_Index_Black]);
result.setEnPassantTarget (
en_passant_target->vulnerable_color,
en_passant_target->coord
);
}
else
{
result.clearEnPassantTargets();
result.clearEnPassantTarget();
}

result.setCastleState (Color::White, builder.getCastleState (Color::White));
Expand Down
63 changes: 27 additions & 36 deletions engine/src/board_code.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

namespace wisdom
{
using EnPassantTargets = array<optional<Coord>, Num_Players>;

using BoardHashCode = std::uint64_t;

class Board;
Expand Down Expand Up @@ -55,14 +53,14 @@ namespace wisdom
enum MetadataBits : std::size_t
{
CURRENT_TURN_BIT = 0,
EN_PASSANT_WHITE_TARGET = 1,
EN_PASSANT_BLACK_TARGET = 5,
CASTLING_STATE_WHITE_TARGET = 9,
CASTLING_STATE_BLACK_TARGET = 12,
EN_PASSANT_TARGET_BIT = 1,
CASTLING_STATE_WHITE_BIT = 7,
CASTLING_STATE_BLACK_BIT = 10,
CURRENT_TURN_MASK = 0b1,
EN_PASSANT_MASK = 0b11111111,
EN_PASSANT_MASK = 0b11111,
CASTLE_ONE_COLOR_MASK = 0b11,
EN_PASSANT_PRESENT = 0b1000,
EN_PASSANT_IS_WHITE = 0b10000,
};

public:
Expand Down Expand Up @@ -100,10 +98,10 @@ namespace wisdom

void setEnPassantTarget (Color color, Coord coord) noexcept
{
std::size_t target_bit_shift = color == Color::White
? EN_PASSANT_WHITE_TARGET
: EN_PASSANT_BLACK_TARGET;
auto coord_bits = coord.column<std::size_t>() | EN_PASSANT_PRESENT;
std::size_t target_bit_shift = EN_PASSANT_TARGET_BIT;
auto coord_bits = coord.column<std::size_t>()
| EN_PASSANT_PRESENT
| (color == Color::White ? EN_PASSANT_IS_WHITE : 0);
coord_bits <<= target_bit_shift;

assert (
Expand All @@ -113,37 +111,41 @@ namespace wisdom

// clear both targets initially. There can be only one at a given time.
auto metadata = getMetadataBits();
metadata &= ~(EN_PASSANT_MASK << EN_PASSANT_WHITE_TARGET);
metadata &= ~(EN_PASSANT_MASK << EN_PASSANT_TARGET_BIT);
metadata |= coord_bits;
setMetadataBits (metadata);
}

void clearEnPassantTargets() noexcept
void clearEnPassantTarget() noexcept
{
auto metadata = getMetadataBits();
metadata &= ~(EN_PASSANT_MASK << EN_PASSANT_WHITE_TARGET);
metadata &= ~(EN_PASSANT_MASK << EN_PASSANT_TARGET_BIT);
setMetadataBits (metadata);
}

[[nodiscard]] auto
enPassantTarget (Color vulnerable_color) const noexcept
-> optional<Coord>
enPassantTarget () const noexcept
-> optional<EnPassantTarget>
{
auto target_bits = getMetadataBits();
auto target_bit_shift = vulnerable_color == Color::White
? EN_PASSANT_WHITE_TARGET
: EN_PASSANT_BLACK_TARGET;
auto target_bit_shift = EN_PASSANT_TARGET_BIT;

target_bits &= EN_PASSANT_MASK << EN_PASSANT_WHITE_TARGET;
target_bits &= EN_PASSANT_MASK << EN_PASSANT_TARGET_BIT;
target_bits >>= target_bit_shift;
auto col = gsl::narrow<int8_t> (target_bits & 0x7);
bool is_present = ((target_bits & EN_PASSANT_PRESENT) > 0);
Color vulnerable_color = ((target_bits & EN_PASSANT_IS_WHITE) > 0)
? Color::White
: Color::Black;
auto row = vulnerable_color == Color::White
? White_En_Passant_Row
: Black_En_Passant_Row;

return is_present
? std::make_optional (makeCoord (row, col))
? std::make_optional (EnPassantTarget {
.coord = makeCoord (row, col),
.vulnerable_color = vulnerable_color
})
: nullopt;
}

Expand All @@ -164,8 +166,8 @@ namespace wisdom
{
auto target_bits = getMetadataBits();
auto target_bit_shift = who == Color::White
? CASTLING_STATE_WHITE_TARGET
: CASTLING_STATE_BLACK_TARGET;
? CASTLING_STATE_WHITE_BIT
: CASTLING_STATE_BLACK_BIT;

return makeCastlingEligibilityFromInt (
(target_bits >> target_bit_shift) & CASTLE_ONE_COLOR_MASK
Expand All @@ -176,8 +178,8 @@ namespace wisdom
{
uint8_t castling_bits = toInt (castling_states);
std::size_t bit_number = who == Color::White
? CASTLING_STATE_WHITE_TARGET
: CASTLING_STATE_BLACK_TARGET;
? CASTLING_STATE_WHITE_BIT
: CASTLING_STATE_BLACK_BIT;
std::size_t mask = CASTLE_ONE_COLOR_MASK << bit_number;

auto metadataBits = getMetadataBits();
Expand All @@ -197,17 +199,6 @@ namespace wisdom
return colorFromColorIndex (index);
}

[[nodiscard]] auto
enPassantTargets() const noexcept
-> EnPassantTargets
{
EnPassantTargets result = {
enPassantTarget (Color::White),
enPassantTarget (Color::Black)
};
return result;
}

[[nodiscard]] auto
getMetadataBits() const noexcept
-> std::uint16_t
Expand Down
17 changes: 11 additions & 6 deletions engine/src/generate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ namespace wisdom
if (!isValidColumn (k_col + col))
continue;

Move knight_move = Move::make (k_row + row, k_col + col, row, col);
Move knight_move = Move::make (
k_row + row,
k_col + col,
row,
col
);
int dst_row = k_row + row;
int dst_col = k_col + col;
auto index = Coord::make (dst_row, dst_col).index();
Expand Down Expand Up @@ -120,7 +125,8 @@ namespace wisdom
piece3 = board.pieceAt (src.row(), dst.column() - 1);
}

return pieceType (piece1) == Piece::None && pieceType (piece2) == Piece::None
return pieceType (piece1) == Piece::None
&& pieceType (piece2) == Piece::None
&& pieceType (piece3) == Piece::None;
}

Expand Down Expand Up @@ -257,17 +263,16 @@ namespace wisdom
appendMove (knight_move);
}

// Returns -1 if no column is eligible.
auto eligibleEnPassantColumn (const Board& board, int row, int column, Color who)
-> optional<int>
{
Color opponent = colorInvert (who);

auto enPassantTarget = board.getEnPassantTarget (opponent);
if (!enPassantTarget.has_value())
auto enPassantTarget = board.getEnPassantTarget();
if (!enPassantTarget.has_value() || enPassantTarget->vulnerable_color != opponent)
return nullopt;

Coord target_coord = *enPassantTarget;
Coord target_coord = enPassantTarget->coord;

// if WHITE rank 4, black rank 3
if ((who == Color::White ? 3 : 4) != row)
Expand Down
6 changes: 3 additions & 3 deletions engine/src/move.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,9 @@ namespace wisdom
}

void
Board::clearEnPassantTargets() noexcept
Board::clearEnPassantTarget() noexcept
{
my_code.clearEnPassantTargets();
my_code.clearEnPassantTarget();
}

void
Expand All @@ -264,7 +264,7 @@ namespace wisdom
}
else
{
clearEnPassantTargets();
clearEnPassantTarget();
}
}

Expand Down
6 changes: 6 additions & 0 deletions engine/src/move.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ namespace type_safe

namespace wisdom
{
struct EnPassantTarget
{
Coord coord;
Color vulnerable_color;
};

using CastlingEligibility = type_safe::flag_set<wisdom::CastlingIneligible>;

inline constexpr CastlingEligibility Either_Side_Eligible = type_safe::noflag;
Expand Down
Loading

0 comments on commit e4d3244

Please sign in to comment.