/// init() is a static member function which 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. internal static void init() { var rk = new RKISS(); for (var c = ColorC.WHITE; c <= ColorC.BLACK; c++) { psq[c] = new ulong[PieceTypeC.PIECE_TYPE_NB][]; for (var pt = PieceTypeC.PAWN; pt <= PieceTypeC.KING; pt++) { psq[c][pt] = new ulong[SquareC.SQUARE_NB]; for (var s = SquareC.SQ_A1; s <= SquareC.SQ_H8; s++) { psq[c][pt][s] = rk.rand(); } } } for (var f = FileC.FILE_A; f <= FileC.FILE_H; f++) { enpassant[f] = rk.rand(); } ulong one = 1; for (var cr = CastleRightC.CASTLES_NONE; cr <= CastleRightC.ALL_CASTLES; cr++) { var b = (ulong)cr; while (b != 0) { var k = castle[one << Utils.pop_lsb(ref b)]; castle[cr] ^= ((k != 0) ? k : rk.rand()); } } side = rk.rand(); exclusion = rk.rand(); for (var i = 0; i < PieceC.PIECE_NB; i++) { PieceSquareTable[i] = new int[SquareC.SQUARE_NB]; } for (var pt = PieceTypeC.PAWN; pt <= PieceTypeC.KING; pt++) { Position.PieceValue[PhaseC.MG][Utils.make_piece(ColorC.BLACK, pt)] = Position.PieceValue[PhaseC.MG][pt]; Position.PieceValue[PhaseC.EG][Utils.make_piece(ColorC.BLACK, pt)] = Position.PieceValue[PhaseC.EG][pt]; var v = Utils.make_score(Position.PieceValue[PhaseC.MG][pt], Position.PieceValue[PhaseC.EG][pt]); for (var s = SquareC.SQ_A1; s <= SquareC.SQ_H8; s++) { PieceSquareTable[Utils.make_piece(ColorC.WHITE, pt)][s] = (v + Utils.PSQT[pt][s]); PieceSquareTable[Utils.make_piece(ColorC.BLACK, pt)][Utils.flip_S(s)] = -(v + Utils.PSQT[pt][s]); } } }
private static ulong pick_random(RKISS rk, int booster) { // Values s1 and s2 are used to rotate the candidate magic of a // quantity known to be the optimal to quickly find the magics. int s1 = booster & 63, s2 = (booster >> 6) & 63; ulong m = rk.rand(); m = (m >> s1) | (m << (64 - s1)); m &= rk.rand(); m = (m >> s2) | (m << (64 - s2)); return m & rk.rand(); }
private static Bitboard pick_random(Bitboard mask, RKISS rk, int booster) { Bitboard magic; // Values s1 and s2 are used to rotate the candidate magic of a // quantity known to be the optimal to quickly find the magics. int s1 = booster & 63, s2 = (booster >> 6) & 63; while (true) { magic = rk.rand(); magic = (magic >> s1) | (magic << (64 - s1)); magic &= rk.rand(); magic = (magic >> s2) | (magic << (64 - s2)); magic &= rk.rand(); if (BitCount8Bit[(mask * magic) >> 56] >= 6) return magic; } }
/// init() is a static member function which 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. internal static void init() { RKISS rk = new RKISS(); for (Color c = ColorC.WHITE; c <= ColorC.BLACK; c++) { zobrist[c] = new Bitboard[8][]; for (PieceType pt = PieceTypeC.PAWN; pt <= PieceTypeC.KING; pt++) { zobrist[c][pt] = new Bitboard[64]; for (Square s = SquareC.SQ_A1; s <= SquareC.SQ_H8; s++) { zobrist[c][pt][s] = rk.rand(); } } } for (File f = FileC.FILE_A; f <= FileC.FILE_H; f++) zobEp[f] = rk.rand(); Bitboard one = 1; for (int cr = CastleRightC.CASTLES_NONE; cr <= CastleRightC.ALL_CASTLES; cr++) { Bitboard b = (Bitboard)cr; while (b != 0) { Key k = zobCastle[one << Utils.pop_1st_bit(ref b)]; zobCastle[cr] ^= ((k != 0) ? k : rk.rand()); } } zobSideToMove = rk.rand(); zobExclusion = rk.rand(); for (int i = 0; i < 16; i++) { pieceSquareTable[i] = new Score[64]; } for (PieceType pt = PieceTypeC.PAWN; pt <= PieceTypeC.KING; pt++) { Score v = Utils.make_score(PieceValueMidgame[pt], PieceValueEndgame[pt]); for (Square s = SquareC.SQ_A1; s <= SquareC.SQ_H8; s++) { pieceSquareTable[Utils.make_piece(ColorC.WHITE, pt)][s] = (v + Utils.PSQT[pt][s]); pieceSquareTable[Utils.make_piece(ColorC.BLACK, pt)][Utils.flip_S(s)] = -(v + Utils.PSQT[pt][s]); } } }