77 constexpr Move() =
default;
89 [[nodiscard]]
constexpr auto from() const noexcept ->
Square;
95 [[nodiscard]] constexpr auto
to() const noexcept ->
Square;
106 [[nodiscard]] constexpr auto
hash() const noexcept ->
size_t;
109 [[nodiscard]] auto
is_null() const noexcept ->
bool {
return std::cmp_equal(data, 0); }
112 [[nodiscard]]
constexpr auto is_promotion() const noexcept ->
bool;
118 [[nodiscard]] constexpr auto
is_castling() const noexcept ->
bool;
120 constexpr auto operator==(const
Move&) const noexcept ->
bool = default;
123 using Integer = std::uint16_t;
125 [[nodiscard]] constexpr auto get_flags() const noexcept -> Integer;
138 Integer data { UINT16_C(0) };
146 -> std::strong_ordering
148 return first.hash() <=> second.hash();
173[[nodiscard, gnu::const]]
constexpr auto promotion(
197 using Integer = std::uint16_t;
199 inline constexpr auto LOWEST_SIX_BITS_MASK = 63uz;
201 inline constexpr Integer START_SQUARE_OFFSET = UINT16_C(6);
202 inline constexpr Integer FLAGS_OFFSET = UINT16_C(12);
204 inline constexpr auto PROMOTED_TYPE_OFFSET_WITHIN_FLAGS = 6uz;
206 [[nodiscard, gnu::const]]
constexpr auto pack_fields(
211 const auto flags = promotedType
213 return PROMOTED_TYPE_OFFSET_WITHIN_FLAGS + std::to_underlying(prom);
215 .value_or(std::to_underlying(type));
217 return static_cast<Integer
>(
218 static_cast<Integer
>(end.index())
219 + (
static_cast<Integer
>(start.index()) << START_SQUARE_OFFSET)
220 + (
static_cast<Integer
>(flags) << FLAGS_OFFSET));
229 : data { detail::pack_fields(start, end, type, promotedType) }
232 if (promotedType.has_value()) {
233 assert(type == PieceType::Pawn);
234 assert(promotedType != PieceType::King);
235 assert(promotedType != PieceType::Pawn);
240constexpr auto Move::get_flags() const noexcept -> Integer
242 static constexpr auto LOWEST_FOUR_BITS_MASK = 15uz;
244 return (data >> detail::FLAGS_OFFSET) & LOWEST_FOUR_BITS_MASK;
249 return Square::from_index((data >> detail::START_SQUARE_OFFSET) & detail::LOWEST_SIX_BITS_MASK);
259 const auto flags = get_flags();
261 if (std::cmp_greater_equal(flags, detail::PROMOTED_TYPE_OFFSET_WITHIN_FLAGS))
262 return PieceType::Pawn;
269 const auto flags = get_flags();
271 if (std::cmp_less(flags, detail::PROMOTED_TYPE_OFFSET_WITHIN_FLAGS))
274 return static_cast<PieceType>(flags - detail::PROMOTED_TYPE_OFFSET_WITHIN_FLAGS);
279 return std::cmp_greater_equal(
280 get_flags(), detail::PROMOTED_TYPE_OFFSET_WITHIN_FLAGS);
286 .transform([](
const PieceType type) {
return type != PieceType::Queen; })
292 return piece() == PieceType::King
293 and std::cmp_greater(
294 file_distance(
from(),
to()),
301 return (
static_cast<size_t>(data) * 6364136223846793005uz) + 1442695040888963407uz;
309 Square { .file = File::E, .rank = rank },
310 Square { .file = File::G, .rank = rank },
320 Square { .file = File::E, .rank = rank },
321 Square { .file = File::C, .rank = rank },
330 assert(promotedType != PieceType::King);
331 assert(promotedType != PieceType::Pawn);
333 const bool isWhite = color == Color::White;
336 Square { .file = file, .rank = isWhite ? Rank::Seven : Rank::Two },
337 Square { .file = file, .rank = isWhite ? Rank::Eight : Rank::One },
constexpr auto back_rank_for(Color color) noexcept -> Rank
constexpr auto operator<=>(const Move &first, const Move &second) noexcept -> std::strong_ordering
constexpr auto castle_queenside(const Color color) noexcept -> Move
constexpr auto castle_kingside(const Color color) noexcept -> Move
constexpr auto promotion(const File file, const Color color, const PieceType promotedType) noexcept -> Move
std::optional< PieceType > MaybePieceType
constexpr auto hash() const noexcept -> size_t
constexpr auto is_promotion() const noexcept -> bool
constexpr auto to() const noexcept -> Square
constexpr auto promoted_type() const noexcept -> MaybePieceType
constexpr auto is_under_promotion() const noexcept -> bool
constexpr auto is_castling() const noexcept -> bool
constexpr auto piece() const noexcept -> PieceType
constexpr auto from() const noexcept -> Square
auto is_null() const noexcept -> bool
static constexpr auto from_index(BitboardIndex index) noexcept -> Square