68 W_PAWN = (Color::WHITE << PieceType::size()) | PieceType::PAWN,
69 W_KNIGHT = (Color::WHITE << PieceType::size()) | PieceType::KNIGHT,
70 W_BISHOP = (Color::WHITE << PieceType::size()) | PieceType::BISHOP,
71 W_ROOK = (Color::WHITE << PieceType::size()) | PieceType::ROOK,
72 W_QUEEN = (Color::WHITE << PieceType::size()) | PieceType::QUEEN,
73 W_KING = (Color::WHITE << PieceType::size()) | PieceType::KING,
75 B_PAWN = (Color::BLACK << PieceType::size()) | PieceType::PAWN,
76 B_KNIGHT = (Color::BLACK << PieceType::size()) | PieceType::KNIGHT,
77 B_BISHOP = (Color::BLACK << PieceType::size()) | PieceType::BISHOP,
78 B_ROOK = (Color::BLACK << PieceType::size()) | PieceType::ROOK,
79 B_QUEEN = (Color::BLACK << PieceType::size()) | PieceType::QUEEN,
80 B_KING = (Color::BLACK << PieceType::size()) | PieceType::KING,
91 static constexpr std::string_view pieceToChar =
"PNBRQK pnbrqk";
93 constexpr Piece(uint8_t value = none()) : m_value(value) {}
94 explicit constexpr Piece(
PieceType pieceType,
Color color) : m_value((color << PieceType::size()) | pieceType) {}
96 explicit constexpr Piece(
char c) {
97 size_t index = pieceToChar.find(c);
98 m_value = (index != std::string_view::npos) ?
static_cast<uint8_t
>(index) : 0;
101 [[nodiscard]]
constexpr uint8_t value()
const {
return m_value; }
103 [[nodiscard]]
constexpr bool ok()
const {
return m_value <= LAST && m_value != 6 && m_value != 7; }
105 [[nodiscard]]
static constexpr Piece none() {
return Piece::NONE; }
107 [[nodiscard]]
constexpr Color color()
const {
return m_value >> PieceType::size(); }
108 [[nodiscard]]
constexpr Color pieceType()
const {
return m_value & PieceType::mask(); }
110 [[nodiscard]]
static constexpr uint8_t number() {
return NB; }
111 [[nodiscard]]
static constexpr uint8_t mask() {
return MASK; }
112 [[nodiscard]]
static constexpr uint8_t size() {
return SIZE; }
114 [[nodiscard]]
static constexpr Piece first() {
return Piece::FIRST; }
115 [[nodiscard]]
static constexpr Piece last() {
return Piece::LAST; }
120 constexpr void skipInvalid() {
121 while (m_current <= Piece::LAST && !Piece(m_current).ok()) {
127 using iterator_category = std::forward_iterator_tag;
128 using value_type = Piece;
129 using difference_type = std::ptrdiff_t;
130 using pointer =
const Piece*;
131 using reference =
const Piece&;
133 constexpr Iterator(uint8_t value) : m_current(value) { skipInvalid(); }
135 constexpr Piece operator*()
const {
return m_current; }
137 constexpr Iterator& operator++() {
143 constexpr Iterator operator++(
int) {
144 Iterator tmp = *
this;
150 constexpr bool operator==(
const Iterator& other)
const {
return m_current == other.m_current; }
152 constexpr bool operator!=(
const Iterator& other)
const {
return m_current != other.m_current; }
157 [[nodiscard]]
constexpr Iterator begin()
const {
return Piece::FIRST; }
158 [[nodiscard]]
constexpr Iterator end()
const {
return Piece::LAST + 1; }
161 [[nodiscard]]
static constexpr Range all() {
return Range{}; }
163 constexpr operator uint8_t() {
return m_value; }
165 friend std::ostream& operator<<(std::ostream& os,
const Piece& obj) {
170 void print(std::ostream& os)
const { os << to_char(); }
172 [[nodiscard]]
char constexpr to_char()
const {
return ok() ? pieceToChar[m_value] :
'?'; }