A move is defined as a pair of half-moves:
Code: Select all
typedef union {
uint64_t v;
struct {
half_move_t prim;
half_move_t sec;
};
} move_t;
Code: Select all
typedef union {
uint32_t v;
struct {
piece_square_t from;
piece_square_t to;
};
} half_move_t;
Code: Select all
typedef union {
uint16_t v;
struct {
union {
uint8_t piece;
struct {
uint8_t index4 : 4;
uint8_t type : 4;
};
struct {
uint8_t index : 5;
uint8_t type3 : 3;
};
};
union {
uint8_t square;
struct {
uint8_t square7 : 7;
uint8_t virgin : 1;
};
};
};
} piece_square_t;
Since piece indices are invariant, index4 changes semantics in to piece-squares, namely,
- prim.to.index4 value is XORed into the board's ep_file field (0-7 for a-h files, 8 for N/A), while
- sec.to.index4 value is XORed into the board's castle field (a 4-bit bitmask).
Castling rights delta is deferred from the colour/side, the 2 LSBs of index4 and virgin (kings, A-castling rook and H-castling are placed in indices 0, 1 and 2 respectively). virgin bits are only set in from piece-squares, allowing to.square to be used as a whole for extra efficiency.
Castling moves (before delta adjustments):
Code: Select all
K 05A087A206688460
Q 03A080A102688460
k 3DB0BFB23E78BC70
q 3BB0B8B13A78BC70