Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 pmbaty 1
/*
2
    Texel - A UCI chess engine.
3
    Copyright (C) 2012-2014  Peter Ă–sterlund, peterosterlund2@gmail.com
4
 
5
    This program is free software: you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation, either version 3 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
 
19
/*
20
 * position.cpp
21
 *
22
 *  Created on: Feb 25, 2012
23
 *      Author: petero
24
 */
25
 
26
#include "position.hpp"
27
#include "evaluate.hpp"
28
#include "textio.hpp"
29
 
30
#include <iostream>
31
#include <cassert>
32
 
33
U64 Position::psHashKeys[Piece::nPieceTypes][64];
34
U64 Position::whiteHashKey;
35
U64 Position::castleHashKeys[16];
36
U64 Position::epHashKeys[9];
37
U64 Position::moveCntKeys[101];
38
 
39
 
40
static StaticInitializer<Position> posInit;
41
 
42
void
43
Position::staticInitialize() {
44
    int rndNo = 0;
45
    for (int p = 0; p < Piece::nPieceTypes; p++)
46
        for (int sq = 0; sq < 64; sq++)
47
            psHashKeys[p][sq] = getRandomHashVal(rndNo++);
48
    whiteHashKey = getRandomHashVal(rndNo++);
49
    for (size_t cm = 0; cm < COUNT_OF(castleHashKeys); cm++)
50
        castleHashKeys[cm] = getRandomHashVal(rndNo++);
51
    for (size_t f = 0; f < COUNT_OF(epHashKeys); f++)
52
        epHashKeys[f] = getRandomHashVal(rndNo++);
53
    for (size_t mc = 0; mc < COUNT_OF(moveCntKeys); mc++)
54
        moveCntKeys[mc] = getRandomHashVal(rndNo++);
55
}
56
 
57
 
58
Position::Position() {
59
    for (int i = 0; i < 64; i++)
60
        squares[i] = Piece::EMPTY;
61
    for (int i = 0; i < Piece::nPieceTypes; i++) {
62
        psScore1_[i] = 0;
63
        psScore2_[i] = 0;
64
        pieceTypeBB_[i] = 0;
65
    }
66
    whiteBB_ = blackBB_ = 0;
67
    whiteMove = true;
68
    castleMask = 0;
69
    epSquare = -1;
70
    halfMoveClock = 0;
71
    fullMoveCounter = 1;
72
    computeZobristHash();
73
    wKingSq_ = bKingSq_ = -1;
74
    wMtrl_ = bMtrl_ = -::kV;
75
    wMtrlPawns_ = bMtrlPawns_ = 0;
76
}
77
 
78
void
79
Position::setPiece(int square, int piece) {
80
    int removedPiece = squares[square];
81
    squares[square] = piece;
82
 
83
    // Update hash key
84
    hashKey ^= psHashKeys[removedPiece][square];
85
    hashKey ^= psHashKeys[piece][square];
86
 
87
    // Update material identifier
88
    matId.removePiece(removedPiece);
89
    matId.addPiece(piece);
90
 
91
    // Update bitboards
92
    const U64 sqMask = 1ULL << square;
93
    pieceTypeBB_[removedPiece] &= ~sqMask;
94
    pieceTypeBB_[piece] |= sqMask;
95
 
96
    if (removedPiece != Piece::EMPTY) {
97
        int pVal = ::pieceValue[removedPiece];
98
        if (Piece::isWhite(removedPiece)) {
99
            wMtrl_ -= pVal;
100
            whiteBB_ &= ~sqMask;
101
            if (removedPiece == Piece::WPAWN) {
102
                wMtrlPawns_ -= pVal;
103
                pHashKey ^= psHashKeys[Piece::WPAWN][square];
104
            }
105
        } else {
106
            bMtrl_ -= pVal;
107
            blackBB_ &= ~sqMask;
108
            if (removedPiece == Piece::BPAWN) {
109
                bMtrlPawns_ -= pVal;
110
                pHashKey ^= psHashKeys[Piece::BPAWN][square];
111
            }
112
        }
113
    }
114
 
115
    if (piece != Piece::EMPTY) {
116
        int pVal = ::pieceValue[piece];
117
        if (Piece::isWhite(piece)) {
118
            wMtrl_ += pVal;
119
            whiteBB_ |= sqMask;
120
            if (piece == Piece::WPAWN) {
121
                wMtrlPawns_ += pVal;
122
                pHashKey ^= psHashKeys[Piece::WPAWN][square];
123
            }
124
            if (piece == Piece::WKING)
125
                wKingSq_ = square;
126
        } else {
127
            bMtrl_ += pVal;
128
            blackBB_ |= sqMask;
129
            if (piece == Piece::BPAWN) {
130
                bMtrlPawns_ += pVal;
131
                pHashKey ^= psHashKeys[Piece::BPAWN][square];
132
            }
133
            if (piece == Piece::BKING)
134
                bKingSq_ = square;
135
        }
136
    }
137
 
138
    // Update piece/square table scores
139
    psScore1_[removedPiece] -= Evaluate::psTab1[removedPiece][square];
140
    psScore2_[removedPiece] -= Evaluate::psTab2[removedPiece][square];
141
    psScore1_[piece]        += Evaluate::psTab1[piece][square];
142
    psScore2_[piece]        += Evaluate::psTab2[piece][square];
143
}
144
 
145
U64
146
Position::hashAfterMove(const Move& move) const {
147
    int from = move.from();
148
    int to = move.to();
149
    int p = squares[from];
150
    int capP = squares[to];
151
 
152
    U64 ret = hashKey ^ whiteHashKey;
153
    ret ^= psHashKeys[capP][to];
154
    ret ^= psHashKeys[p][to];
155
    ret ^= psHashKeys[p][from];
156
    ret ^= psHashKeys[Piece::EMPTY][from];
157
 
158
    return ret;
159
}
160
 
161
void
162
Position::makeMove(const Move& move, UndoInfo& ui) {
163
    ui.capturedPiece = squares[move.to()];
164
    ui.castleMask = castleMask;
165
    ui.epSquare = epSquare;
166
    ui.halfMoveClock = halfMoveClock;
167
    bool wtm = whiteMove;
168
 
169
    hashKey ^= whiteHashKey;
170
 
171
    const int p = squares[move.from()];
172
    int capP = squares[move.to()];
173
    U64 fromMask = 1ULL << move.from();
174
 
175
    int prevEpSquare = epSquare;
176
    setEpSquare(-1);
177
 
178
    if ((capP != Piece::EMPTY) || ((pieceTypeBB(Piece::WPAWN, Piece::BPAWN) & fromMask) != 0)) {
179
        halfMoveClock = 0;
180
 
181
        // Handle en passant and epSquare
182
        if (p == Piece::WPAWN) {
183
            if (move.to() - move.from() == 2 * 8) {
184
                int x = getX(move.to());
185
                if (BitBoard::epMaskW[x] & pieceTypeBB(Piece::BPAWN))
186
                    setEpSquare(move.from() + 8);
187
            } else if (move.to() == prevEpSquare) {
188
                setPiece(move.to() - 8, Piece::EMPTY);
189
            }
190
        } else if (p == Piece::BPAWN) {
191
            if (move.to() - move.from() == -2 * 8) {
192
                int x = getX(move.to());
193
                if (BitBoard::epMaskB[x] & pieceTypeBB(Piece::WPAWN))
194
                    setEpSquare(move.from() - 8);
195
            } else if (move.to() == prevEpSquare) {
196
                setPiece(move.to() + 8, Piece::EMPTY);
197
            }
198
        }
199
 
200
        if ((pieceTypeBB(Piece::WKING, Piece::BKING) & fromMask) != 0) {
201
            if (wtm) {
202
                setCastleMask(castleMask & ~(1 << A1_CASTLE));
203
                setCastleMask(castleMask & ~(1 << H1_CASTLE));
204
            } else {
205
                setCastleMask(castleMask & ~(1 << A8_CASTLE));
206
                setCastleMask(castleMask & ~(1 << H8_CASTLE));
207
            }
208
        }
209
 
210
        // Perform move
211
        setPiece(move.from(), Piece::EMPTY);
212
        // Handle promotion
213
        if (move.promoteTo() != Piece::EMPTY) {
214
            setPiece(move.to(), move.promoteTo());
215
        } else {
216
            setPiece(move.to(), p);
217
        }
218
    } else {
219
        halfMoveClock++;
220
 
221
        // Handle castling
222
        if ((pieceTypeBB(Piece::WKING, Piece::BKING) & fromMask) != 0) {
223
            int k0 = move.from();
224
            if (move.to() == k0 + 2) { // O-O
225
                movePieceNotPawn(k0 + 3, k0 + 1);
226
            } else if (move.to() == k0 - 2) { // O-O-O
227
                movePieceNotPawn(k0 - 4, k0 - 1);
228
            }
229
            if (wtm) {
230
                setCastleMask(castleMask & ~(1 << A1_CASTLE));
231
                setCastleMask(castleMask & ~(1 << H1_CASTLE));
232
            } else {
233
                setCastleMask(castleMask & ~(1 << A8_CASTLE));
234
                setCastleMask(castleMask & ~(1 << H8_CASTLE));
235
            }
236
        }
237
 
238
        // Perform move
239
        movePieceNotPawn(move.from(), move.to());
240
    }
241
    if (wtm) {
242
        // Update castling rights when rook moves
243
        if ((BitBoard::maskCorners & fromMask) != 0) {
244
            if (p == Piece::WROOK)
245
                removeCastleRights(move.from());
246
        }
247
        if ((BitBoard::maskCorners & (1ULL << move.to())) != 0) {
248
            if (capP == Piece::BROOK)
249
                removeCastleRights(move.to());
250
        }
251
    } else {
252
        fullMoveCounter++;
253
        // Update castling rights when rook moves
254
        if ((BitBoard::maskCorners & fromMask) != 0) {
255
            if (p == Piece::BROOK)
256
                removeCastleRights(move.from());
257
        }
258
        if ((BitBoard::maskCorners & (1ULL << move.to())) != 0) {
259
            if (capP == Piece::WROOK)
260
                removeCastleRights(move.to());
261
        }
262
    }
263
 
264
    whiteMove = !wtm;
265
}
266
 
267
void
268
Position::makeMoveB(const Move& move, UndoInfo& ui) {
269
    ui.capturedPiece = squares[move.to()];
270
    ui.castleMask = castleMask;
271
 
272
    const int p = squares[move.from()];
273
    int capP = squares[move.to()];
274
    U64 fromMask = 1ULL << move.from();
275
 
276
    int prevEpSquare = epSquare;
277
 
278
    if ((capP != Piece::EMPTY) || ((pieceTypeBB(Piece::WPAWN, Piece::BPAWN) & fromMask) != 0)) {
279
        // Handle en passant
280
        if (p == Piece::WPAWN) {
281
            if (move.to() == prevEpSquare)
282
                setPieceB(move.to() - 8, Piece::EMPTY);
283
        } else if (p == Piece::BPAWN) {
284
            if (move.to() == prevEpSquare)
285
                setPieceB(move.to() + 8, Piece::EMPTY);
286
        }
287
 
288
        // Perform move
289
        setPieceB(move.from(), Piece::EMPTY);
290
        // Handle promotion
291
        if (move.promoteTo() != Piece::EMPTY) {
292
            setPieceB(move.to(), move.promoteTo());
293
        } else {
294
            setPieceB(move.to(), p);
295
        }
296
    } else {
297
        // Handle castling
298
        if ((pieceTypeBB(Piece::WKING, Piece::BKING) & fromMask) != 0) {
299
            int k0 = move.from();
300
            if (move.to() == k0 + 2) { // O-O
301
                movePieceNotPawnB(k0 + 3, k0 + 1);
302
            } else if (move.to() == k0 - 2) { // O-O-O
303
                movePieceNotPawnB(k0 - 4, k0 - 1);
304
            }
305
        }
306
 
307
        // Perform move
308
        movePieceNotPawnB(move.from(), move.to());
309
    }
310
}
311
 
312
void
313
Position::movePieceNotPawn(int from, int to) {
314
    const int piece = squares[from];
315
    hashKey ^= psHashKeys[piece][from];
316
    hashKey ^= psHashKeys[piece][to];
317
    hashKey ^= psHashKeys[Piece::EMPTY][from];
318
    hashKey ^= psHashKeys[Piece::EMPTY][to];
319
 
320
    squares[from] = Piece::EMPTY;
321
    squares[to] = piece;
322
 
323
    const U64 sqMaskF = 1ULL << from;
324
    const U64 sqMaskT = 1ULL << to;
325
    pieceTypeBB_[piece] &= ~sqMaskF;
326
    pieceTypeBB_[piece] |= sqMaskT;
327
    if (Piece::isWhite(piece)) {
328
        whiteBB_ &= ~sqMaskF;
329
        whiteBB_ |= sqMaskT;
330
        if (piece == Piece::WKING)
331
            wKingSq_ = to;
332
    } else {
333
        blackBB_ &= ~sqMaskF;
334
        blackBB_ |= sqMaskT;
335
        if (piece == Piece::BKING)
336
            bKingSq_ = to;
337
    }
338
 
339
    psScore1_[piece] += Evaluate::psTab1[piece][to] - Evaluate::psTab1[piece][from];
340
    psScore2_[piece] += Evaluate::psTab2[piece][to] - Evaluate::psTab2[piece][from];
341
}
342
 
343
// ----------------------------------------------------------------------------
344
 
345
void
346
Position::serialize(SerializeData& data) const {
347
    for (int i = 0; i < 4; i++) {
348
        int sq0 = i * 16;
349
        U64 v = 0;
350
        for (int sq = 0; sq < 16; sq++)
351
            v = (v << 4) | squares[sq0 + sq];
352
        data.v[i] = v;
353
    }
354
    U64 flags = whiteMove;
355
    flags = (flags << 4) | castleMask;
356
    flags = (flags << 8) | (epSquare & 0xff);
357
    flags = (flags << 8) | (halfMoveClock & 0xff);
358
    flags = (flags << 16) | (fullMoveCounter & 0xffff);
359
    data.v[4] = flags;
360
}
361
 
362
void
363
Position::deSerialize(const SerializeData& data) {
364
    for (int i = 0; i < Piece::nPieceTypes; i++) {
365
        psScore1_[i] = 0;
366
        psScore2_[i] = 0;
367
        pieceTypeBB_[i] = 0;
368
    }
369
    whiteBB_ = blackBB_ = 0;
370
    wMtrl_ = bMtrl_ = -::kV;
371
    wMtrlPawns_ = bMtrlPawns_ = 0;
372
    for (int i = 0; i < 4; i++) {
373
        int sq0 = i * 16;
374
        U64 v = data.v[i];
375
        for (int sq = 15; sq >= 0; sq--) {
376
            int piece = v & 0xf;
377
            v >>= 4;
378
            int square = sq0 + sq;
379
            squares[square] = piece;
380
 
381
            const U64 sqMask = 1ULL << square;
382
            pieceTypeBB_[piece] |= sqMask;
383
            if (piece != Piece::EMPTY) {
384
                int pVal = ::pieceValue[piece];
385
                if (Piece::isWhite(piece)) {
386
                    wMtrl_ += pVal;
387
                    whiteBB_ |= sqMask;
388
                    if (piece == Piece::WPAWN)
389
                        wMtrlPawns_ += pVal;
390
                    if (piece == Piece::WKING)
391
                        wKingSq_ = square;
392
                } else {
393
                    bMtrl_ += pVal;
394
                    blackBB_ |= sqMask;
395
                    if (piece == Piece::BPAWN)
396
                        bMtrlPawns_ += pVal;
397
                    if (piece == Piece::BKING)
398
                        bKingSq_ = square;
399
                }
400
            }
401
            psScore1_[piece] += Evaluate::psTab1[piece][square];
402
            psScore2_[piece] += Evaluate::psTab2[piece][square];
403
        }
404
    }
405
 
406
    U64 flags = data.v[4];
407
    fullMoveCounter = flags & 0xffff;
408
    flags >>= 16;
409
    halfMoveClock = flags & 0xff;
410
    flags >>= 8;
411
    int ep = flags & 0xff; if (ep == 0xff) ep = -1;
412
    epSquare = ep;
413
    flags >>= 8;
414
    castleMask = flags & 0xf;
415
    flags >>= 4;
416
    whiteMove = (flags & 1) != 0;
417
 
418
    computeZobristHash();
419
}
420
 
421
// ----------------------------------------------------------------------------
422
 
423
std::ostream&
424
operator<<(std::ostream& os, const Position& pos) {
425
    std::stringstream ss;
426
    ss << std::hex << pos.zobristHash();
427
    os << TextIO::asciiBoard(pos) << (pos.isWhiteMove() ? "white\n" : "black\n") << ss.str();
428
    return os;
429
}
430
 
431
U64
432
Position::computeZobristHash() {
433
    U64 hash = 0;
434
    pHashKey = 0;
435
    matId = {};
436
    for (int sq = 0; sq < 64; sq++) {
437
        int p = squares[sq];
438
        matId.addPiece(p);
439
        hash ^= psHashKeys[p][sq];
440
        if ((p == Piece::WPAWN) || (p == Piece::BPAWN))
441
            pHashKey ^= psHashKeys[p][sq];
442
    }
443
    if (whiteMove)
444
        hash ^= whiteHashKey;
445
    hash ^= castleHashKeys[castleMask];
446
    hash ^= epHashKeys[(epSquare >= 0) ? getX(epSquare) + 1 : 0];
447
    hashKey = hash;
448
    return hash;
449
}
450
 
451
const U64
452
Position::zobristRndKeys[] = {
453
    0xd7f5bae778359690ULL, 0x597a80e80456583cULL, 0xf41fc6250b89af0aULL, 0x60bbccb1c393eb8eULL,
454
    0x609a7b63b265bad6ULL, 0x7c2203b2d50e50ddULL, 0x5cdb65b020e76780ULL, 0x3ada5f98c76f082fULL,
455
    0xb8664a3b4835aba4ULL, 0xfd52e04af3634f9dULL, 0x19845bb0dc72bfebULL, 0x323f11923ad0ce94ULL,
456
    0x840b643592625af3ULL, 0x08d0487ddf83e6b1ULL, 0xe102c4c56f3cbcf1ULL, 0x8796d332562f05aeULL,
457
    0x8da8c0e4914f9754ULL, 0x8d33ff34f6348b49ULL, 0x9d19aea59af28996ULL, 0x9eb6168a4359a5feULL,
458
    0x31663b93847b0fc7ULL, 0x90eba80ddb28d49aULL, 0xccee52c57542c041ULL, 0x0860882a3e8279cfULL,
459
    0xde316bf1225afa4aULL, 0xc7b1c13ea1ba90c6ULL, 0x86dee889c37e993aULL, 0x84a546382686f7f9ULL,
460
    0xf5279c7d250960a6ULL, 0x74c682f9a715318dULL, 0xe7df0efd43f4030aULL, 0xdc6746e82902823cULL,
461
    0x166d42c650423d16ULL, 0xf0ec64304812b32dULL, 0x1332e60d6eec5b48ULL, 0xa6edf8bd55663265ULL,
462
    0x9be3edd5fba6cfd3ULL, 0xea3c98aad8c558f1ULL, 0x577d05d0fcff765dULL, 0xf4dffef665484f9aULL,
463
    0x80522262e9120108ULL, 0x47e9fa92bc64f2eeULL, 0x689ed873d813ba14ULL, 0xdbe14e4bad57221aULL,
464
    0x27dde4dac822503bULL, 0xeb54f328a3ec06bbULL, 0x385875cea7e74a41ULL, 0x9939e2b74efb03ecULL,
465
    0xe9dab3b1f89ac50eULL, 0x542e57cd136b4844ULL, 0xfd0d99e83d6b34b8ULL, 0x2ab51be0b039bdd7ULL,
466
    0xa848485bf044dac6ULL, 0xfb8b9ccc055dda28ULL, 0x6bd5fcf11932c643ULL, 0x5562cc1783eafc90ULL,
467
    0x84c2258075a4fc77ULL, 0xa3e2654a1b9ac399ULL, 0xa0d0b4498debbc94ULL, 0x7b5a612c9e7f4013ULL,
468
    0x541ad1f5345860e9ULL, 0xe994fc3ad27d8421ULL, 0x7d004d11c8d81c45ULL, 0xdf060a0b1ba0a5d0ULL,
469
    0xd7554261378a32ebULL, 0x3833239c3fe92c7dULL, 0xdf6f7a5e977113d5ULL, 0xe04fc2e2017aa5cdULL,
470
    0x7670776c650e1507ULL, 0x2b7cbce40c6231ddULL, 0xda383fc3dd431843ULL, 0xe5b36397cf1ec05dULL,
471
    0xdc984f60c622c2a9ULL, 0x51ef8d0af8fe2607ULL, 0x1511f2e39e554dffULL, 0x5f2c921d80f3be07ULL,
472
    0x2015c1d1cc6b9e92ULL, 0x99f7e5a26196f13bULL, 0x7a93cc38310fb397ULL, 0xd11d2eba53c47047ULL,
473
    0x070f46cdfa04dd80ULL, 0x0ebb465f6fea9c74ULL, 0xfb61452fb27308d9ULL, 0xa952f5d52c3eb97dULL,
474
    0x95799379a4a515abULL, 0x06508b45a2745539ULL, 0xaf69d20bf29de152ULL, 0xb0ad19b1f4ee4eb8ULL,
475
    0x2bd91aa7c8200e4dULL, 0xcecee5089679a9c2ULL, 0xc189667953231141ULL, 0x24f90ceadfd2ece5ULL,
476
    0x3518487a931724d2ULL, 0x5244fe5f9e40057cULL, 0x366ce132f59078ffULL, 0xe63f79535cf61cdeULL,
477
    0xefdfab636b84b733ULL, 0xe38c18fdb5bf9f22ULL, 0xa4064c6acad42a58ULL, 0xcce22e73ebafa83aULL,
478
    0xa40b98bb7736c6e0ULL, 0xb75dd212bc092f4dULL, 0x41cb16cdede1750eULL, 0xc079f0fc98bb6a11ULL,
479
    0xb6aa18d94d9b37baULL, 0x1647aa4c407d1244ULL, 0x8c705a13349e10c3ULL, 0xce30a5c3e1dabee9ULL,
480
    0x2d6ca598c617b183ULL, 0xca21c9cddd1af110ULL, 0xb5e68f6381dacedaULL, 0xd9c61ec96684461fULL,
481
    0x0b1fa1bcae112ee1ULL, 0x154042c24e0404c6ULL, 0xb4efbfbf8ea0e4f8ULL, 0xfd436a8b275b1c15ULL,
482
    0x47dacd95f41bd571ULL, 0xf7714e0b7756278aULL, 0x559e24fc8d287691ULL, 0x91c041e4c56036f7ULL,
483
    0x1f6578f865919a79ULL, 0xc8cdcdd242fab4d9ULL, 0x28302a7558bebb6bULL, 0xa6fbdd97c0895919ULL,
484
    0xcbadb431be485173ULL, 0x703991cf429a8bbdULL, 0x9ec19ced4781bba6ULL, 0x94af792408408df7ULL,
485
    0xabed4ed1677c86e1ULL, 0x0f6e9cbb41089de3ULL, 0x3c88eacbb947dc3bULL, 0x99b3fbd4c65fe1cfULL,
486
    0x034cd4892067845cULL, 0xbcabc47135a8c209ULL, 0x8d553cd1b31bed9dULL, 0x0d8a566720267700ULL,
487
    0x3bed637a9a370afdULL, 0x41494335f1d0adfbULL, 0x9f12bfff16b28edeULL, 0xce6453efe358988dULL,
488
    0x2215954804510ab6ULL, 0x6b4394e84989f5f2ULL, 0xca8c91dd50847010ULL, 0xa947c7e59c35417aULL,
489
    0x8f95c01ab298ec1eULL, 0xe95721786359e315ULL, 0xb4a2d874cec85136ULL, 0x7f1f7f8bce470897ULL,
490
    0x7437e83c9fd5e424ULL, 0x6eeb30c64a162b8cULL, 0x23c1516503b4f507ULL, 0xcb321488c3757420ULL,
491
    0xcebed99b362fd959ULL, 0x6c127ce789a52e6dULL, 0x980b79769c8813e0ULL, 0x26c25f71471c7e54ULL,
492
    0x53934724e51cc126ULL, 0xd8680dabd6b9d852ULL, 0xd1bacb3c3b6f4daeULL, 0x2597310144a51aadULL,
493
    0xdb11576656984ffcULL, 0xab667b46feae063cULL, 0x503558ac4b13be6fULL, 0x3a3e7d2c081594d7ULL,
494
    0x4157037c0c54ea64ULL, 0xf6126e71ad203300ULL, 0xc3f04d0b97cad0fdULL, 0xbff96410f693d8b3ULL,
495
    0xac6ae032fbaab91eULL, 0xc00eeb6a400bb962ULL, 0x2477bdbbcf3a2976ULL, 0x094c7b15ce23247cULL,
496
    0x01e71a4167f69b90ULL, 0x6e29b4138facff1fULL, 0x565686f589cc4d65ULL, 0x73f81ca8ebee9fcbULL,
497
    0x05a346d75398ffb3ULL, 0x4a69fb255d62ed90ULL, 0xccced0c1106d1c93ULL, 0x625916cfa21515e0ULL,
498
    0x6f8ee1626c380dc1ULL, 0xf2e16898283cd0c3ULL, 0x727321be23832a2bULL, 0x43441f936eeb2d87ULL,
499
    0x14b45b1ecb3f7714ULL, 0x7ddfc1f328929f1aULL, 0x2d55a0468e13ec26ULL, 0x21dd2c1f3057970fULL,
500
    0xa6e1a5ce99fdd971ULL, 0x701c90f12059e247ULL, 0x1b7ae58e5c64ff4cULL, 0x05de117111a62053ULL,
501
    0x137b6510a83e5ca8ULL, 0x07fc44272c5becf7ULL, 0x0f16dafab947f490ULL, 0x0895b0033e5e8900ULL,
502
    0xeed683f7b95fd966ULL, 0x46506e5194dc9ccbULL, 0x408031d8bc251a31ULL, 0x26f999eeac14cfd6ULL,
503
    0xc720d88aaede1459ULL, 0x1339ca054c720e1dULL, 0x70111e113ba72600ULL, 0xdb22a28a6dc25133ULL,
504
    0x72e937c0bff13900ULL, 0x107808448080fbfaULL, 0x34f3338c200fdb4fULL, 0x4a0eadbe656dbc83ULL,
505
    0x84dd6549f109d3bfULL, 0x746c4aecbae19826ULL, 0x513838a22e0cfe1cULL, 0x11b8f4b8fa368a3fULL,
506
    0xdf6d5ae667795071ULL, 0xcf130962ae8c6607ULL, 0x82858c9a6b5d69e9ULL, 0x1da5a0a49b579480ULL,
507
    0xd84db8c20e132aa6ULL, 0x0c3b0392ff2e1e63ULL, 0x912d3070ad153aa2ULL, 0x6d8ff71426c0d062ULL,
508
    0xdbed3534b24e6bd3ULL, 0xa876821775929182ULL, 0xcdaa7d29acfa4a83ULL, 0x10333764a610f69fULL,
509
    0x63e24d99bc37a324ULL, 0x8c25823bad7029f5ULL, 0x2ef28a1deece6115ULL, 0x32b90c23208a0008ULL,
510
    0x723589f592ed6591ULL, 0x00c7516ed0d83959ULL, 0xe0fc684a298682e4ULL, 0x36fa668e47c35a84ULL,
511
    0xe9b3118ed5043e35ULL, 0x75d8783d5a29f16aULL, 0x7c3c86fa947f09aeULL, 0x56f2a5e6daf19aaeULL,
512
    0x00900521d0b38f6cULL, 0x26fa3cdcdd8cabc0ULL, 0x4a83b4473548d939ULL, 0x784f302daf6e022aULL,
513
    0xe46c4deeeb312976ULL, 0xa9b98bd7ba7011adULL, 0x64c14cfea7abc8f5ULL, 0xc1497eb0406690faULL,
514
    0x9511d4de569276efULL, 0xabf024a50a90b64aULL, 0x49b19b07c3e22da3ULL, 0x706bd69e20520907ULL,
515
    0x894b149339d83ad9ULL, 0xbcf1438efca42924ULL, 0xdb560b04bef14919ULL, 0x9b7482cbecc444d6ULL,
516
    0xed2bb01a83016742ULL, 0x71f684628505a4e1ULL, 0x670bcdc8f1042d61ULL, 0xa8f134df95b5d080ULL,
517
    0xffb794a24165093fULL, 0x50d032fa1d662fb4ULL, 0x2810a6f28ffbb86fULL, 0xe67681ca3f1c85c7ULL,
518
    0x03cb85ef8d956f64ULL, 0x1738ad2440ba2ca9ULL, 0xd0407f7f7463398fULL, 0x160b8d8af7dc2f9bULL,
519
    0x0405a3e372380b98ULL, 0x6c7e379ee9d8b82dULL, 0xdc4fe04fd1875ffeULL, 0x7d644123159cfb27ULL,
520
    0x49606435071bb986ULL, 0x90996d41b01eb18dULL, 0x5183897c42d1975eULL, 0xf56aeaa393372306ULL,
521
    0x3e61ec92c30aaacfULL, 0x325b84d16be4df60ULL, 0x1e5bca8358d2da94ULL, 0x6b927e82bfa69929ULL,
522
    0x085ad4d97f3dc0cfULL, 0x8cae40fec0c216aaULL, 0x764c17024ef6c979ULL, 0xc96b7917c5ab12b3ULL,
523
    0xb1f58a09d022290fULL, 0x4549907a6ebf95f1ULL, 0x1d00457d45793c60ULL, 0x0d4301ba9f5832cbULL,
524
    0xa2836b7853af8349ULL, 0xba9f1018ecdd2d0fULL, 0xf3f596aada6e690dULL, 0xc6649514b3e81409ULL,
525
    0xb6d8a6c7ebfe4afcULL, 0x115175cfa1169485ULL, 0xe4a59f8ae8f01b9bULL, 0x05415ed13bb46446ULL,
526
    0x8902f6711e2897a9ULL, 0x1ea71ce7028495e6ULL, 0x34fb7b46530d0bc3ULL, 0xb244f37d544d11b4ULL,
527
    0x4b7706d4e0d4a2c8ULL, 0x28e623ef474904f5ULL, 0x961ebd4357a2a031ULL, 0xca8ddd9ea423647fULL,
528
    0x3c3aea6f91215fbaULL, 0x2c89ecf10fe90db9ULL, 0x823e33b306ce8675ULL, 0x66dbe9c27aa0cbc8ULL,
529
    0xa5393f1e6a80d339ULL, 0x68b115fc5b13af32ULL, 0x4a5a983409430b7cULL, 0x30b18f3cfdd3c98eULL,
530
    0x929ddbbe3a82803eULL, 0x64ccccd7140f4a9bULL, 0xd7f803762450fec5ULL, 0x832e6ceca2780550ULL,
531
    0x7c6840451f7a0143ULL, 0x02655066b6f784e9ULL, 0xee1659bae59fb670ULL, 0x4542a44ed14050fdULL,
532
    0xe4f07584584e1e14ULL, 0x83dc19959c56dee9ULL, 0x8aeb3988a882c1c5ULL, 0xe19b46fed3c4f2bfULL,
533
    0xce1258daee0a0946ULL, 0x247c26799366976aULL, 0x10acf6eca81488a3ULL, 0xa7ad75899d582d56ULL,
534
    0xe315be1a51f538ffULL, 0xb5be8993675b7872ULL, 0x3db8d2d7608bbde8ULL, 0x9ff1c2c3ce3ceac1ULL,
535
    0xeeecc280de870e1bULL, 0x5d77564297d99e2aULL, 0x4c3f25277aa1a701ULL, 0xff06a70466279913ULL,
536
    0xc026377450f01f65ULL, 0x1b2494641bf91608ULL, 0x5f1b74fb08c332b9ULL, 0xea2c64e3db9f9057ULL,
537
    0x9d4f807cbff85025ULL, 0xcee8670f094702b7ULL, 0xf340eef21642e7c3ULL, 0x19606d55ebe426beULL,
538
    0xed97dc58e1711875ULL, 0xa417f28f24dea798ULL, 0x11cd6acb68c72546ULL, 0xf1921aac289d9dd6ULL,
539
    0x6bd0fcfc448bc595ULL, 0x3e1f240d8fdc4618ULL, 0xa3828d7a1ff27fc8ULL, 0x46a4b0335abbf426ULL,
540
    0xdf7115c761657e18ULL, 0x3d28f804775cffc4ULL, 0x30342adb438b9c69ULL, 0xb9937f6ce61ea1cdULL,
541
    0xd4b5567c46873e35ULL, 0x940200555367edb0ULL, 0xb9d944f5f979e14fULL, 0x3b8bd9a0316d97b1ULL,
542
    0x96798a6bc116783eULL, 0x39acfcb474f282e4ULL, 0xdb94a39f58a94510ULL, 0xaa7980b4175d122fULL,
543
    0xc9efca1c00e61953ULL, 0x33de221d4b8295e7ULL, 0xf2c235e73e3b2542ULL, 0x83215ca5453dcb65ULL,
544
    0xf58ff8a8df56fb2dULL, 0x09559195c7cb434eULL, 0x1161fe1c7f8f7187ULL, 0x148818fc6eaca639ULL,
545
    0xd5298696e9d8cc30ULL, 0xfa6b53e9a9d6a4c7ULL, 0xb7cfd2c1d2ed429eULL, 0x33df557fb7aa966fULL,
546
    0xe556777cddbba676ULL, 0x05c1c1887877a56eULL, 0x2e89de6e661bd34bULL, 0xa17a85d2b115f694ULL,
547
    0xa807afd9ce6c2628ULL, 0xa555ddd592ebdf55ULL, 0xf1b79535a4a444e6ULL, 0x6778915e7b1823c8ULL,
548
    0xd0bceed9f840f9c1ULL, 0x5760eb1fe0d2758bULL, 0x342d44714e3c65b9ULL, 0xed7a362bcbe6feb6ULL,
549
    0x1705103c42821aedULL, 0xc501924ccd211bf5ULL, 0xcfe2ea8d5d1b6856ULL, 0x24ae2eb2f6bfc818ULL,
550
    0x7fb97dbbee485d64ULL, 0xd64b84c4aeeb08d0ULL, 0xe2fd0cc4a47204a0ULL, 0xaf55b1facc3987a1ULL,
551
    0x1dfd4be371d6f91aULL, 0x20fda8869c9263eeULL, 0x999bd21d8576298aULL, 0x1eb57256cbe60d94ULL,
552
    0x4dceb0738230ace0ULL, 0x2dcc0846f5f39d84ULL, 0xbf22300cf9173002ULL, 0x5a1aa9b8743c632cULL,
553
    0x9070299e5bbf03ebULL, 0xbfeb907c9407f326ULL, 0x190423598b0cbaf6ULL, 0x309e4bf71e4c443bULL,
554
    0x79ec14272ad6eeccULL, 0xc80fc37f51135e15ULL, 0xe648d34336875121ULL, 0x773e4ab9e8b0acc0ULL,
555
    0xfb44a070ffd3a52aULL, 0x10696674757da91bULL, 0x41a63ec5b12cede6ULL, 0x4028279f3697edc4ULL,
556
    0xf968fbc2fabe7cc6ULL, 0x8d7f9f58b58c124cULL, 0xd8ea949dbab5a05dULL, 0x54bd7bbd38c9b3afULL,
557
    0x474005f184ab67ddULL, 0x3d5607cf170fb906ULL, 0x7d5c3e449ecf9a7bULL, 0x64252034d8f92f53ULL,
558
    0xbc687bb81f55f180ULL, 0x192de7c9da91f403ULL, 0xbeb7d9e0019a8b18ULL, 0x7db48efae4df737cULL,
559
    0x175ec9517c5c4c0eULL, 0x717a7d0ebda47f15ULL, 0xa587e3e6f2b8e954ULL, 0xab2cd98817f315e2ULL,
560
    0xcc0e745d179b1998ULL, 0x6649139d5d71f1d0ULL, 0xfcc5b6186974a8f5ULL, 0xa7059f06a374e713ULL,
561
    0x213cef524ef7b75fULL, 0x281fda3316b40c85ULL, 0xeebd55e267534c75ULL, 0xcab02b62892df3b9ULL,
562
    0x3b808869d5a722a5ULL, 0x4d97222b49abd9dfULL, 0x4ddc171d34629f30ULL, 0xd3752bcdc5ef181dULL,
563
    0xab4d39c6aa8a5ca7ULL, 0x6ba8bd4d5cb06082ULL, 0x583d4de08802857dULL, 0x026c5618433aa7edULL,
564
    0x1232c81cafbfd167ULL, 0x5a33e75840166131ULL, 0x3ea02e990724ef4dULL, 0x3951fad4b82928bcULL,
565
    0xf1e92e7fb0846900ULL, 0x15fed7db76b1e8feULL, 0x5052710ed579d80eULL, 0xd783125e16b47e73ULL,
566
    0x98d8b7da8bdc9c2bULL, 0x98ce50243f35581eULL, 0xb141d678f827a0d4ULL, 0xb0f8e3094f49fa61ULL,
567
    0xab19151f7a7cdb52ULL, 0x6ba2c537f521a4f1ULL, 0x1ade518a3d9c178dULL, 0x8500515c23f51115ULL,
568
    0xf3cc5c2fefd7a98dULL, 0xd8bbbb3e9ae20b79ULL, 0xf871825bb7ac5147ULL, 0xbb781a17cca93d0aULL,
569
    0xf3575106b160c93cULL, 0xf844c703f58f2e1fULL, 0x2a5c72d4367ca657ULL, 0x99d7c01cf853ec21ULL,
570
    0x1a6f335ad74dfff5ULL, 0x4fbdc8c120b994f2ULL, 0x408461eb155418cdULL, 0x157916359ffe2c1eULL,
571
    0x525f1a7db4223dbfULL, 0x25c3000b1e90fb19ULL, 0x57bdd0c1d663fa2dULL, 0xfb802e7119bfbe24ULL,
572
    0xaae1c35ec6eb14c4ULL, 0x652583024fcd306dULL, 0xe8be1108b58af685ULL, 0x77a89f20ae1f8a94ULL,
573
    0xbc22aa4ab340e4bfULL, 0x78bfc970c96c221cULL, 0x1d3f7809a295ee76ULL, 0xda430da50a13a883ULL,
574
    0xc1306bf82a441264ULL, 0xe31afb1e6fd6451cULL, 0x3a2d9759aa34eeb3ULL, 0xbf5ceaf7ab48104dULL,
575
    0x3400ed26b9495770ULL, 0x3b296387eb154befULL, 0x1c93c216ecba4af5ULL, 0x5a34070cf1e792aaULL,
576
    0x42c9d7c5a3609633ULL, 0x4379936a9a13d21fULL, 0x84e2a6c2f892c5d7ULL, 0xb23b8143286b71edULL,
577
    0x7d2a12b06074cab3ULL, 0x8540d38e599343fbULL, 0x3b3b8f9db8e41f17ULL, 0x161e4e09e20ab0c6ULL,
578
    0x162298b0f8723d99ULL, 0x9afbdb3f8b032893ULL, 0x5ec3f04936e0883aULL, 0xc50c2bce3a56ef64ULL,
579
    0x4460c752721c55d4ULL, 0xf015b1f777a6afdcULL, 0x06f1e56f14c48c36ULL, 0x33e7235f85296282ULL,
580
    0x06040eb1efdd11b9ULL, 0x346b7f7b751f66f3ULL, 0xbb4fa9a8e6d1d035ULL, 0xe1d3d700a82e48d5ULL,
581
    0x8135cfd26c74b440ULL, 0x65d5d35b5696f10cULL, 0xbf9838f966bb07e8ULL, 0xebd2eb4bbcb43720ULL,
582
    0xbbfeec86250e9350ULL, 0x66aba8170e00c52fULL, 0xabccc4a86f130675ULL, 0x2ca5716416ed7185ULL,
583
    0x010b20c0e57bc195ULL, 0x2fe60878da02ad71ULL, 0x1b0fef55ed00184eULL, 0x1261c170eeb052b6ULL,
584
    0x6a13113537136749ULL, 0x61c36852fc8ed2d0ULL, 0x3792d791924af876ULL, 0x5ec74fb3066e0ab6ULL,
585
    0x08e5788888816a21ULL, 0x238b94c0003b284dULL, 0x7d712871cee92534ULL, 0x4848d5aa004ba38aULL,
586
    0x1205c02c9b1ce8e5ULL, 0xba3aac58d085586eULL, 0xb0fa368bfeb857abULL, 0x29046208a0f9a5ecULL,
587
    0x7e9cd0525a6a8cefULL, 0x205f2c43beab7fc5ULL, 0xd6a2d6213b8fd0f3ULL, 0x0897451e05d3e003ULL,
588
    0x37df4af89203d875ULL, 0x103862149234cca6ULL, 0x19953ac4237d4439ULL, 0x4a089784e1bad7d8ULL,
589
    0xfefa933f9266f384ULL, 0xd7153f3f27c9855cULL, 0x82dfe8503c066585ULL, 0xd1b163cce1e1794cULL,
590
    0x50a0c5f3b4e0185aULL, 0xc1aa0810e07a4a11ULL, 0xf923c43f65456424ULL, 0x725076b178a0cec6ULL,
591
    0x6a8ffed38d48e8c1ULL, 0x98c7d98b58632ce9ULL, 0x10d9eaa19eb6646dULL, 0x09d53df4e86ed7c1ULL,
592
    0x351546a5962fd169ULL, 0x9a9e3300af4c96b3ULL, 0x2c0efad71fe68509ULL, 0x55465603290e4df8ULL,
593
    0x3c6a5b9948795195ULL, 0xdec4cbaf18698cb6ULL, 0x22a7fc751a85732fULL, 0x237aca9e62b6ee42ULL,
594
    0x3ec48c5a1a0eeadaULL, 0xdca8d6c1752a75b0ULL, 0x551d35ee59e8df71ULL, 0x6abcfa8e5bbce350ULL,
595
    0xe572c1e3e84c1878ULL, 0x735166f77889b868ULL, 0x4fa1a3b5f083865fULL, 0x8e681cc7db9e5cc1ULL,
596
    0xbdd3e56d0c286e7dULL, 0xb0a86df0d313440eULL, 0x1cf34137a8f0dd3dULL, 0x489c25283ca067b7ULL,
597
    0x0c1ca8135db56e13ULL, 0xff7e6858fcd20f2fULL, 0x2a920c1a2fb1c744ULL, 0x49ade1415c0f4579ULL,
598
    0xc87e5ccefb5965cfULL, 0x210c7df122a3a8d1ULL, 0x01ba3a70643d903fULL, 0xe07ccb713c01a278ULL,
599
    0x62c4a7883e9408b6ULL, 0x5ee17e7a19fe78dcULL, 0x0ae510b98403b793ULL, 0x21557b4ba5db3c1dULL,
600
    0xdb9583eb7765f872ULL, 0x1d81a84105cb6a78ULL, 0x8083f770c8a9ba2eULL, 0xc26d49a4d229f025ULL,
601
    0x71296a23163a7939ULL, 0x3c5c70a50a4f78afULL, 0x0764005abc6939e0ULL, 0x8789dc959a95e3a7ULL,
602
    0x3d33823ef2e4667dULL, 0xac0d4840351a939aULL, 0x3a1e288f96e7befcULL, 0x0b0acf1eeb03e0e6ULL,
603
    0x5af734f93a1f45abULL, 0x26a757c07ebb8db1ULL, 0x213234b390a5ea73ULL, 0xde773d9c51af6f74ULL,
604
    0xd49f3afe03115a77ULL, 0x5f633306505f406bULL, 0x02e449a05a0562c0ULL, 0x314666b3bc46b3dfULL,
605
    0xece9fb5e19a2aa37ULL, 0xe6c59b7170283f22ULL, 0xb46eefb8b8a61f82ULL, 0x096a87d165af2088ULL,
606
    0x39c222e996b6f76dULL, 0x6a36fa7cea8230f5ULL, 0xae8e037994cad44fULL, 0xbab83290685556c1ULL,
607
    0x4647f6a1aee27fedULL, 0xf7555e9a540b8d18ULL, 0x40b059b1ceb14081ULL, 0x079823a46fccb19bULL,
608
    0x52149b6c54c621a9ULL, 0x179d81ca92e38367ULL, 0xa4b7a879aeec1968ULL, 0x46bafea8e15407b4ULL,
609
    0x7b82184063a31cb8ULL, 0xc2a7d35965bb02d9ULL, 0x20a1b2b01c93ecc3ULL, 0x9f20f598305af5eaULL,
610
    0x0be76e68eabbfb22ULL, 0xe45c23075b6a5c1eULL, 0xa2804a249b3cf0c0ULL, 0x48afb9bef6c4e536ULL,
611
    0xce14af50e72e33d6ULL, 0xb3b78d21e4c01949ULL, 0xda9c1933e182091eULL, 0x848482ce26352dcbULL,
612
    0x800ff9ef2e1b00ddULL, 0x878c5d32481c244bULL, 0x1c6e9aa00137637cULL, 0xf872c37c83005a46ULL,
613
    0x7fa48f34e9f56c13ULL, 0x2ace3766cddcc711ULL, 0xc17b1e2d4baf85abULL, 0x76ceade0c91a543aULL,
614
    0x9056b0651be35aabULL, 0xd1782c9c5d85ef5eULL, 0x10200abecac6936dULL, 0xdc32c02478a5d493ULL,
615
    0x312a8b39d2e30863ULL, 0xe90c092fb5e7fedeULL, 0x05a0a4173c2a42faULL, 0xa306c98b558ec17fULL,
616
    0xa5c0b6af2641fe9dULL, 0xc0988090c5d6c130ULL, 0x83cf195ea8474febULL, 0x11d4ad1165868aa7ULL,
617
    0xb7a6fc6bfe40f3f9ULL, 0x344debcb5d483760ULL, 0xb01627e1b014c80cULL, 0xee324b6baa3b32eaULL,
618
    0xcdc83a3c452b5cb3ULL, 0xf491453b385a69abULL, 0x9c2c3555a589cd4cULL, 0x5aa3bc66d8cd5cf7ULL,
619
    0x9b1f928b19ba6b0bULL, 0x8c84e00fd7f06d9bULL, 0x3fad17cbd0278447ULL, 0xeb7a41f56e2c5f2eULL,
620
    0xfbc63c4d2c6c3965ULL, 0x9ab96ff21a641a28ULL, 0xa832bf87b363fdc4ULL, 0x2b812317410a4379ULL,
621
    0x2bd1c5e152843155ULL, 0xcc24d8b28bc935b7ULL, 0x3fca0d25fdff806bULL, 0xefd4afea47bf0930ULL,
622
    0xd16793374903e8c9ULL, 0x48af011da240633fULL, 0x9e3a22216c89b468ULL, 0x50689dc217481424ULL,
623
    0x4b43c0dc7b5fbce2ULL, 0x30be1725b1412644ULL, 0x8ad173e150b56693ULL, 0x23ec5789dac251eaULL,
624
    0x1ba4f07a78684deeULL, 0xe14d05d473a5f091ULL, 0x2e5646f0688fc5d4ULL, 0xcc6055f3bb092632ULL,
625
    0x84c0232dfe2fa15bULL, 0x3a948cc8bca8f4d4ULL, 0xebbab53f8b2cd488ULL, 0x8e355721af8e4399ULL,
626
    0x8bab9ede93d1efe6ULL, 0x6bd30d7339afa1faULL, 0x1dff66a347f8b750ULL, 0x820d0ac4c04a5431ULL,
627
    0x00945bfeaa4da653ULL, 0xf65203cde1c67a14ULL, 0x64017b1f6d7660e6ULL, 0x4c23fe7c46272a2eULL,
628
    0x610365dd8fa1e5b2ULL, 0x26e1842faf459b6aULL, 0x1f961aefb6770961ULL, 0x09c3397165c36f30ULL,
629
    0xf2136ef9fbc45fc2ULL, 0xe88d6dd9adcce726ULL, 0x8d003d5edc84418cULL, 0x7c4d6b6c3d7304e9ULL,
630
    0x88ae6ae8726245a6ULL, 0x3412f396edea2b07ULL, 0x2f65e37016e9a869ULL, 0x8df912cd07f489e3ULL,
631
    0xe6af3fc7b992ac5cULL, 0x198b75fd3330c88cULL, 0x920edd264d30bab5ULL, 0x7f1fa0d7af191e17ULL,
632
    0x395d8a980e403790ULL, 0x8a402b7b2acdca5eULL, 0xc030e6695e214c9cULL, 0x22e0dcf37ff4c145ULL,
633
    0x2111f336bab565bfULL, 0x61a2770d697989e9ULL, 0xcba8f5b67005f6ceULL, 0x1a0a499cd71b0ef4ULL,
634
    0xa9dcc2c35a4f3905ULL, 0xfca509f2c373804cULL, 0x82b2185d68a7d270ULL, 0xc90f71c6982e71dcULL,
635
    0xa0fbe5e49cc20e03ULL, 0x8cbb93a5ee1bf578ULL, 0xab98e26c684fafb9ULL, 0xbcfc7f32ed9e9d0eULL,
636
    0xd7c39e4893d23142ULL, 0x29367a1a9aaa1c65ULL, 0x5909c56f588f7685ULL, 0x65c3930d9faa698aULL,
637
    0x802d369653fd8b5cULL, 0x2f890d4546b8f490ULL, 0x1346134080dd7835ULL, 0xe3eb6fbab330b08eULL,
638
    0x77dbb5da01eb53f4ULL, 0x377171d4350c661eULL, 0xea1161836a59ae79ULL, 0xa6feebb40ae5f830ULL,
639
    0xe6cc130af9337850ULL, 0x9c1120b73bb280aaULL, 0x2fed2c970fa8f45aULL, 0x80300f25880b1c84ULL,
640
    0x9c2abb0207dce1afULL, 0x58569aac7cb10a43ULL, 0x0f7546be97cab5acULL, 0xf87857864a1061afULL,
641
    0x4996455690b6293eULL, 0x8f35d2d6a5c426bbULL, 0x076f2bab8ffd52c6ULL, 0xbe48212ad0b9c51aULL,
642
    0x80d0e7ba33bf2edfULL, 0xc30f0aa8957168f7ULL, 0x253729f26a5a53b1ULL, 0x503df089f39c8e42ULL,
643
    0x88f857d06544265fULL, 0x3c61e1a5d4aea8a0ULL, 0x4fa7d9282963c1beULL, 0x03678fa2487bb947ULL,
644
    0x5d2492f527aefb51ULL, 0xcf0a306c104d0364ULL, 0x5be920772cad0c02ULL, 0x37705f8902c5f913ULL,
645
    0x6d1624633bd07072ULL, 0x4b5017f055f75d27ULL, 0x619a4b5f06babf49ULL, 0x53a53263a185b4c2ULL,
646
    0xe808f04864e997ecULL, 0x3868f76efc5ee1e8ULL, 0xb6c4f39fe63c108bULL, 0x7910f9529f2a051eULL,
647
    0x3a1e8bf70918df16ULL, 0x60ce2ad57e56893fULL, 0x8ffebebb87334674ULL, 0xf2d1e502e685f6f0ULL,
648
    0x802c514db9b0ee0eULL, 0x266a15b5e189ac9aULL, 0x9654b4dd610a5ac7ULL, 0xa7e6a2acb6522521ULL,
649
    0xe1452641949e3aedULL, 0xf852eb37d8292272ULL, 0x23440b894539e2dcULL, 0x3de3135d2480e2eaULL,
650
    0xf35b2a0a2e456d6cULL, 0x457c0694aa06eab7ULL, 0x10f8f60e000d20c4ULL, 0x3ee2e03bfccde830ULL,
651
    0x4bd6b8c76b8c2078ULL, 0x14a004df9b5c767dULL, 0x6465d9f58082ef7bULL, 0xacfef0a936ff1047ULL,
652
    0xe5044ad195710642ULL, 0x773310d1465bdb40ULL, 0x98cd081351af90edULL, 0xbdd24a947f995f9eULL,
653
    0x0b783c8add1fdcbfULL, 0x4c07f0d821ffe777ULL, 0xf9649e68057f1071ULL, 0x92b9fee00900c1dbULL,
654
    0xc10cd24cf919e4fbULL, 0x430da99db7548368ULL, 0x9ffbc57261a9bf18ULL, 0x93fe31caceb19a49ULL,
655
    0x3ff9497f33400965ULL, 0x355923fa7f6dfaa8ULL, 0x82b2de4000477a0fULL, 0x9f36510c4db52a2fULL,
656
    0x35fe019be7ce0446ULL, 0x854b79c6cf45d796ULL, 0xc7a8669ed85eab29ULL, 0x0616cc03ef9f5883ULL,
657
    0x05f32f21e7e08c08ULL, 0x3d7b96cc202021bdULL, 0x294d253dd6250389ULL, 0x396b20c1c40fbcd5ULL,
658
    0x924d5b892e00f5aaULL, 0x46f663fd7afec7b9ULL, 0x2dcb4fed2f62cf54ULL, 0x867656fb399a763bULL,
659
    0x6e645b42b0ed3df0ULL, 0xefbda0a959a82efaULL, 0x1e57f0d772fc387dULL, 0x0674d8a0f91d418fULL,
660
    0x7d505da665fb9ed1ULL, 0xb92f926e73571550ULL, 0xca4afd00ae0f2651ULL, 0x4ebfad7e532820f1ULL,
661
    0xc98143a7869aa213ULL, 0x659e2fb4bcff90a7ULL, 0x11ae0639334eee27ULL, 0x83e7533307ff2e6fULL,
662
    0x60f5f716547d8cc3ULL, 0xc4bfead179135b68ULL, 0x08f766a9a3a8de62ULL, 0xb684258554ee0537ULL,
663
    0x4891d873f8e3e0feULL, 0xf54572e5ac0b3a3cULL, 0x977a735beb8878cfULL, 0x4be958fbc1d86455ULL,
664
    0x0d7de03cb6629efdULL, 0x7b2c68ae5c970120ULL, 0x5ed392cce09f00e4ULL, 0x7da97f4ab6824d5bULL,
665
    0xa23b535e2b4a30c3ULL, 0xcbe9d4ab2a70eeccULL, 0x158896735f4e2fccULL, 0x83df96151a52fc84ULL,
666
    0xa6a2844c5b1131c4ULL, 0xe4e63b91dbcf8115ULL, 0xc83c4b75bc1a5b80ULL, 0x09f3cd287f693d64ULL,
667
    0xa366a3a824cec2f0ULL, 0x7e17190295ea7e8bULL, 0x65d4cb9fc6225bc2ULL, 0x29c5a0905e3c2736ULL,
668
    0x68e90502619dbf85ULL, 0xc1c427d5896e405cULL, 0xfa4afc8f8de8ecefULL, 0x8e5301dd532114e7ULL,
669
    0x933156b65ee4a918ULL, 0x76fd40da0354fd37ULL, 0x295d788895520e8aULL, 0x82d8f759909f819eULL,
670
    0x6f8be0b29b366883ULL, 0x57192fcaf5eb578aULL, 0x86a3f9fa0fd932f0ULL, 0x3a9712777a36e539ULL,
671
    0x4e9a81b491b610d4ULL, 0x112ab256f111f7b3ULL, 0xeb18a646723db641ULL, 0xf5df4391e176cfdfULL,
672
    0x0988c3ae0a878c1eULL, 0x83eee968ca9994a3ULL, 0x2f87a0054d15a108ULL, 0x8e8f6ad28a52fb62ULL,
673
    0x4506387e508b536eULL, 0xf4be16fd24b9def7ULL, 0xccdee07b69cfc3dcULL, 0x1d61f742a60333e8ULL,
674
    0x2bf5dd9169aa7f01ULL, 0xc226cf16c071fa2eULL, 0x817f04841559b8a3ULL, 0xf6af48567c6e78c2ULL,
675
    0xcd804be16811e77bULL, 0x6b397f055a9882efULL, 0x088fda249f941a3fULL, 0x6dbf67f07092c293ULL,
676
    0x1645327035a2bd54ULL, 0xc39c205b04ec4e8dULL, 0xc01c17f1dbd0fc6aULL, 0xa28db4ab9710fa3aULL,
677
    0x7d90dcc1fdbb11c3ULL, 0x103546bdb065c73eULL, 0x8141482edf322617ULL, 0x4a346c9c5f8d353bULL,
678
    0xb383563ab40c28f6ULL, 0x02d49f9b654646e2ULL, 0x40cf6a1d632f905cULL, 0xc79b313acfb4b5f7ULL,
679
    0xef662c62dca07ef1ULL, 0xcef5d422f7659834ULL, 0x8c73e6fb1b697f4eULL, 0x7231cadcef269eadULL,
680
    0x9951b99f01fb70f1ULL, 0x536778b8e9f3b25bULL, 0xa75da0d5cb39c1beULL, 0xabcaba5e733f76a3ULL,
681
    0x5a3b1f3f07d061f6ULL, 0xb96c2bd8a2f04332ULL, 0xb9205d72024398b9ULL, 0x7b3dee2a6799b3bdULL,
682
    0xaa9c6adb7db1a38aULL, 0x08b635cdf28e5f5dULL, 0xc915c83f2ee319ebULL, 0xcd207081bbf6d18fULL,
683
    0xd4fef1db4cd1fb0dULL, 0x481eda802b30c94aULL, 0x7b404bcd3fb72ca8ULL, 0xbedcddb701683d01ULL,
684
    0x0d0e7d869fc2a5c9ULL, 0x9f32dc09ea332545ULL, 0x932528e46eff6c95ULL, 0x3e4c75e674bd93fbULL,
685
    0x8c8391e4a1861342ULL, 0xe7ae7559f3c3c3adULL, 0x62c883f00d9e4d9fULL, 0x0bc550d471eac53eULL,
686
    0xb6b944c871a8565dULL, 0x2a01cfb60b741f8eULL, 0x49db94bdff8b73b5ULL, 0x80b474d2d8fd36f6ULL,
687
    0xa6c75296fb9f028aULL, 0xfc0f8bbf3ad79375ULL, 0xeaeb54285d08c14fULL, 0x0eef9a5fb0c3e2edULL,
688
    0x54d588939fe544f6ULL, 0x17084509804201ffULL, 0x31b8372478d93e4dULL, 0x5885e4f1e37edfceULL,
689
    0x4e1bdff27c17069aULL, 0x08a253bd9b9cb273ULL, 0x5435a8db7d2a894eULL, 0x975dafbadbaa58a0ULL,
690
    0xfdc47ff3f5f9a594ULL, 0x4323e44de8a86bb3ULL, 0x2be02fa2a15f8860ULL, 0xa0f6d6b4378d111eULL,
691
    0x628b1647a8f34039ULL, 0xb1ae42641adc6944ULL, 0xce22f3b15bbca65dULL, 0xff839edc88ee6833ULL,
692
    0x9b944c8fbaffbe94ULL, 0x4dcf12e95dbf59d8ULL, 0xd4e8006c8265fa6dULL
693
};
694
 
695
U64
696
Position::getRandomHashVal(int rndNo) {
697
    assert(rndNo >= 0);
698
    assert(rndNo < (int)COUNT_OF(zobristRndKeys));
699
    return zobristRndKeys[rndNo];
700
}