Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Revert "Consolidate en passant state to 5 bits"" #126

Merged
merged 1 commit into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading