+CACHE_LINE_ALIGNMENT
+
+Score pieceSquareTable[PIECE_NB][SQUARE_NB];
+Value PieceValue[PHASE_NB][PIECE_NB] = {
+{ VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg },
+{ VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg } };
+
+namespace Zobrist {
+
+Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+Key enpassant[FILE_NB];
+Key castle[CASTLE_RIGHT_NB];
+Key side;
+Key exclusion;
+
+/// init() initializes at startup the various arrays used to compute hash keys
+/// and the piece square tables. The latter is a two-step operation: First, the
+/// white halves of the tables are copied from PSQT[] tables. Second, the black
+/// halves of the tables are initialized by flipping and changing the sign of
+/// the white scores.
+
+void init() {
+
+ RKISS rk;
+
+ for (Color c = WHITE; c <= BLACK; c++)
+ for (PieceType pt = PAWN; pt <= KING; pt++)
+ for (Square s = SQ_A1; s <= SQ_H8; s++)
+ psq[c][pt][s] = rk.rand<Key>();
+
+ for (File f = FILE_A; f <= FILE_H; f++)
+ enpassant[f] = rk.rand<Key>();
+
+ for (int cr = CASTLES_NONE; cr <= ALL_CASTLES; cr++)
+ {
+ Bitboard b = cr;
+ while (b)
+ {
+ Key k = castle[1ULL << pop_lsb(&b)];
+ castle[cr] ^= k ? k : rk.rand<Key>();
+ }
+ }
+
+ side = rk.rand<Key>();
+ exclusion = rk.rand<Key>();
+
+ for (PieceType pt = PAWN; pt <= KING; pt++)
+ {
+ PieceValue[MG][make_piece(BLACK, pt)] = PieceValue[MG][pt];
+ PieceValue[EG][make_piece(BLACK, pt)] = PieceValue[EG][pt];
+
+ Score v = make_score(PieceValue[MG][pt], PieceValue[EG][pt]);
+
+ for (Square s = SQ_A1; s <= SQ_H8; s++)
+ {
+ pieceSquareTable[make_piece(WHITE, pt)][ s] = (v + PSQT[pt][s]);
+ pieceSquareTable[make_piece(BLACK, pt)][~s] = -(v + PSQT[pt][s]);
+ }
+ }
+}
+
+} // namespace Zobrist
+
+
+namespace {
+
+/// next_attacker() is an helper function used by see() to locate the least
+/// valuable attacker for the side to move, remove the attacker we just found
+/// from the 'occupied' bitboard and scan for new X-ray attacks behind it.
+
+template<int Pt> FORCE_INLINE
+PieceType next_attacker(const Bitboard* bb, const Square& to, const Bitboard& stmAttackers,
+ Bitboard& occupied, Bitboard& attackers) {
+
+ if (stmAttackers & bb[Pt])
+ {
+ Bitboard b = stmAttackers & bb[Pt];
+ occupied ^= b & ~(b - 1);
+
+ if (Pt == PAWN || Pt == BISHOP || Pt == QUEEN)
+ attackers |= attacks_bb<BISHOP>(to, occupied) & (bb[BISHOP] | bb[QUEEN]);
+
+ if (Pt == ROOK || Pt == QUEEN)
+ attackers |= attacks_bb<ROOK>(to, occupied) & (bb[ROOK] | bb[QUEEN]);
+
+ return (PieceType)Pt;
+ }
+ return next_attacker<Pt+1>(bb, to, stmAttackers, occupied, attackers);
+}
+
+template<> FORCE_INLINE
+PieceType next_attacker<KING>(const Bitboard*, const Square&, const Bitboard&, Bitboard&, Bitboard&) {
+ return KING; // No need to update bitboards, it is the last cycle
+}
+
+} // namespace
+