const union { uint32_t i; char c[4]; } Le = { 0x01020304 };
const bool IsLittleEndian = (Le.c[0] == 4);
- T v = *((T*)addr);
+ T v;
+
+ if ((uintptr_t)addr & (alignof(T) - 1)) // Unaligned pointer (very rare)
+ std::memcpy(&v, addr, sizeof(T));
+ else
+ v = *((T*)addr);
+
if (LE != IsLittleEndian)
swap_byte(v);
return v;
enum { Split = 1, HasPawns = 2 };
- uint8_t flags = *data++;
+ assert(e.hasPawns == !!(*data & HasPawns));
+ assert((e.key != e.key2) == !!(*data & Split));
- assert(e.hasPawns == !!(flags & HasPawns));
- assert((e.key != e.key2) == !!(flags & Split));
+ data++; // First byte stores flags
const int Sides = IsWDL && (e.key != e.key2) ? 2 : 1;
const File MaxFile = e.hasPawns ? FILE_D : FILE_A;
moveCount++;
- pos.do_move(move, st, pos.gives_check(move));
+ pos.do_move(move, st);
value = -search(pos, result);
pos.undo_move(move);
for (int idx = 0; idx < 10; idx++)
for (Square s1 = SQ_A1; s1 <= SQ_D4; ++s1)
if (MapA1D1D4[s1] == idx && (idx || s1 == SQ_B1)) // SQ_B1 is mapped to 0
+ {
for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
if ((StepAttacksBB[KING][s1] | s1) & s2)
continue; // Illegal position
else
MapKK[idx][s2] = code++;
+ }
// Legal positions with both kings on diagonal are encoded as last ones
for (auto p : bothOnDiagonal)
{
bool zeroing = pos.capture(move) || type_of(pos.moved_piece(move)) == PAWN;
- pos.do_move(move, st, pos.gives_check(move));
+ pos.do_move(move, st);
// For zeroing moves we want the dtz of the move _before_ doing it,
// otherwise we will get the dtz of the next move sequence. Search the
// Probe each move
for (size_t i = 0; i < rootMoves.size(); ++i) {
Move move = rootMoves[i].pv[0];
- pos.do_move(move, st, pos.gives_check(move));
+ pos.do_move(move, st);
int v = 0;
if (pos.checkers() && dtz > 0) {
// Probe each move
for (size_t i = 0; i < rootMoves.size(); ++i) {
Move move = rootMoves[i].pv[0];
- pos.do_move(move, st, pos.gives_check(move));
+ pos.do_move(move, st);
WDLScore v = -Tablebases::probe_wdl(pos, &result);
pos.undo_move(move);