|
@@ -4,14 +4,31 @@
|
|
|
#include <cinttypes>
|
|
|
#include <type_traits>
|
|
|
|
|
|
+
|
|
|
namespace chessy
|
|
|
{
|
|
|
using U64 = uint64_t;
|
|
|
- using Index = int8_t;
|
|
|
+ union Index;
|
|
|
|
|
|
struct Bitboard;
|
|
|
}
|
|
|
|
|
|
+union chessy::Index
|
|
|
+{
|
|
|
+ int8_t index;
|
|
|
+
|
|
|
+ // Anonymous structs are actually not allowed in C++.
|
|
|
+ // Fortunately any sane compiler still supports them.
|
|
|
+ struct {
|
|
|
+ uint8_t column : 3;
|
|
|
+ uint8_t row : 3;
|
|
|
+ };
|
|
|
+
|
|
|
+ Index() = default;
|
|
|
+ inline Index(int8_t ind) : index {ind} {}
|
|
|
+ inline operator int8_t (void) const { return index; }
|
|
|
+};
|
|
|
+
|
|
|
|
|
|
struct chessy::Bitboard
|
|
|
{
|
|
@@ -20,8 +37,9 @@ struct chessy::Bitboard
|
|
|
Bitboard (void) = default;
|
|
|
Bitboard (const Bitboard&) = default;
|
|
|
~Bitboard (void) = default;
|
|
|
- inline Bitboard (U64 bits) : bits(bits) {}
|
|
|
- inline Bitboard (Index row, Index column) : bits(row + column * 8) {}
|
|
|
+
|
|
|
+ inline Bitboard (U64 bits) : bits {bits} {}
|
|
|
+ inline static Bitboard fromIndex(Index i) { return 1 << i; }
|
|
|
|
|
|
inline void setBit (int i) { bits |= 1 << i; }
|
|
|
inline void unsetBit (int i) { bits |= ~(1 << i); }
|
|
@@ -45,6 +63,10 @@ struct chessy::Bitboard
|
|
|
inline void moveSEOne (void) { bits = (bits >> 9) & ~aColumn; }
|
|
|
inline void moveSWOne (void) { bits = (bits >> 7) & ~hColumn; }
|
|
|
|
|
|
+ inline void operator &= (const Bitboard& b) { bits &= b.bits; }
|
|
|
+ inline void operator |= (const Bitboard& b) { bits |= b.bits; }
|
|
|
+ inline void operator ^= (const Bitboard& b) { bits ^= b.bits; }
|
|
|
+
|
|
|
inline Bitboard operator & (const Bitboard& b) const { return bits & b.bits; }
|
|
|
inline Bitboard operator | (const Bitboard& b) const { return bits | b.bits; }
|
|
|
inline Bitboard operator ^ (const Bitboard& b) const { return bits ^ b.bits; }
|
|
@@ -52,15 +74,41 @@ struct chessy::Bitboard
|
|
|
inline bool operator == (const Bitboard& b) const { return bits == b.bits; }
|
|
|
inline bool operator != (const Bitboard& b) const { return bits != b.bits; }
|
|
|
inline operator U64(void) const { return bits; }
|
|
|
+
|
|
|
+
|
|
|
+ inline Bitboard mirror (void) const
|
|
|
+ {
|
|
|
+#if __GNUC__ > 4 && __GNUC_MINOR__ >= 3
|
|
|
+ return __builtin_bswap64(bits);
|
|
|
+#else
|
|
|
+ return (bits << 56) |
|
|
|
+ ((bits & 0xFF00) << 40) |
|
|
|
+ ((bits & 0xFF0000) << 24) |
|
|
|
+ ((bits & 0xFF000000) << 8) |
|
|
|
+ ((bits & 0xFF00000000) >> 8) |
|
|
|
+ ((bits & 0xFF0000000000) >> 24) |
|
|
|
+ ((bits & 0xFF000000000000) >> 40) |
|
|
|
+ (bits >> 56);
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ static int trailingZeroes (U64 x) {
|
|
|
+#if __GNUC__ > 4 && __GNUC_MINOR__ >= 5
|
|
|
+ return __builtin_ctzll(x);
|
|
|
+#else
|
|
|
+ for (unsigned char i = 0; i < 64; i++)
|
|
|
+ if (x & (1 << i))
|
|
|
+ return i;
|
|
|
+#endif
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
|
|
|
static_assert(std::is_pod<chessy::Bitboard>().value,
|
|
|
"chessy::Bitboard should be a POD structure.");
|
|
|
-static_assert(std::is_trivial<chessy::Bitboard>().value,
|
|
|
- "chessy::Bitboard should be a trivial structure.");
|
|
|
static_assert(sizeof(chessy::Bitboard) == sizeof(uint64_t),
|
|
|
"chessy::Bitboard should be 64 bits in size.");
|
|
|
|
|
|
|
|
|
-#endif /* CHESSY_BITBOARD_H */
|
|
|
+#endif // CHESSY_BITBOARD_H
|
|
|
+
|