diff --git a/README.md b/README.md index 660e54b2..89766952 100644 --- a/README.md +++ b/README.md @@ -2,32 +2,30 @@ Cinnamon ========== ### UCI Chess Engine -- [Play on line](https://gekomad.github.io/Cinnamon/) - Cinnamon is a chess program for Windows, Linux, Mac OS, Android and Raspberry Pi, is a console-based chess engine for use with [xboard][4], [Arena][5], [Tarrasch][6], [Droidfish][7] or any UCI-compatible GUI. Cinnamon is also a javascript library to play with [chessboardjs][8] or any js GUI. +- [Play on line](https://gekomad.github.io/Cinnamon/) + Version ---------- -2.3.4 +2.4 News ---------- -- Chess 960 -- Killer heuristics -- Improved move ordering -- Improved Gaviota Tablebase search -- Syzygy Tablebases -- BMI2 Instructions -- Bug fix in enpassant -- Bug fix parallel perft +- Reverse Futility Pruning +- Stalemate improvement +- Trasposition Table improvement +- Bug fix in castle +- Bug fix in en passant +- Speeded up Perft +- Compilable with MS Visual Studio Useful links ---------- - [Bitboard Calculator](https://gekomad.github.io/Cinnamon/BitboardCalculator/) -- [C++ thread pool](https://github.com/gekomad/BlockingThreadPool) - [Auriga Distributed Perft](https://github.com/gekomad/Auriga) - [Web Eval debugger](https://github.com/gekomad/chess-engine-eval-debugger) -- [Android App](https://play.google.com/store/apps/details?id=com.github.gekomad.cinnamonengine) +- [Cinnamon on Android](https://play.google.com/store/apps/details?id=com.github.gekomad.cinnamonengine) - [Cinnamon on DGT Pi](https://www.digitalgametechnology.com/index.php/products/revelation-ii/533-dgt-pi-chess-computer-for-dgt-e-boards) - [Clion IDE](https://www.jetbrains.com/?from=CINNAMON_CHESS_ENGINE) @@ -35,6 +33,7 @@ Useful links Features ---------- +- [Elo ratings][3] - Available for both Unix, Windows, Mac, Android, ARM and Javascript - UCI protocol - GPL 3 License @@ -44,6 +43,7 @@ Features - Rotated bitboards - Null moves - Futility pruning +- Reverse Futility Pruning - Delta pruning - Razoring - Interruptible multithread Perft test [standard][9] and [chess960][10] @@ -53,14 +53,12 @@ Features - Killer heuristics - Lazy evaluation - MVV/LVA -- Two-tier Transposition Table +- Transposition Table - Aspiration Windows - Late Move Reduction - Ponder -- Open Book (Polyglot) - Gaviota Tablebases - Syzygy Tablebases -- [Elo ratings][3] Binaries ---------- @@ -71,35 +69,45 @@ All files are compiled statically, no further libraries are necessary. Command line tools ---------- #### Perft -`cinnamon -perft [-d depth] [-c nCpu] [-h hash size (mb) [-F dump file]] [-Chess960] [-f "fen position"] ` +`cinnamon.exe -perft [-d depth] [-c nCpu] [-h hash size (mb) [-F dump file]] [-Chess960] [-f "fen position"] ` Setting `-F` and `-h` you can stop (Ctrl-c) and restart the perft process. + #### Gaviota DTM (distance to mate) -`cinnamon -dtm-gtb -f "fen position" -p path` +`cinnamon.exe -dtm-gtb -f "fen position" -p path` #### Gaviota WDL (win/draw/loss) -`cinnamon -wdl-gtb -f "fen position" -p path` +`cinnamon.exe -wdl-gtb -f "fen position" -p path` #### SYZYFY DTZ (distance to zero) -`cinnamon -dtz-syzygy -f "fen position" -p path` +`cinnamon.exe -dtz-syzygy -f "fen position" -p path` #### SYZYFY WDL (win/draw/loss) -`cinnamon -wdl-syzygy -f "fen position" -p path` +`cinnamon.exe -wdl-syzygy -f "fen position" -p path` #### EPD generator -`cinnamon -puzzle_epd -t K?K?` - example: `cinnamon -puzzle_epd -t KRKP` +`cinnamon.exe -puzzle_epd -t K?K?` + + example: `cinnamon.exe -puzzle_epd -t KRRKPN` Compiling --------- -Cinnamon requires C++11 or greater, use unique Makefile to compile for many architectures: +Cinnamon requires C++11 or greater + +- use MS Visual Studio (cinnamon.vcxproj) +- use cmake (CMakeLists.txt) + +- use make - unique Makefile to compile for many architectures: + + +``` $ make @@ -126,6 +134,7 @@ Cinnamon requires C++11 or greater, use unique Makefile to compile for many arch g++ is the default compiler, add COMP=yourcompiler to use another compiler example: make cinnamon64-modern-INTEL COMP=clang++ +``` License ------- @@ -146,4 +155,4 @@ Cinnamon was written by Giuseppe Cannella at gmail dot com. [8]: https://chessboardjs.com [9]: https://gekomad.github.io/Cinnamon/perft.html [10]: https://www.chessprogramming.org/Chess960_Perft_Results - [11]: https://gekomad.github.io/Cinnamon/ + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e3ba1eeb..d9f2de12 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,38 +1,70 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.17) project(cinnamon_debug) # debug -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -Wno-braced-scalar-init -mbmi2 -DUSE_BMI2 -DBENCH_MODE -fno-omit-frame-pointer -g -pthread -pedantic -std=c++11 -DDLOG_LEVEL=_TRACE -DDEBUG_MODE -fsigned-char -fno-exceptions -fno-rtti -funroll-loops -msse4.2 -DHAS_POPCNT -mpopcnt -msse3 -DHAS_BSF -DHAS_64BIT -m64 ") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init -fsanitize=address -mbmi2 -DUSE_BMI2 -g -DDEBUG_MODE -pthread -Wall -Wpedantic -W -std=c++11 -DDLOG_LEVEL=_TRACE -funroll-loops -msse4.2 -DHAS_POPCNT -mpopcnt -msse3 -DHAS_BSF -m64 ") # bench -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init -mbmi2 -DUSE_BMI2 -pthread -pedantic -DBENCH_MODE -std=c++11 -DDLOG_LEVEL=_FATAL -Wall -Ofast -DNDEBUG -fsigned-char -fno-exceptions -fno-rtti -funroll-loops -msse4.2 -DHAS_POPCNT -mpopcnt -msse3 -DHAS_BSF -DHAS_64BIT -m64 ") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init -mbmi2 -DUSE_BMI2 -pthread -Wpedantic -W -DBENCH_MODE -std=c++11 -DDLOG_LEVEL=_FATAL -Wall -O3 -DNDEBUG -funroll-loops -msse4.2 -DHAS_POPCNT -mpopcnt -msse3 -DHAS_BSF -m64 ") # unit test -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init -fsanitize=address -fno-omit-frame-pointer -g -pthread -pedantic -std=c++11 -DDLOG_LEVEL=_TRACE -DFULL_TEST -DDEBUG_MODE -fsigned-char -fno-exceptions -fno-rtti -funroll-loops -msse4.2 -DHAS_POPCNT -mpopcnt -msse3 -DHAS_BSF -DHAS_64BIT -m64 ") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init -fsanitize=address -g -pthread -Wall -Wpedantic -W -std=c++11 -DDLOG_LEVEL=_TRACE -DFULL_TEST -DDEBUG_MODE -funroll-loops -msse4.2 -DHAS_POPCNT -mpopcnt -msse3 -DHAS_BSF -m64 ") -set(SOURCE_FILES +# tuning +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init -mbmi2 -DUSE_BMI2 -O3 -pthread -Wall -Wpedantic -W -std=c++11 -DTUNING -DNDEBUG -DDLOG_LEVEL=_FATAL -funroll-loops -msse4.2 -DHAS_POPCNT -mpopcnt -msse3 -DHAS_BSF -m64 ") - lib/gtb-probe.h +include_directories(db/gtb) +include_directories(db/gtb/compression) +include_directories(db/gtb/compression/lzma) +include_directories(db/gtb/sysport) + +set(SOURCE_FILES namespaces/constants.h - namespaces/debug.h namespaces/bits.h namespaces/random.h + namespaces/see.h namespaces/board.h namespaces/board.cpp perft/_TPerftRes.h perft/Perft.cpp perft/Perft.h - db/OpenBook.cpp - db/OpenBook.h db/syzygy/SYZYGY.h db/syzygy/SYZYGY.cpp db/syzygy/tbprobe.c db/gaviota/GTB.h db/gaviota/GTB.cpp + db/gaviota/gtb/compression/lzma/Alloc.c + db/gaviota/gtb/compression/lzma/Alloc.h + db/gaviota/gtb/compression/lzma/Bra.h + db/gaviota/gtb/compression/lzma/Bra86.c + db/gaviota/gtb/compression/lzma/LzFind.c + db/gaviota/gtb/compression/lzma/LzFind.h + db/gaviota/gtb/compression/lzma/LzFindMt.h + db/gaviota/gtb/compression/lzma/LzHash.h + db/gaviota/gtb/compression/lzma/Lzma86Dec.c + db/gaviota/gtb/compression/lzma/Lzma86Dec.h + db/gaviota/gtb/compression/lzma/Lzma86Enc.c + db/gaviota/gtb/compression/lzma/Lzma86Enc.h + db/gaviota/gtb/compression/lzma/LzmaDec.c + db/gaviota/gtb/compression/lzma/LzmaDec.h + db/gaviota/gtb/compression/lzma/LzmaEnc.c + db/gaviota/gtb/compression/lzma/LzmaEnc.h + db/gaviota/gtb/compression/lzma/Types.h + db/gaviota/gtb/compression/wrap.c + db/gaviota/gtb/compression/wrap.h + db/gaviota/gtb/sysport/sysport.c + db/gaviota/gtb/sysport/sysport.h + db/gaviota/gtb/gtb-att.c + db/gaviota/gtb/gtb-att.h + db/gaviota/gtb/gtb-dec.c + db/gaviota/gtb/gtb-dec.h + db/gaviota/gtb/gtb-probe.c + db/gaviota/gtb/gtb-probe.h + db/gaviota/gtb/gtb-types.h + db/gaviota/gtb/version.h perft/PerftThread.cpp perft/PerftThread.h test/test.cpp - threadPool/Mutex.h threadPool/ObserverThread.h threadPool/Spinlock.h threadPool/Thread.h @@ -45,11 +77,10 @@ set(SOURCE_FILES util/IniFile.h util/logger.h util/Singleton.h - util/String.cpp - util/String.h util/bench/Time.h util/Timer.cpp util/Timer.h + util/getopt.h ChessBoard.cpp ChessBoard.h Eval.cpp @@ -66,9 +97,11 @@ set(SOURCE_FILES SearchManager.cpp SearchManager.h Uci.cpp - Uci.h) + Uci.h + unistd.h + ) set(CMAKE_CXX_COMPILER "clang++") add_executable(cinnamon_debug ${SOURCE_FILES}) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG") -target_link_libraries(cinnamon_debug ${CMAKE_SOURCE_DIR}/lib/Linux/64/libgtb.a /usr/lib/libgtest.a) +target_link_libraries(cinnamon_debug /usr/lib/libgtest.a) diff --git a/src/ChessBoard.cpp b/src/ChessBoard.cpp index b5bd0902..8d572a3f 100644 --- a/src/ChessBoard.cpp +++ b/src/ChessBoard.cpp @@ -19,10 +19,10 @@ #include "ChessBoard.h" ChessBoard::ChessBoard() { + Bitboard(); fenString = string(STARTPOS); - memset(&structureEval, 0, sizeof(_Tboard)); - if ((chessboard[SIDETOMOVE_IDX] = loadFen(fenString)) == 2) { - fatal("Bad FEN position format ", fenString); + if ((sideToMove = loadFen(fenString)) == 2) { + fatal("Bad FEN position format ", fenString) std::exit(1); } } @@ -41,16 +41,16 @@ void ChessBoard::makeZobristKey() { } } - for (u64 x2 = chessboard[RIGHT_CASTLE_IDX]; x2; RESET_LSB(x2)) { + for (u64 x2 = rightCastle; x2; RESET_LSB(x2)) { const int position = BITScanForward(x2); updateZobristKey(RIGHT_CASTLE_IDX, position);//12 } - if (chessboard[ENPASSANT_IDX] != NO_ENPASSANT) { - updateZobristKey(ENPASSANT_IDX, chessboard[ENPASSANT_IDX]);//13 + if (enPassant != NO_ENPASSANT) { + updateZobristKey(ENPASSANT_IDX, enPassant);//13 } - updateZobristKey(SIDETOMOVE_IDX, chessboard[SIDETOMOVE_IDX]); //14 + updateZobristKey(SIDETOMOVE_IDX, sideToMove); //14 } @@ -68,9 +68,9 @@ string ChessBoard::boardToFen() const { int l = 0; string row; for (int x = 0; x < 8; x++) { - int q = board::getPieceAt(POW2[63 - ((y * 8) + x)], chessboard); + int q = board::getPieceAt(POW2(63 - ((y * 8) + x)), chessboard); if (q == SQUARE_EMPTY) { - q = board::getPieceAt(POW2[63 - ((y * 8) + x)], chessboard); + q = board::getPieceAt(POW2(63 - ((y * 8) + x)), chessboard); } if (q == SQUARE_EMPTY) { l++; @@ -90,37 +90,36 @@ string ChessBoard::boardToFen() const { fen.append("/"); } } - if (chessboard[SIDETOMOVE_IDX] == BLACK) { + if (sideToMove == BLACK) { fen.append(" b "); } else { fen.append(" w "); } int cst = 0; - if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_WHITE_MASK) { + if (rightCastle & RIGHT_KING_CASTLE_WHITE_MASK) { fen += whiteRookKingSideCastle; cst++; } - if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_WHITE_MASK) { + if (rightCastle & RIGHT_QUEEN_CASTLE_WHITE_MASK) { fen += whiteRookQueenSideCastle; cst++; } - if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_BLACK_MASK) { + if (rightCastle & RIGHT_KING_CASTLE_BLACK_MASK) { fen += blackRookKingSideCastle; cst++; } - if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_BLACK_MASK) { + if (rightCastle & RIGHT_QUEEN_CASTLE_BLACK_MASK) { fen += blackRookQueenSideCastle; cst++; } if (!cst) { fen.append("-"); } - if (chessboard[ENPASSANT_IDX] == NO_ENPASSANT) { + if (enPassant == NO_ENPASSANT) { fen.append(" -"); } else { fen.append(" "); - chessboard[SIDETOMOVE_IDX] ? fen.append(BOARD[chessboard[ENPASSANT_IDX] + 8]) : fen.append( - BOARD[chessboard[ENPASSANT_IDX] - 8]); + sideToMove ? fen.append(BOARD[enPassant + 8]) : fen.append(BOARD[enPassant - 8]); } fen.append(" 0 "); fen.append(to_string(movesCount)); @@ -130,52 +129,49 @@ string ChessBoard::boardToFen() const { void ChessBoard::display() const { cout << endl << " a b c d e f g h"; for (int t = 0; t <= 63; t++) { - char x = ' '; + char x; if (t % 8 == 0) { cout << endl << " ----+---+---+---+---+---+---+----" << endl; cout << " " << 8 - RANK_AT[t] << " | "; } - x = (x = (x = FEN_PIECE[board::getPieceAt(POW2[63 - t], chessboard)]) != '-' ? x + x = (x = (x = FEN_PIECE[board::getPieceAt(POW2(63 - t), chessboard)]) != '-' ? x : FEN_PIECE[board::getPieceAt( - POW2[63 - t], chessboard)]) == '-' ? ' ' : x; - x != ' ' ? cout << x : POW2[t] & WHITE_SQUARES ? cout << " " : cout << "."; + POW2(63 - t), chessboard)]) == '-' ? ' ' : x; + x != ' ' ? cout << x : POW2(t) & WHITE_SQUARES ? cout << " " : cout << "."; cout << " | "; - }; + } cout << endl << " ----+---+---+---+---+---+---+----" << endl; cout << " a b c d e f g h" << endl << endl << "fen:\t\t" << boardToFen() << endl; - cout << "side:\t\t" << (chessboard[SIDETOMOVE_IDX] ? "White" : "Black") << endl; + cout << "side:\t\t" << (sideToMove ? "White" : "Black") << endl; cout << "castle:\t\t"; - if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_WHITE_MASK) cout << whiteRookKingSideCastle; - if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_WHITE_MASK) cout << whiteRookQueenSideCastle; - if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_BLACK_MASK) cout << blackRookKingSideCastle; - if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_BLACK_MASK) cout << blackRookQueenSideCastle; + if (rightCastle & RIGHT_KING_CASTLE_WHITE_MASK) cout << whiteRookKingSideCastle; + if (rightCastle & RIGHT_QUEEN_CASTLE_WHITE_MASK) cout << whiteRookQueenSideCastle; + if (rightCastle & RIGHT_KING_CASTLE_BLACK_MASK) cout << blackRookKingSideCastle; + if (rightCastle & RIGHT_QUEEN_CASTLE_BLACK_MASK) cout << blackRookQueenSideCastle; cout << endl; cout << "ep:\t\t\t" - << (chessboard[ENPASSANT_IDX] == 100 ? "" : (chessboard[SIDETOMOVE_IDX] ? BOARD[chessboard[ENPASSANT_IDX] + 8] - : BOARD[chessboard[ENPASSANT_IDX] - + << (enPassant == NO_ENPASSANT ? "" : (sideToMove ? BOARD[enPassant + 8] : BOARD[enPassant - 8])) << endl; cout << "Chess960:\t" << (chess960 ? "true" : "false") << endl; -#ifdef DEBUG_MODE - cout << "zobristKey:\t0x" << hex << chessboard[ZOBRISTKEY_IDX] << "ull" << dec << endl; -#endif + DEBUG(cout << "zobristKey:\t0x" << hex << chessboard[ZOBRISTKEY_IDX] << "ull" << dec << endl) cout << endl; } string ChessBoard::moveToString(const _Tmove *move) { - string a = decodeBoardinv(move->s.type, move->s.from, move->s.side); - if (move->s.type & 0xc) return a; - string b = decodeBoardinv(move->s.type, move->s.to, move->s.side); - if (move->s.promotionPiece != -1) (a + b) += (char) tolower(FEN_PIECE[move->s.promotionPiece]); + string a = decodeBoardinv(move->type, move->from, move->side); + if (move->type & 0xc) return a; + string b = decodeBoardinv(move->type, move->to, move->side); + if (move->promotionPiece != NO_PROMOTION) (a + b) += (char) tolower(FEN_PIECE[move->promotionPiece]); return a + b; } -void ChessBoard::print(const _Tmove *move, const _Tchessboard &chessboard) { +void ChessBoard::print(const _Tmove *move) { cout << moveToString(move) << " " << flush; } -string ChessBoard::decodeBoardinv(const uchar type, const int a, const int side) { +string ChessBoard::decodeBoardinv(const uchar type, const int a, const uchar side) { if (type & QUEEN_SIDE_CASTLE_MOVE_MASK && side == WHITE) { return isChess960() ? BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide] : "e1c1"; } @@ -188,31 +184,38 @@ string ChessBoard::decodeBoardinv(const uchar type, const int a, const int side) if (type & KING_SIDE_CASTLE_MOVE_MASK && side == BLACK) { return isChess960() ? BOARD[startPosBlackKing] + BOARD[startPosBlackRookKingSide] : "e8g8"; } - ASSERT(!(type & 0xC)); + assert(!(type & 0xC)); if (a >= 0 && a < 64) { return BOARD[a]; } - _assert(0); + _assert(0) +} + +void ChessBoard::clearChessboard() { + memset(chessboard, 0, sizeof(_Tchessboard)); + enPassant = NO_ENPASSANT; + rightCastle = 0; + sideToMove=0; } int ChessBoard::loadFen(const string &fen) { if (fen.empty()) { return loadFen(); } - startPosWhiteKing = -1; - startPosWhiteRookKingSide = -1; - startPosWhiteRookQueenSide = -1; + startPosWhiteKing = NO_POSITION; + startPosWhiteRookKingSide = NO_POSITION; + startPosWhiteRookQueenSide = NO_POSITION; - startPosBlackKing = -1; - startPosBlackRookKingSide = -1; - startPosBlackRookQueenSide = -1; + startPosBlackKing = NO_POSITION; + startPosBlackRookKingSide = NO_POSITION; + startPosBlackRookQueenSide = NO_POSITION; MATCH_QUEENSIDE = ""; MATCH_QUEENSIDE_WHITE = "O-O-O "; MATCH_KINGSIDE_WHITE = "O-O "; MATCH_QUEENSIDE_BLACK = "O-O-O "; MATCH_KINGSIDE_BLACK = "O-O "; fenString = fen; - memset(chessboard, 0, sizeof(_Tchessboard)); + clearChessboard(); istringstream iss(fen); string pos, castle, enpassant, side, a1, a2; iss >> pos; @@ -222,7 +225,8 @@ int ChessBoard::loadFen(const string &fen) { iss >> a1; iss >> a2; a2 += " 1"; - movesCount = stoi(a2); + if (String::isNumber(a2)) + movesCount = stoi(a2); int ix = 0; array s; @@ -237,16 +241,16 @@ int ChessBoard::loadFen(const string &fen) { } } else { return 2; - }; + } } } if (ix != 64) { return 2; } if (side == "b") { - chessboard[SIDETOMOVE_IDX] = BLACK; + sideToMove = BLACK; } else if (side == "w") { - chessboard[SIDETOMOVE_IDX] = WHITE; + sideToMove = WHITE; } else { return 2; } @@ -255,9 +259,9 @@ int ChessBoard::loadFen(const string &fen) { int p = s[63 - i]; if (p != SQUARE_EMPTY) { updateZobristKey(p, i); - chessboard[p] |= POW2[i]; + chessboard[p] |= POW2(i); } else { - chessboard[p] &= NOTPOW2[i]; + chessboard[p] &= NOTPOW2(i); } } startPosWhiteKing = BITScanForward(chessboard[KING_WHITE]); @@ -265,29 +269,29 @@ int ChessBoard::loadFen(const string &fen) { auto whiteRookKingSide = [&](const char c) { startPosWhiteRookKingSide = BITScanForward(chessboard[ROOK_WHITE] & 0xffULL); updateZobristKey(RIGHT_CASTLE_IDX, 4); - ASSERT(4 == BITScanForward(RIGHT_KING_CASTLE_WHITE_MASK)); - chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_WHITE_MASK; + assert(4 == BITScanForward(RIGHT_KING_CASTLE_WHITE_MASK)); + rightCastle |= RIGHT_KING_CASTLE_WHITE_MASK; whiteRookKingSideCastle = c; }; auto blackRookKingSide = [&](const char c) { startPosBlackRookKingSide = BITScanForward(chessboard[ROOK_BLACK] & 0xff00000000000000ULL); updateZobristKey(RIGHT_CASTLE_IDX, 6); - ASSERT(6 == BITScanForward(RIGHT_KING_CASTLE_BLACK_MASK)); - chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_BLACK_MASK; + assert(6 == BITScanForward(RIGHT_KING_CASTLE_BLACK_MASK)); + rightCastle |= RIGHT_KING_CASTLE_BLACK_MASK; blackRookKingSideCastle = c; }; auto whiteRookQueenSide = [&](const char c) { startPosWhiteRookQueenSide = BITScanReverse(chessboard[ROOK_WHITE] & 0xffULL); updateZobristKey(RIGHT_CASTLE_IDX, 5); - ASSERT(5 == BITScanForward(RIGHT_QUEEN_CASTLE_WHITE_MASK)); - chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_WHITE_MASK; + assert(5 == BITScanForward(RIGHT_QUEEN_CASTLE_WHITE_MASK)); + rightCastle |= RIGHT_QUEEN_CASTLE_WHITE_MASK; whiteRookQueenSideCastle = c; }; auto blackRookQueenSide = [&](const char c) { startPosBlackRookQueenSide = BITScanReverse(chessboard[ROOK_BLACK] & 0xff00000000000000ULL); updateZobristKey(RIGHT_CASTLE_IDX, 7); - ASSERT(7 == BITScanForward(RIGHT_QUEEN_CASTLE_BLACK_MASK)); - chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_BLACK_MASK; + assert(7 == BITScanForward(RIGHT_QUEEN_CASTLE_BLACK_MASK)); + rightCastle |= RIGHT_QUEEN_CASTLE_BLACK_MASK; blackRookQueenSideCastle = c; }; for (unsigned e = 0; e < castle.length(); e++) { @@ -334,33 +338,33 @@ int ChessBoard::loadFen(const string &fen) { } } - chessboard[ENPASSANT_IDX] = NO_ENPASSANT; + enPassant = NO_ENPASSANT; for (int i = 0; i < 64; i++) { if (enpassant == BOARD[i]) { - chessboard[ENPASSANT_IDX] = i; - if (chessboard[SIDETOMOVE_IDX]) { - chessboard[ENPASSANT_IDX] -= 8; + enPassant = i; + if (sideToMove) { + enPassant -= 8; } else { - chessboard[ENPASSANT_IDX] += 8; + enPassant += 8; } - updateZobristKey(ENPASSANT_IDX, chessboard[ENPASSANT_IDX]); + updateZobristKey(ENPASSANT_IDX, enPassant); break; } } if (isChess960()) { - if (startPosWhiteRookKingSide != -1) + if (startPosWhiteRookKingSide != NO_POSITION) MATCH_KINGSIDE_WHITE += BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookKingSide]; - if (startPosBlackRookQueenSide != -1) + if (startPosBlackRookQueenSide != NO_POSITION) MATCH_QUEENSIDE_BLACK += BOARD[startPosBlackKing] + BOARD[startPosBlackRookQueenSide]; - if (startPosWhiteRookQueenSide != -1) + if (startPosWhiteRookQueenSide != NO_POSITION) MATCH_QUEENSIDE_WHITE += BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide]; - if (startPosBlackRookKingSide != -1) + if (startPosBlackRookKingSide != NO_POSITION) MATCH_KINGSIDE_BLACK += BOARD[startPosBlackKing] + BOARD[startPosBlackRookKingSide]; - if (startPosBlackRookQueenSide != -1) + if (startPosBlackRookQueenSide != NO_POSITION) MATCH_QUEENSIDE += MATCH_QUEENSIDE_BLACK + " " + BOARD[startPosBlackKing] + BOARD[startPosBlackRookQueenSide]; - if (startPosWhiteRookQueenSide != -1) + if (startPosWhiteRookQueenSide != NO_POSITION) MATCH_QUEENSIDE += MATCH_QUEENSIDE_WHITE + " " + BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide]; } else { @@ -371,5 +375,5 @@ int ChessBoard::loadFen(const string &fen) { MATCH_QUEENSIDE = MATCH_QUEENSIDE_WHITE + " e8c8"; } - return chessboard[SIDETOMOVE_IDX]; + return sideToMove; } diff --git a/src/ChessBoard.h b/src/ChessBoard.h index 7e8e64cf..808d7bea 100644 --- a/src/ChessBoard.h +++ b/src/ChessBoard.h @@ -21,7 +21,7 @@ #include #include #include -#include "util/String.h" +#include "namespaces/String.h" #include "namespaces/bits.h" #include #include "namespaces/random.h" @@ -40,11 +40,11 @@ using namespace _logger; using namespace constants; using namespace _def; -class ChessBoard : public Bitboard { +class ChessBoard { public: ChessBoard(); - string decodeBoardinv(const uchar type, const int a, const int side); + string decodeBoardinv(const uchar type, const int a, const uchar side); virtual ~ChessBoard(); @@ -52,12 +52,14 @@ class ChessBoard : public Bitboard { int loadFen(const string &); + void clearChessboard(); + const _Tchessboard &getChessboard() const { return chessboard; } void setSide(const bool b) { - chessboard[SIDETOMOVE_IDX] = b; + sideToMove = b; } void setChess960(bool c) { chess960 = c; } @@ -70,38 +72,39 @@ class ChessBoard : public Bitboard { string boardToFen() const; + uchar sideToMove; protected: -#ifdef BENCH_MODE - Times *times = &Times::getInstance(); -#endif + _Tchessboard chessboard; - int startPosWhiteKing; - int startPosWhiteRookKingSide; - int startPosWhiteRookQueenSide; + uchar startPosWhiteKing; + uchar startPosWhiteRookKingSide; + uchar startPosWhiteRookQueenSide; + + uchar startPosBlackKing; + uchar startPosBlackRookKingSide; + uchar startPosBlackRookQueenSide; - int startPosBlackKing; - int startPosBlackRookKingSide; - int startPosBlackRookQueenSide; + uchar rightCastle; + uchar enPassant; string MATCH_QUEENSIDE; string MATCH_QUEENSIDE_WHITE; string MATCH_KINGSIDE_WHITE; string MATCH_QUEENSIDE_BLACK; string MATCH_KINGSIDE_BLACK; - _Tboard structureEval; int movesCount = 1; bool chess960 = false; void makeZobristKey(); - void print(const _Tmove *move, const _Tchessboard &chessboard); + void print(const _Tmove *move); #ifdef DEBUG_MODE void updateZobristKey(int piece, int position) { - ASSERT_RANGE(position, 0, 63); - ASSERT_RANGE(piece, 0, 14); + ASSERT_RANGE(position, 0, 63) + ASSERT_RANGE(piece, 0, 15) chessboard[ZOBRISTKEY_IDX] ^= _random::RANDOM_KEY[piece][position]; } @@ -120,4 +123,3 @@ class ChessBoard : public Bitboard { int loadFen(); }; - diff --git a/src/Eval.cpp b/src/Eval.cpp index 292ef4eb..05c369e3 100644 --- a/src/Eval.cpp +++ b/src/Eval.cpp @@ -22,6 +22,7 @@ using namespace _eval; u64 *Eval::evalHash; Eval::Eval() { + memset(&structureEval, 0, sizeof(_Tboard)); if (evalHash == nullptr) evalHash = (u64 *) calloc(hashSize, sizeof(u64)); } @@ -38,7 +39,7 @@ Eval::~Eval() { * 4. add ATTACK_KING * number of attacking pawn to other king * 5. space - in OPEN phase PAWN_CENTER * CENTER_MASK * 7. *king security* - in OPEN phase add at kingSecurity FRIEND_NEAR_KING * each pawn near to king and substracts ENEMY_NEAR_KING * each enemy pawn near to king - * 8. pawn in 8th - if pawn is in 7' add PAWN_7H. If pawn can go forward add PAWN_IN_8TH for each pawn + * 8. pawn in promotion - if pawn is in 7' add PAWN_7H. If pawn can go forward add PAWN_IN_PROMOTION for each pawn * 9. unprotected - no friends pawn protect it * 10. blocked - pawn can't go on * 11. isolated - there aren't friend pawns on the two sides - subtracts PAWN_ISOLATED for each pawn @@ -47,27 +48,29 @@ Eval::~Eval() { * 14. passed - if there isn't friend pawns forward and forward on sides until 8' rank add PAWN_PASSED[side][pos] */ -template -int Eval::evaluatePawn() { +template +int Eval::evaluatePawn(const _Tchessboard &chessboard) { INC(evaluationCount[side]); int result = 0; - constexpr int xside = side ^1; + constexpr int xside = X(side); const u64 ped_friends = chessboard[side]; // 5. space - if (phase == OPEN) { - result += PAWN_CENTER * bitCount(ped_friends & CENTER_MASK); - ADD(SCORE_DEBUG.PAWN_CENTER[side], PAWN_CENTER * bitCount(ped_friends & CENTER_MASK)); - } +// if (phase == OPEN) { +// result += PAWN_CENTER * bitCount(ped_friends & CENTER_MASK); +// ADD(SCORE_DEBUG.PAWN_CENTER[side], PAWN_CENTER * bitCount(ped_friends & CENTER_MASK)); +// } // 7. if (phase != OPEN) { +// if (structureEval.pinned[side] & ped_friends) result -= PAWN_PINNED; +// ADD(SCORE_DEBUG.PAWN_PINNED[side], -PAWN_PINNED); structureEval.kingSecurity[side] += FRIEND_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[side]] & ped_friends); - structureEval.kingSecurity[side] -= - ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & ped_friends); +// structureEval.kingSecurity[side] -= +// ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & ped_friends); } // 8. pawn in 8th @@ -80,15 +83,15 @@ int Eval::evaluatePawn() { (structureEval.allPiecesSide[xside] & (shiftForward(pawnsIn7) | shiftForward(pawnsIn7))); - result += PAWN_IN_8TH * bitCount(pawnsIn8); //try to decrease PAWN_IN_8TH - ADD(SCORE_DEBUG.PAWN_IN_8TH[side], PAWN_IN_8TH * (bitCount(pawnsIn8))); + result += PAWN_IN_PROMOTION * bitCount(pawnsIn8); //try to decrease PAWN_IN_PROMOTION + ADD(SCORE_DEBUG.PAWN_IN_PROMOTION[side], PAWN_IN_PROMOTION * (bitCount(pawnsIn8))); } for (u64 p = ped_friends; p; RESET_LSB(p)) { bool isolated = false; const int o = BITScanForward(p); - u64 pos = POW2[o]; + const u64 pos = POW2(o); // 4. attack king if (structureEval.posKingBit[xside] & PAWN_FORK_MASK[side][o]) { @@ -109,14 +112,14 @@ int Eval::evaluatePawn() { } /// isolated if (!(ped_friends & PAWN_ISOLATED_MASK[o])) { - result -= PAWN_ISOLATED; - ADD(SCORE_DEBUG.PAWN_ISOLATED[side], -PAWN_ISOLATED); +// result -= PAWN_ISOLATED; +// ADD(SCORE_DEBUG.PAWN_ISOLATED[side], -PAWN_ISOLATED); isolated = true; } /// doubled - if (NOTPOW2[o] & FILE_[o] & ped_friends) { - result -= DOUBLED_PAWNS; - ADD(SCORE_DEBUG.DOUBLED_PAWNS[side], -DOUBLED_PAWNS); + if (NOTPOW2(o) & FILE_[o] & ped_friends) { +// result -= DOUBLED_PAWNS; +// ADD(SCORE_DEBUG.DOUBLED_PAWNS[side], -DOUBLED_PAWNS); /// doubled and isolated if (isolated) { ADD(SCORE_DEBUG.DOUBLED_ISOLATED_PAWNS[side], -DOUBLED_ISOLATED_PAWNS); @@ -147,11 +150,12 @@ int Eval::evaluatePawn() { * 6. if only one bishop and pawns on same square color substracts n_pawns * BISHOP_PAWN_ON_SAME_COLOR * 7. outposts * 8. bishop on big diagonal + * 9. pinned */ -template -int Eval::evaluateBishop(const u64 enemies) { +template +int Eval::evaluateBishop(const _Tchessboard &chessboard, const u64 enemies) { INC(evaluationCount[side]); - constexpr int xside = side ^1; + constexpr int xside = X(side); u64 bishop = chessboard[BISHOP_BLACK + side]; // 1. @@ -165,7 +169,7 @@ int Eval::evaluateBishop(const u64 enemies) { result -= BISHOP_PAWN_ON_SAME_COLOR * bitCount(chessboard[side] & board::colors(BITScanForward(bishop))); } else { // 2. - ASSERT(nBishop > 1) + assert(nBishop > 1); if (phase != OPEN) { result += BONUS2BISHOP; ADD(SCORE_DEBUG.BONUS2BISHOP[side], BONUS2BISHOP); @@ -174,45 +178,46 @@ int Eval::evaluateBishop(const u64 enemies) { // 3. *king security* if (phase != OPEN) { - structureEval.kingSecurity[side] -= - ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & bishop); - ADD(SCORE_DEBUG.KING_SECURITY_BISHOP[side], - -ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & bishop)); + // 9. pinned + if (structureEval.pinned[side] & bishop) result -= BISHOP_PINNED; + ADD(SCORE_DEBUG.BISHOP_PINNED[side], -BISHOP_PINNED); +// structureEval.kingSecurity[side] -= +// ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & bishop); +// ADD(SCORE_DEBUG.KING_SECURITY_BISHOP[side], +// -ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & bishop)); } // 4. undevelop - if (phase != END) { - result -= UNDEVELOPED_BISHOP * bitCount(BISHOP_HOME[side] & bishop); - ADD(SCORE_DEBUG.UNDEVELOPED_BISHOP[side], UNDEVELOPED_BISHOP * bitCount(BISHOP_HOME[side] & bishop)); - } +// if (phase != END) { +// result -= UNDEVELOPED_BISHOP * bitCount(BISHOP_HOME[side] & bishop); +// ADD(SCORE_DEBUG.UNDEVELOPED_BISHOP[side], UNDEVELOPED_BISHOP * bitCount(BISHOP_HOME[side] & bishop)); +// } for (; bishop; RESET_LSB(bishop)) { const int o = BITScanForward(bishop); // 5. mobility - u64 captured = getDiagCapture(o, structureEval.allPieces, enemies); - ASSERT(bitCount(captured) + board::getDiagShiftCount(o, structureEval.allPieces) < - (int) (sizeof(MOB_BISHOP) / sizeof(int))) + const u64 x = Bitboard::getDiagonalAntiDiagonal(o, structureEval.allPieces); + const u64 captured = x & enemies; + assert(bitCount(captured) + bitCount(x & ~structureEval.allPieces) < (int) (sizeof(MOB_BISHOP) / sizeof(int))); + if (captured & structureEval.posKingBit[xside]) structureEval.kingAttackers[xside] |= POW2(o); - if (captured & structureEval.posKingBit[xside]) { - structureEval.kingAttackers[xside] |= POW2[o]; - } + result += MOB_BISHOP[phase][bitCount(captured) + bitCount(x & ~structureEval.allPieces)]; - result += MOB_BISHOP[phase][bitCount(captured) + board::getDiagShiftCount(o, structureEval.allPieces)]; ADD(SCORE_DEBUG.MOB_BISHOP[side], - MOB_BISHOP[phase][bitCount(captured) + board::getDiagShiftCount(o, structureEval.allPieces)]); + MOB_BISHOP[phase][bitCount(captured) + bitCount(x & ~structureEval.allPieces)]); // 6. - if (phase != OPEN) { - if ((BIG_DIAGONAL & structureEval.allPieces) == POW2[o]) { - ADD(SCORE_DEBUG.OPEN_DIAG_BISHOP[side], OPEN_FILE); - result += OPEN_FILE; - } - if ((BIG_ANTIDIAGONAL & structureEval.allPieces) == POW2[o]) { - ADD(SCORE_DEBUG.OPEN_DIAG_BISHOP[side], OPEN_FILE); - result += OPEN_FILE; - } - } +// if (phase != OPEN) { +// if ((BIG_DIAGONAL & structureEval.allPieces) == POW2(o)) { +// ADD(SCORE_DEBUG.OPEN_DIAG_BISHOP[side], OPEN_FILE); +// result += OPEN_FILE; +// } +// if ((BIG_ANTIDIAGONAL & structureEval.allPieces) == POW2(o)) { +// ADD(SCORE_DEBUG.OPEN_DIAG_BISHOP[side], OPEN_FILE); +// result += OPEN_FILE; +// } +// } // 7. outposts auto p = BISHOP_OUTPOST[side][o]; @@ -220,10 +225,9 @@ int Eval::evaluateBishop(const u64 enemies) { //enemy pawn doesn't attack bishop if (p && !(PAWN_FORK_MASK[xside][o] & chessboard[xside])) { //friend paws defends bishop - if (PAWN_FORK_MASK[side ^ 1][o] & chessboard[side]) { + if (PAWN_FORK_MASK[X(side)][o] & chessboard[side]) { result += p; - if (!(chessboard[KNIGHT_BLACK + xside]) && - !(chessboard[BISHOP_BLACK + xside] & board::colors(o))) { + if (!(chessboard[KNIGHT_BLACK + xside]) && !(chessboard[BISHOP_BLACK + xside] & board::colors(o))) { result += p; } } @@ -240,42 +244,47 @@ int Eval::evaluateBishop(const u64 enemies) { * 5. open file - if there is any pieces on same file add OPEN_FILE_Q * 6. 5. bishop on queen - if there is a bishop on same diagonal add BISHOP_ON_QUEEN */ -template -int Eval::evaluateQueen(const u64 enemies) { +template +int Eval::evaluateQueen(const _Tchessboard &chessboard, const u64 enemies) { INC(evaluationCount[side]); u64 queen = chessboard[QUEEN_BLACK + side]; int result = 0; - constexpr int xside = side ^1; + constexpr int xside = X(side); // 2. *king security* if (phase != OPEN) { + if (structureEval.pinned[side] & queen) result -= QUEEN_PINNED; + ADD(SCORE_DEBUG.QUEEN_PINNED[side], -QUEEN_PINNED); structureEval.kingSecurity[side] += FRIEND_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[side]] & queen); ADD(SCORE_DEBUG.KING_SECURITY_QUEEN[side], FRIEND_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[side]] & queen)); - structureEval.kingSecurity[side] -= - ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & queen); - ADD(SCORE_DEBUG.KING_SECURITY_QUEEN[xside], - -ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & queen)); +// if (RANK_2_7[xside] & queen && POW2(structureEval.posKing[xside]) & RANK_1_8[xside]) result += QUEEN_IN_7; + +// structureEval.kingSecurity[side] -= +// ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & queen); +// ADD(SCORE_DEBUG.KING_SECURITY_QUEEN[xside], +// -ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & queen)); } for (; queen; RESET_LSB(queen)) { const int o = BITScanForward(queen); // 3. mobility - u64 x = board::getMobilityQueen(o, enemies, structureEval.allPieces); + const u64 x = board::performRankFileCaptureAndShift(o, enemies, structureEval.allPieces) | + board::getDiagShiftAndCapture(o, enemies, structureEval.allPieces); + result += MOB_QUEEN[phase][bitCount(x)]; ADD(SCORE_DEBUG.MOB_QUEEN[side], MOB_QUEEN[phase][bitCount(x)]); - if (x & structureEval.posKingBit[xside]) - structureEval.kingAttackers[xside] |= POW2[o]; + if (x & structureEval.posKingBit[xside]) structureEval.kingAttackers[xside] |= POW2(o); // 4. half open file - if ((chessboard[xside] & FILE_[o])) { - ADD(SCORE_DEBUG.HALF_OPEN_FILE_Q[side], HALF_OPEN_FILE_Q); - result += HALF_OPEN_FILE_Q; - } +// if ((chessboard[xside] & FILE_[o])) { +// ADD(SCORE_DEBUG.HALF_OPEN_FILE_Q[side], HALF_OPEN_FILE_Q); +// result += HALF_OPEN_FILE_Q; +// } // 5. open file - if ((FILE_[o] & structureEval.allPieces) == POW2[o]) { + if ((FILE_[o] & structureEval.allPieces) == POW2(o)) { ADD(SCORE_DEBUG.OPEN_FILE_Q[side], OPEN_FILE_Q); result += OPEN_FILE_Q; } @@ -298,42 +307,44 @@ int Eval::evaluateQueen(const u64 enemies) { * 6. outposts */ -template -int Eval::evaluateKnight(const u64 notMyBits) { +template +int Eval::evaluateKnight(const _Tchessboard &chessboard, const u64 notMyBits) { INC(evaluationCount[side]); u64 knight = chessboard[KNIGHT_BLACK + side]; if (!knight) return 0; - constexpr int xside = side ^1; + constexpr int xside = X(side); // 1. pinned int result = 0; // 2. undevelop - if (phase == OPEN) { - result -= bitCount(knight & KNIGHT_HOME[side]) * UNDEVELOPED_KNIGHT; - ADD(SCORE_DEBUG.UNDEVELOPED_KNIGHT[side], - bitCount(knight & KNIGHT_HOME[side]) * UNDEVELOPED_KNIGHT); - } +// if (phase == OPEN) { +// result -= bitCount(knight & KNIGHT_HOME[side]) * UNDEVELOPED_KNIGHT; +// ADD(SCORE_DEBUG.UNDEVELOPED_KNIGHT[side], +// bitCount(knight & KNIGHT_HOME[side]) * UNDEVELOPED_KNIGHT); +// } // 4. king security if (phase != OPEN) { + if (structureEval.pinned[side] & knight) result -= KNIGHT_PINNED; + ADD(SCORE_DEBUG.KNIGHT_PINNED[side], -KNIGHT_PINNED); structureEval.kingSecurity[side] += FRIEND_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[side]] & knight); ADD(SCORE_DEBUG.KING_SECURITY_KNIGHT[side], FRIEND_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[side]] & knight)); - structureEval.kingSecurity[side] -= - ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & knight); - ADD(SCORE_DEBUG.KING_SECURITY_KNIGHT[xside], - -ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & knight)); +// structureEval.kingSecurity[side] -= +// ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & knight); +// ADD(SCORE_DEBUG.KING_SECURITY_KNIGHT[xside], +// -ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & knight)); } for (; knight; RESET_LSB(knight)) { const int pos = BITScanForward(knight); // 5. mobility - ASSERT(bitCount(notMyBits & KNIGHT_MASK[pos]) < (int) (sizeof(MOB_KNIGHT) / sizeof(int))) + assert(bitCount(notMyBits & KNIGHT_MASK[pos]) < (int) (sizeof(MOB_KNIGHT) / sizeof(int))); u64 mob = notMyBits & KNIGHT_MASK[pos]; result += MOB_KNIGHT[bitCount(mob)]; - if (mob & structureEval.posKingBit[xside]) structureEval.kingAttackers[xside] |= POW2[pos]; + if (mob & structureEval.posKingBit[xside]) structureEval.kingAttackers[xside] |= POW2(pos); ADD(SCORE_DEBUG.MOB_KNIGHT[side], MOB_KNIGHT[bitCount(mob)]); // 6. outposts @@ -365,87 +376,90 @@ int Eval::evaluateKnight(const u64 notMyBits) { * 7. 2 linked towers * 8. Penalise if Rook is Blocked Horizontally */ -template -int Eval::evaluateRook(const u64 king, const u64 enemies, const u64 friends) { +template +int Eval::evaluateRook(const _Tchessboard &chessboard, const u64 enemies, const u64 friends) { INC(evaluationCount[side]); u64 rook = chessboard[ROOK_BLACK + side]; if (!rook) return 0; - const int nRooks = bitCount(rook); +// const int nRooks = bitCount(rook); // 2. int result = 0; - constexpr int xside = side ^1; + constexpr int xside = X(side); // 3. in 7th if (phase == MIDDLE) { - result += ROOK_7TH_RANK * bitCount(rook & RANK_1_7[side]); - ADD(SCORE_DEBUG.ROOK_7TH_RANK[side], ROOK_7TH_RANK * bitCount(rook & RANK_1_7[side])); + result += ROOK_7TH_RANK * bitCount(rook & RANK_2_7[xside]); + ADD(SCORE_DEBUG.ROOK_7TH_RANK[side], ROOK_7TH_RANK * bitCount(rook & RANK_2_7[xside])); } // 4. king security if (phase != OPEN) { + if (structureEval.pinned[side] & rook) result -= ROOK_PINNED; + ADD(SCORE_DEBUG.ROOK_PINNED[side], -ROOK_PINNED); structureEval.kingSecurity[side] += FRIEND_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[side]] & rook); ADD(SCORE_DEBUG.KING_SECURITY_ROOK[side], FRIEND_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[side]] & rook)); - structureEval.kingSecurity[side] -= - ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & rook); - ADD(SCORE_DEBUG.KING_SECURITY_ROOK[xside], - -ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & rook)); + if (RANK_2_7[xside] & rook && POW2(structureEval.posKing[xside]) & RANK_1_8[xside]) result += ROOK_IN_7; +// structureEval.kingSecurity[side] -= +// ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & rook); +// ADD(SCORE_DEBUG.KING_SECURITY_ROOK[xside], +// -ENEMY_NEAR_KING * bitCount(NEAR_MASK2[structureEval.posKing[xside]] & rook)); } // .6 - if (((F1G1bit[side] & king) && (H1H2G1bit[side] & rook)) || ((C1B1bit[side] & king) && (A1A2B1bit[side] & rook))) { - ADD(SCORE_DEBUG.ROOK_TRAPPED[side], -ROOK_TRAPPED); - result -= ROOK_TRAPPED; - } +// if (((F1G1bit[side] & king) && (H1H2G1bit[side] & rook)) || ((C1B1bit[side] & king) && (A1A2B1bit[side] & rook))) { +// ADD(SCORE_DEBUG.ROOK_TRAPPED[side], -ROOK_TRAPPED); +// result -= ROOK_TRAPPED; +// } // .7 - if (nRooks == 2) { - const int firstRook = BITScanForward(rook); - const int secondRook = BITScanReverse(rook); - if ((!(LINK_ROOKS[firstRook][secondRook] & structureEval.allPieces))) { - ADD(SCORE_DEBUG.CONNECTED_ROOKS[side], CONNECTED_ROOKS); - result += CONNECTED_ROOKS; - } - } +// if (nRooks == 2) { +// const int firstRook = BITScanForward(rook); +// const int secondRook = BITScanReverse(rook); +// if ((!(LINK_ROOKS[firstRook][secondRook] & structureEval.allPieces))) { +// ADD(SCORE_DEBUG.CONNECTED_ROOKS[side], CONNECTED_ROOKS); +// result += CONNECTED_ROOKS; +// } +// } for (; rook; RESET_LSB(rook)) { const int o = BITScanForward(rook); //mobility u64 mob = board::getMobilityRook(o, enemies, friends); - if (mob & structureEval.posKingBit[xside]) structureEval.kingAttackers[xside] |= POW2[o]; + if (mob & structureEval.posKingBit[xside]) structureEval.kingAttackers[xside] |= POW2(o); - ASSERT(bitCount(mob) < (int) (sizeof(MOB_ROOK[phase]) / sizeof(int))) + assert(bitCount(mob) < (int) (sizeof(MOB_ROOK[phase]) / sizeof(int))); result += MOB_ROOK[phase][bitCount(mob)]; ADD(SCORE_DEBUG.MOB_ROOK[side], MOB_ROOK[phase][bitCount(mob)]); - if (phase != OPEN) { - // .8 Penalise if Rook is Blocked Horizontally - if ((RANK_BOUND[o] & structureEval.allPieces) == RANK_BOUND[o]) { - ADD(SCORE_DEBUG.ROOK_BLOCKED[side], -ROOK_BLOCKED); - result -= ROOK_BLOCKED; - } - } +// if (phase != OPEN) { +// // .8 Penalise if Rook is Blocked Horizontally +// if ((RANK_BOUND[o] & structureEval.allPieces) == RANK_BOUND[o]) { +// ADD(SCORE_DEBUG.ROOK_BLOCKED[side], -ROOK_BLOCKED); +// result -= ROOK_BLOCKED; +// } +// } // .5 - if (!(chessboard[side] & FILE_[o])) { - ADD(SCORE_DEBUG.ROOK_OPEN_FILE[side], OPEN_FILE); - result += OPEN_FILE; - } - if (!(chessboard[xside] & FILE_[o])) { - ADD(SCORE_DEBUG.ROOK_OPEN_FILE[side], OPEN_FILE); - result += OPEN_FILE; - } +// if (!(chessboard[side] & FILE_[o])) { +// ADD(SCORE_DEBUG.ROOK_OPEN_FILE[side], OPEN_FILE); +// result += OPEN_FILE; +// } +// if (!(chessboard[xside] & FILE_[o])) { +// ADD(SCORE_DEBUG.ROOK_OPEN_FILE[side], OPEN_FILE); +// result += OPEN_FILE; +// } } return result; } template -int Eval::evaluateKing(int side, u64 squares) { - ASSERT(evaluationCount[side] == 5) +int Eval::evaluateKing(const _Tchessboard &chessboard, const uchar side, const u64 squares) { + assert(evaluationCount[side] == 5); int result = 0; uchar pos_king = structureEval.posKing[side]; if (phase == END) { @@ -455,13 +469,13 @@ int Eval::evaluateKing(int side, u64 squares) { ADD(SCORE_DEBUG.DISTANCE_KING[side], DISTANCE_KING_OPENING[pos_king]); result = DISTANCE_KING_OPENING[pos_king]; } - + //mobility - ASSERT(bitCount(squares & NEAR_MASK1[pos_king]) < (int) (sizeof(MOB_KING[phase]) / sizeof(int))) + assert(bitCount(squares & NEAR_MASK1[pos_king]) < (int) (sizeof(MOB_KING[phase]) / sizeof(int))); result += MOB_KING[phase][bitCount(squares & NEAR_MASK1[pos_king])]; ADD(SCORE_DEBUG.MOB_KING[side], MOB_KING[phase][bitCount(squares & NEAR_MASK1[pos_king])]); - ASSERT(pos_king < 64) + assert(pos_king < 64); if (!(NEAR_MASK1[pos_king] & chessboard[side])) { ADD(SCORE_DEBUG.PAWN_NEAR_KING[side], -PAWN_NEAR_KING); result -= PAWN_NEAR_KING; @@ -472,7 +486,7 @@ int Eval::evaluateKing(int side, u64 squares) { void Eval::storeHashValue(const u64 key, const short value) { evalHash[key % hashSize] = (key & keyMask) | (value & valueMask); - ASSERT(value == getHashValue(key)) + assert(value == getHashValue(key)); } short Eval::getHashValue(const u64 key) { @@ -483,81 +497,105 @@ short Eval::getHashValue(const u64 key) { return noHashValue; } -short Eval::getScore(const u64 key, const int side, const int alpha, const int beta, const bool trace) { +short +Eval::getScore(const _Tchessboard &chessboard, const u64 key, const uchar side, const int alpha, const int beta DEBUG2(, + const bool trace) +) { + /// endgame +// if (Endgame::win(side, N_PIECE, chessboard)) { +// return _INFINITE / 2; +// } +// if (Endgame::win(X(side), N_PIECE, chessboard)) { +// return -(_INFINITE / 2); +// } +// if (Endgame::isDraw(N_PIECE, chessboard)) { +// return 0; +// } +// if (N_PIECE == 5 || N_PIECE == 4) { +// const auto result = Endgame::getEndgameValue(side, chessboard, N_PIECE); +// if (result != INT_MAX) { +//#ifndef TUNING +// storeHashValue(key, result); +//#endif +// return side ? -result : result; +// } +// } +#ifndef TUNING const short hashValue = getHashValue(key); - if (hashValue != noHashValue) { - return side ? -hashValue : hashValue; - } - int lazyscore_white = lazyEvalSide(); - int lazyscore_black = lazyEvalSide(); - int lazyscore = lazyscore_black - lazyscore_white; - if (side) { - lazyscore = -lazyscore; - } + DEBUG2(if (!trace)) if (hashValue != noHashValue) return side ? -hashValue : hashValue; + +#endif + int lazyscore_white = lazyEvalSide(chessboard); + int lazyscore_black = lazyEvalSide(chessboard); + + const int lazyscore = side ? lazyscore_white - lazyscore_black : lazyscore_black - lazyscore_white; if (lazyscore > (beta + FUTIL_MARGIN) || lazyscore < (alpha - FUTIL_MARGIN)) { INC(lazyEvalCuts); return lazyscore; } -#ifdef DEBUG_MODE - evaluationCount[WHITE] = evaluationCount[BLACK] = 0; - memset(&SCORE_DEBUG, 0, sizeof(_TSCORE_DEBUG)); -#endif - memset(structureEval.kingSecurity, 0, sizeof(structureEval.kingSecurity)); - int npieces = board::getNpiecesNoPawnNoKing(chessboard) + board::getNpiecesNoPawnNoKing(chessboard); + DEBUG(evaluationCount[WHITE] = evaluationCount[BLACK] = 0) + DEBUG(memset(&SCORE_DEBUG, 0, sizeof(_TSCORE_DEBUG))) + + structureEval.kingSecurity[WHITE] = structureEval.kingSecurity[BLACK] = 0; + const auto w = board::getBitmapNoPawnsNoKing(chessboard); + const auto b = board::getBitmapNoPawnsNoKing(chessboard); + const int npieces = bitCount(w | b); _Tphase phase; - if (npieces < 6) { - phase = END; - } else if (npieces < 11) { - phase = MIDDLE; - } else { - phase = OPEN; - } - structureEval.allPiecesNoPawns[BLACK] = board::getBitmapNoPawns(chessboard); - structureEval.allPiecesNoPawns[WHITE] = board::getBitmapNoPawns(chessboard); + if (npieces < 6) phase = END; + else if (npieces < 11) phase = MIDDLE; + else phase = OPEN; + + structureEval.allPiecesNoPawns[BLACK] = b | chessboard[KING_BLACK]; + structureEval.allPiecesNoPawns[WHITE] = w | chessboard[KING_WHITE]; structureEval.allPiecesSide[BLACK] = structureEval.allPiecesNoPawns[BLACK] | chessboard[PAWN_BLACK]; structureEval.allPiecesSide[WHITE] = structureEval.allPiecesNoPawns[WHITE] | chessboard[PAWN_WHITE]; structureEval.allPieces = structureEval.allPiecesSide[BLACK] | structureEval.allPiecesSide[WHITE]; structureEval.posKing[BLACK] = (uchar) BITScanForward(chessboard[KING_BLACK]); structureEval.posKing[WHITE] = (uchar) BITScanForward(chessboard[KING_WHITE]); - structureEval.posKingBit[BLACK] = POW2[structureEval.posKing[BLACK]]; - structureEval.posKingBit[WHITE] = POW2[structureEval.posKing[WHITE]]; + structureEval.posKingBit[BLACK] = POW2(structureEval.posKing[BLACK]); + structureEval.posKingBit[WHITE] = POW2(structureEval.posKing[WHITE]); structureEval.kingAttackers[WHITE] = structureEval.kingAttackers[BLACK] = 0; + if (phase != OPEN) { + structureEval.pinned[WHITE] = board::getPinned(structureEval.allPieces, + structureEval.allPiecesSide[WHITE], + structureEval.posKing[WHITE], chessboard); + structureEval.pinned[BLACK] = board::getPinned(structureEval.allPieces, + structureEval.allPiecesSide[BLACK], + structureEval.posKing[BLACK], chessboard); + } else { + structureEval.pinned[WHITE] = structureEval.pinned[BLACK] = 0; + } _Tresult Tresult; switch (phase) { case OPEN : - getRes(Tresult); + getRes(chessboard, Tresult); break; case END : - getRes(Tresult); + getRes(chessboard, Tresult); break; case MIDDLE: - getRes(Tresult); + getRes(chessboard, Tresult); break; default: break; } - int bonus_attack_king_black = 0; - int bonus_attack_king_white = 0; - if (phase != OPEN) { - bonus_attack_king_black = BONUS_ATTACK_KING[bitCount(structureEval.kingAttackers[WHITE])]; - bonus_attack_king_white = BONUS_ATTACK_KING[bitCount(structureEval.kingAttackers[BLACK])]; - } + const int bonus_attack_king_black = + phase == OPEN ? 0 : BONUS_ATTACK_KING[bitCount(structureEval.kingAttackers[WHITE])]; + const int bonus_attack_king_white = + phase == OPEN ? 0 : BONUS_ATTACK_KING[bitCount(structureEval.kingAttackers[BLACK])]; - ASSERT(getMobilityCastle(structureEval.allPieces) < (int) (sizeof(MOB_CASTLE[phase]) / sizeof(int))) - ASSERT(getMobilityCastle(structureEval.allPieces) < (int) (sizeof(MOB_CASTLE[phase]) / sizeof(int))) - int mobWhite = MOB_CASTLE[phase][getMobilityCastle(structureEval.allPieces)]; - int mobBlack = MOB_CASTLE[phase][getMobilityCastle(structureEval.allPieces)]; - int attack_king_white = ATTACK_KING * bitCount(structureEval.kingAttackers[BLACK]); - int attack_king_black = ATTACK_KING * bitCount(structureEval.kingAttackers[WHITE]); + const int attack_king_white = ATTACK_KING * bitCount(structureEval.kingAttackers[BLACK]); + const int attack_king_black = ATTACK_KING * bitCount(structureEval.kingAttackers[WHITE]); side == WHITE ? lazyscore_black -= 5 : lazyscore_white += 5; - int result = (mobBlack + attack_king_black + bonus_attack_king_black + lazyscore_black + Tresult.pawns[BLACK] + - Tresult.knights[BLACK] + Tresult.bishop[BLACK] + Tresult.rooks[BLACK] + Tresult.queens[BLACK] + - Tresult.kings[BLACK]) - - (mobWhite + attack_king_white + bonus_attack_king_white + lazyscore_white + Tresult.pawns[WHITE] + - Tresult.knights[WHITE] + Tresult.bishop[WHITE] + Tresult.rooks[WHITE] + Tresult.queens[WHITE] + - Tresult.kings[WHITE]); + const int result = + (attack_king_black + bonus_attack_king_black + lazyscore_black + Tresult.pawns[BLACK] + + Tresult.knights[BLACK] + Tresult.bishop[BLACK] + Tresult.rooks[BLACK] + Tresult.queens[BLACK] + + Tresult.kings[BLACK]) - + (attack_king_white + bonus_attack_king_white + lazyscore_white + Tresult.pawns[WHITE] + + Tresult.knights[WHITE] + Tresult.bishop[WHITE] + Tresult.rooks[WHITE] + Tresult.queens[WHITE] + + Tresult.kings[WHITE]); #ifdef DEBUG_MODE if (trace) { @@ -581,8 +619,6 @@ short Eval::getScore(const u64 key, const int side, const int alpha, const int b cout << HEADER; cout << "|Material: " << setw(10) << (double) (lazyscore_white - lazyscore_black) / 100.0 << setw(15) << (double) (lazyscore_white) / 100.0 << setw(10) << (double) (lazyscore_black) / 100.0 << "\n"; - cout << "|Mobility: " << setw(10) << (double) (mobWhite - mobBlack) / 100.0 << setw(15) << - (double) (mobWhite) / 100.0 << setw(10) << (double) (mobBlack) / 100.0 << "\n"; cout << "|Bonus attack king:" << setw(10) << (double) (bonus_attack_king_white - bonus_attack_king_black) / 100.0 << setw(15) << (double) (bonus_attack_king_white) / 100.0 << setw(10) << (double) (bonus_attack_king_black) / 100.0 @@ -596,25 +632,25 @@ short Eval::getScore(const u64 key, const int side, const int alpha, const int b cout << "| attack king: " << setw(10) << (double) (SCORE_DEBUG.ATTACK_KING_PAWN[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.ATTACK_KING_PAWN[BLACK]) / 100.0 << "\n"; - cout << "| center: " << setw(10) << (double) (SCORE_DEBUG.PAWN_CENTER[WHITE]) / 100.0 << - setw(10) << (double) (SCORE_DEBUG.PAWN_CENTER[BLACK]) / 100.0 << "\n"; +// cout << "| center: " << setw(10) << (double) (SCORE_DEBUG.PAWN_CENTER[WHITE]) / 100.0 << +// setw(10) << (double) (SCORE_DEBUG.PAWN_CENTER[BLACK]) / 100.0 << "\n"; cout << "| in 7th: " << setw(10) << (double) (SCORE_DEBUG.PAWN_7H[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.PAWN_7H[BLACK]) / 100.0 << "\n"; - cout << "| in 8th: " << setw(10) << - (double) (SCORE_DEBUG.PAWN_IN_8TH[WHITE]) / 100.0 << - setw(10) << (double) (SCORE_DEBUG.PAWN_IN_8TH[BLACK]) / 100.0 << "\n"; + cout << "| in promotion: " << setw(10) << + (double) (SCORE_DEBUG.PAWN_IN_PROMOTION[WHITE]) / 100.0 << + setw(10) << (double) (SCORE_DEBUG.PAWN_IN_PROMOTION[BLACK]) / 100.0 << "\n"; cout << "| blocked: " << setw(10) << (double) (SCORE_DEBUG.PAWN_BLOCKED[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.PAWN_BLOCKED[BLACK]) / 100.0 << "\n"; cout << "| unprotected: " << setw(10) << (double) (SCORE_DEBUG.UNPROTECTED_PAWNS[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.UNPROTECTED_PAWNS[BLACK]) / 100.0 << "\n"; - cout << "| isolated " << setw(10) << - (double) (SCORE_DEBUG.PAWN_ISOLATED[WHITE]) / 100.0 << setw(10) << - (double) (SCORE_DEBUG.PAWN_ISOLATED[BLACK]) / 100.0 << "\n"; - cout << "| double " << setw(10) << - (double) (SCORE_DEBUG.DOUBLED_PAWNS[WHITE]) / 100.0 << setw(10) << - (double) (SCORE_DEBUG.DOUBLED_PAWNS[BLACK]) / 100.0 << "\n"; +// cout << "| isolated " << setw(10) << +// (double) (SCORE_DEBUG.PAWN_ISOLATED[WHITE]) / 100.0 << setw(10) << +// (double) (SCORE_DEBUG.PAWN_ISOLATED[BLACK]) / 100.0 << "\n"; +// cout << "| double " << setw(10) << +// (double) (SCORE_DEBUG.DOUBLED_PAWNS[WHITE]) / 100.0 << setw(10) << +// (double) (SCORE_DEBUG.DOUBLED_PAWNS[BLACK]) / 100.0 << "\n"; cout << "| double isolated " << setw(10) << (double) (SCORE_DEBUG.DOUBLED_ISOLATED_PAWNS[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.DOUBLED_ISOLATED_PAWNS[BLACK]) / 100.0 << "\n"; @@ -630,20 +666,23 @@ short Eval::getScore(const u64 key, const int side, const int alpha, const int b (double) (SCORE_DEBUG.ENEMIES_PAWNS_ALL[BLACK]) / 100.0 << "\n"; cout << "| none: " << setw(10) << (double) (SCORE_DEBUG.NO_PAWNS[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.NO_PAWNS[BLACK]) / 100.0 << "\n"; - +// cout << "| pinned: " << setw(10) << (double) (SCORE_DEBUG.PAWN_PINNED[WHITE]) / 100.0 << +// setw(10) << (double) (SCORE_DEBUG.PAWN_PINNED[BLACK]) / 100.0 << "\n"; cout << HEADER; cout << "|Knight: " << setw(10) << (double) (Tresult.knights[WHITE] - Tresult.knights[BLACK]) / 100.0 << setw(15) << (double) (Tresult.knights[WHITE]) / 100.0 << setw(10) << (double) (Tresult.knights[BLACK]) / 100.0 << "\n"; - cout << "| undevelop: " << setw(10) << - (double) (SCORE_DEBUG.UNDEVELOPED_KNIGHT[WHITE]) / 100.0 << setw(10) << - (double) (SCORE_DEBUG.UNDEVELOPED_KNIGHT[BLACK]) / 100.0 << "\n"; +// cout << "| undevelop: " << setw(10) << +// (double) (SCORE_DEBUG.UNDEVELOPED_KNIGHT[WHITE]) / 100.0 << setw(10) << +// (double) (SCORE_DEBUG.UNDEVELOPED_KNIGHT[BLACK]) / 100.0 << "\n"; cout << "| trapped: " << setw(10) << (double) (SCORE_DEBUG.KNIGHT_TRAPPED[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.KNIGHT_TRAPPED[BLACK]) / 100.0 << "\n"; cout << "| mobility: " << setw(10) << (double) (SCORE_DEBUG.MOB_KNIGHT[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.MOB_KNIGHT[BLACK]) / 100.0 << "\n"; - + cout << "| pinned: " << setw(10) << (double) (SCORE_DEBUG.KNIGHT_PINNED[WHITE]) / 100.0 + << + setw(10) << (double) (SCORE_DEBUG.KNIGHT_PINNED[BLACK]) / 100.0 << "\n"; cout << HEADER; cout << "|Bishop: " << setw(10) << (double) (Tresult.bishop[WHITE] - Tresult.bishop[BLACK]) / 100.0 << setw(15) << (double) (Tresult.bishop[WHITE]) / 100.0 << setw(10) @@ -653,16 +692,18 @@ short Eval::getScore(const u64 key, const int side, const int alpha, const int b setw(10) << (double) (SCORE_DEBUG.BAD_BISHOP[BLACK]) / 100.0 << "\n"; cout << "| mobility: " << setw(10) << (double) (SCORE_DEBUG.MOB_BISHOP[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.MOB_BISHOP[BLACK]) / 100.0 << "\n"; - cout << "| undevelop: " << setw(10) << - (double) (SCORE_DEBUG.UNDEVELOPED_BISHOP[WHITE]) / 100.0 << setw(10) << - (double) (SCORE_DEBUG.UNDEVELOPED_BISHOP[BLACK]) / 100.0 << "\n"; - cout << "| open diag: " << setw(10) << - (double) (SCORE_DEBUG.OPEN_DIAG_BISHOP[WHITE]) / 100.0 << setw(10) << - (double) (SCORE_DEBUG.OPEN_DIAG_BISHOP[BLACK]) / 100.0 << "\n"; +// cout << "| undevelop: " << setw(10) << +// (double) (SCORE_DEBUG.UNDEVELOPED_BISHOP[WHITE]) / 100.0 << setw(10) << +// (double) (SCORE_DEBUG.UNDEVELOPED_BISHOP[BLACK]) / 100.0 << "\n"; +// cout << "| open diag: " << setw(10) << +// (double) (SCORE_DEBUG.OPEN_DIAG_BISHOP[WHITE]) / 100.0 << setw(10) << +// (double) (SCORE_DEBUG.OPEN_DIAG_BISHOP[BLACK]) / 100.0 << "\n"; cout << "| bonus 2 bishops: " << setw(10) << (double) (SCORE_DEBUG.BONUS2BISHOP[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.BONUS2BISHOP[BLACK]) / 100.0 << "\n"; - + cout << "| pinned: " << setw(10) << (double) (SCORE_DEBUG.BISHOP_PINNED[WHITE]) / 100.0 + << + setw(10) << (double) (SCORE_DEBUG.BISHOP_PINNED[BLACK]) / 100.0 << "\n"; cout << HEADER; cout << "|Rook: " << setw(10) << (double) (Tresult.rooks[WHITE] - Tresult.rooks[BLACK]) / 100.0 << setw(15) << (double) (Tresult.rooks[WHITE]) / 100.0 << setw(10) << (double) (Tresult.rooks[BLACK]) / 100.0 @@ -671,21 +712,22 @@ short Eval::getScore(const u64 key, const int side, const int alpha, const int b cout << "| 7th: " << setw(10) << (double) (SCORE_DEBUG.ROOK_7TH_RANK[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.ROOK_7TH_RANK[BLACK]) / 100.0 << "\n"; - cout << "| trapped: " << setw(10) << - (double) (SCORE_DEBUG.ROOK_TRAPPED[WHITE]) / 100.0 << - setw(10) << (double) (SCORE_DEBUG.ROOK_TRAPPED[BLACK]) / 100.0 << "\n"; +// cout << "| trapped: " << setw(10) << +// (double) (SCORE_DEBUG.ROOK_TRAPPED[WHITE]) / 100.0 << +// setw(10) << (double) (SCORE_DEBUG.ROOK_TRAPPED[BLACK]) / 100.0 << "\n"; cout << "| mobility: " << setw(10) << (double) (SCORE_DEBUG.MOB_ROOK[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.MOB_ROOK[BLACK]) / 100.0 << "\n"; - cout << "| blocked: " << setw(10) << - (double) (SCORE_DEBUG.ROOK_BLOCKED[WHITE]) / 100.0 << - setw(10) << (double) (SCORE_DEBUG.ROOK_BLOCKED[BLACK]) / 100.0 << "\n"; - cout << "| open file: " << setw(10) << - (double) (SCORE_DEBUG.ROOK_OPEN_FILE[WHITE]) / 100.0 << setw(10) << - (double) (SCORE_DEBUG.ROOK_OPEN_FILE[BLACK]) / 100.0 << "\n"; - cout << "| connected: " << setw(10) << - (double) (SCORE_DEBUG.CONNECTED_ROOKS[WHITE]) / 100.0 << setw(10) << - (double) (SCORE_DEBUG.CONNECTED_ROOKS[BLACK]) / 100.0 << "\n"; - +// cout << "| blocked: " << setw(10) << +// (double) (SCORE_DEBUG.ROOK_BLOCKED[WHITE]) / 100.0 << +// setw(10) << (double) (SCORE_DEBUG.ROOK_BLOCKED[BLACK]) / 100.0 << "\n"; +// cout << "| open file: " << setw(10) << +// (double) (SCORE_DEBUG.ROOK_OPEN_FILE[WHITE]) / 100.0 << setw(10) << +// (double) (SCORE_DEBUG.ROOK_OPEN_FILE[BLACK]) / 100.0 << "\n"; +// cout << "| connected: " << setw(10) << +// (double) (SCORE_DEBUG.CONNECTED_ROOKS[WHITE]) / 100.0 << setw(10) << +// (double) (SCORE_DEBUG.CONNECTED_ROOKS[BLACK]) / 100.0 << "\n"; + cout << "| pinned: " << setw(10) << (double) (SCORE_DEBUG.ROOK_PINNED[WHITE]) / 100.0 << + setw(10) << (double) (SCORE_DEBUG.ROOK_PINNED[BLACK]) / 100.0 << "\n"; cout << HEADER; cout << "|Queen: " << setw(10) << (double) (Tresult.queens[WHITE] - Tresult.queens[BLACK]) / 100.0 << setw(15) << (double) (Tresult.queens[WHITE]) / 100.0 << setw(10) @@ -696,7 +738,9 @@ short Eval::getScore(const u64 key, const int side, const int alpha, const int b cout << "| bishop on queen: " << setw(10) << (double) (SCORE_DEBUG.BISHOP_ON_QUEEN[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.BISHOP_ON_QUEEN[BLACK]) / 100.0 << "\n"; - + cout << "| pinned: " << setw(10) << (double) (SCORE_DEBUG.QUEEN_PINNED[WHITE]) / 100.0 + << + setw(10) << (double) (SCORE_DEBUG.QUEEN_PINNED[BLACK]) / 100.0 << "\n"; cout << HEADER; cout << "|King: " << setw(10) << (double) (Tresult.kings[WHITE] - Tresult.kings[BLACK]) / 100.0 << setw(15) << (double) (Tresult.kings[WHITE]) / 100.0 << setw(10) << (double) (Tresult.kings[BLACK]) / 100.0 @@ -709,13 +753,14 @@ short Eval::getScore(const u64 key, const int side, const int alpha, const int b cout << "| pawn near: " << setw(10) << (double) (SCORE_DEBUG.PAWN_NEAR_KING[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.PAWN_NEAR_KING[BLACK]) / 100.0 << "\n"; -// cout << "| mobility: " << setw(10) << (double) (SCORE_DEBUG.MOB_KING[WHITE]) / 100.0 << setw(10) << (double) (SCORE_DEBUG.MOB_KING[BLACK]) / 100.0 << "\n"; cout << endl; - cout << "\n|Total (white).......... " << (side ? result / 100.0 : -result / 100.0) << endl; + cout << "\n|Total (white).......... " << (side ? -result / 100.0 : result / 100.0) << endl; cout << flush; } #endif +#ifndef TUNING storeHashValue(key, result); +#endif return side ? -result : result; } diff --git a/src/Eval.h b/src/Eval.h index c8116a8e..e0c16dc1 100644 --- a/src/Eval.h +++ b/src/Eval.h @@ -22,112 +22,135 @@ #include "namespaces/board.h" #ifdef BENCH_MODE + #include "util/bench/Times.h" + #endif + #include #include #include using namespace constants; -class Eval: public GenMoves { +class Eval { public: Eval(); - ~Eval() override; + ~Eval(); - short getScore(const u64 key, const int side, const int alpha, const int beta, const bool trace); + short getScore(const _Tchessboard &chessboard, const u64 key, const uchar side, const int alpha, const int beta + DEBUG2(,const bool trace = false) + ); - template - int lazyEval() { - return lazyEvalSide() - lazyEvalSide(); + template + int lazyEval(const _Tchessboard &chessboard) const { + return lazyEvalSide(chessboard) - lazyEvalSide(chessboard); } - DEBUG(unsigned lazyEvalCuts) + STATIC_CONST int REVERSE_FUTIL_MARGIN = 180; + STATIC_CONST int FUTIL_MARGIN = 220; + STATIC_CONST int EXT_FUTIL_MARGIN = 550; + STATIC_CONST int RAZOR_MARGIN = 1171; + STATIC_CONST int ATTACK_KING = 45; + STATIC_CONST int BISHOP_ON_QUEEN = 8; + STATIC_CONST int BACKWARD_PAWN = 6; + STATIC_CONST int DOUBLED_ISOLATED_PAWNS = 9; +// STATIC_CONST int DOUBLED_PAWNS = 0; + STATIC_CONST int PAWN_IN_7TH = 21; +// STATIC_CONST int PAWN_CENTER = 0; + STATIC_CONST int PAWN_IN_PROMOTION = 99; +// STATIC_CONST int PAWN_ISOLATED = 0; + STATIC_CONST int PAWN_NEAR_KING = 11; + STATIC_CONST int PAWN_BLOCKED = 8; + STATIC_CONST int UNPROTECTED_PAWNS = 6; +// STATIC_CONST int ENEMY_NEAR_KING = 0; + STATIC_CONST int FRIEND_NEAR_KING = 8; +// STATIC_CONST int HALF_OPEN_FILE_Q = 0; + STATIC_CONST int BONUS2BISHOP = 33; + STATIC_CONST int BISHOP_PAWN_ON_SAME_COLOR = 2; +// STATIC_CONST int CONNECTED_ROOKS = 0; +// STATIC_CONST int OPEN_FILE = 0; + STATIC_CONST int OPEN_FILE_Q = 4; + STATIC_CONST int ROOK_7TH_RANK = 13; +// STATIC_CONST int ROOK_BLOCKED = 0; +// STATIC_CONST int ROOK_TRAPPED = 0; +// STATIC_CONST int UNDEVELOPED_KNIGHT = 0; +// STATIC_CONST int UNDEVELOPED_BISHOP = 0; + STATIC_CONST int KNIGHT_PINNED = 54; + STATIC_CONST int ROOK_PINNED = 29; + STATIC_CONST int BISHOP_PINNED = 26; + STATIC_CONST int QUEEN_PINNED = 2; +// STATIC_CONST int QUEEN_IN_7 = 10; + STATIC_CONST int ROOK_IN_7 = 7; +// STATIC_CONST int PAWN_PINNED = 0; -protected: - STATIC_CONST int FUTIL_MARGIN = 154; - STATIC_CONST int EXT_FUTILY_MARGIN = 392; - STATIC_CONST int RAZOR_MARGIN = 1071; - STATIC_CONST int ATTACK_KING = 30; - STATIC_CONST int BISHOP_ON_QUEEN = 2; - STATIC_CONST int BACKWARD_PAWN = 2; - STATIC_CONST int DOUBLED_ISOLATED_PAWNS = 14; - STATIC_CONST int DOUBLED_PAWNS = 5; - STATIC_CONST int PAWN_IN_7TH = 32; - STATIC_CONST int PAWN_CENTER = 15; - STATIC_CONST int PAWN_IN_8TH = 114; - STATIC_CONST int PAWN_ISOLATED = 3; - STATIC_CONST int PAWN_NEAR_KING = 2; - STATIC_CONST int PAWN_BLOCKED = 5; - STATIC_CONST int UNPROTECTED_PAWNS = 5; - STATIC_CONST int ENEMY_NEAR_KING = 2; - STATIC_CONST int FRIEND_NEAR_KING = 1; - STATIC_CONST int HALF_OPEN_FILE_Q = 3; - STATIC_CONST int BONUS2BISHOP = 18; - STATIC_CONST int BISHOP_PAWN_ON_SAME_COLOR = 5; - STATIC_CONST int CONNECTED_ROOKS = 7; - STATIC_CONST int OPEN_FILE = 10; - STATIC_CONST int OPEN_FILE_Q = 3; - STATIC_CONST int ROOK_7TH_RANK = 10; - STATIC_CONST int ROOK_BLOCKED = 13; - STATIC_CONST int ROOK_TRAPPED = 6; - STATIC_CONST int UNDEVELOPED_KNIGHT = 4; - STATIC_CONST int UNDEVELOPED_BISHOP = 4; #ifdef DEBUG_MODE + unsigned lazyEvalCuts; typedef struct { int BAD_BISHOP[2]; int MOB_BISHOP[2]; - int UNDEVELOPED_BISHOP[2]; +// int UNDEVELOPED_BISHOP[2]; int OPEN_DIAG_BISHOP[2]; int BONUS2BISHOP[2]; - +// int PAWN_PINNED[2]; + int BISHOP_PINNED[2]; + int QUEEN_PINNED[2]; + int KNIGHT_PINNED[2]; + int ROOK_PINNED[2]; int ATTACK_KING_PAWN[2]; - int PAWN_CENTER[2]; +// int PAWN_CENTER[2]; int PAWN_7H[2]; - int PAWN_IN_8TH[2]; + int PAWN_IN_PROMOTION[2]; int PAWN_BLOCKED[2]; int UNPROTECTED_PAWNS[2]; - int PAWN_ISOLATED[2]; - int DOUBLED_PAWNS[2]; +// int PAWN_ISOLATED[2]; +// int DOUBLED_PAWNS[2]; int DOUBLED_ISOLATED_PAWNS[2]; int BACKWARD_PAWN[2]; int FORK_SCORE[2]; int PAWN_PASSED[2]; int ENEMIES_PAWNS_ALL[2]; int NO_PAWNS[2]; - - int KING_SECURITY_BISHOP[2]; +// int KING_SECURITY_BISHOP[2]; int KING_SECURITY_QUEEN[2]; int KING_SECURITY_KNIGHT[2]; int KING_SECURITY_ROOK[2]; int DISTANCE_KING[2]; int PAWN_NEAR_KING[2]; int MOB_KING[2]; - int MOB_QUEEN[2]; int OPEN_FILE_Q[2]; int BISHOP_ON_QUEEN[2]; - int HALF_OPEN_FILE_Q[2]; - - int UNDEVELOPED_KNIGHT[2]; +// int HALF_OPEN_FILE_Q[2]; +// int UNDEVELOPED_KNIGHT[2]; int KNIGHT_TRAPPED[2]; int MOB_KNIGHT[2]; - - int ROOK_7TH_RANK[2]; - int ROOK_TRAPPED[2]; +// int ROOK_TRAPPED[2]; int MOB_ROOK[2]; - int ROOK_BLOCKED[2]; +// int ROOK_BLOCKED[2]; int ROOK_OPEN_FILE[2]; - int CONNECTED_ROOKS[2]; +// int CONNECTED_ROOKS[2]; } _TSCORE_DEBUG; _TSCORE_DEBUG SCORE_DEBUG; #endif private: + + typedef struct { + u64 allPieces; + u64 kingAttackers[2]; + u64 allPiecesSide[2]; + u64 allPiecesNoPawns[2]; + u64 posKingBit[2]; + int kingSecurity[2]; + uchar posKing[2]; + u64 pinned[2]; + } _Tboard; + _Tboard structureEval; static constexpr int hashSize = 65536; static constexpr u64 keyMask = 0xffffffffffff0000ULL; static constexpr u64 valueMask = 0xffffULL; @@ -137,10 +160,8 @@ class Eval: public GenMoves { inline void storeHashValue(const u64 key, const short value); - static inline short getHashValue(const u64 key) ; -#ifdef BENCH_MODE - Times* times = &Times::getInstance(); -#endif + static inline short getHashValue(const u64 key); + enum _Tphase { OPEN, MIDDLE, END }; @@ -157,66 +178,68 @@ class Eval: public GenMoves { DEBUG(int evaluationCount[2]) template<_Tphase phase> - void getRes(_Tresult &res) { + void getRes(const _Tchessboard &chessboard, _Tresult &res) { - BENCH(times->start("eval pawn")); - res.pawns[BLACK] = evaluatePawn(); - res.pawns[WHITE] = evaluatePawn(); - BENCH(times->stop("eval pawn")); + BENCH_START("eval pawn") + res.pawns[BLACK] = evaluatePawn(chessboard); + res.pawns[WHITE] = evaluatePawn(chessboard); + BENCH_STOP("eval pawn") - BENCH(times->start("eval bishop")); - res.bishop[BLACK] = evaluateBishop(structureEval.allPiecesSide[WHITE]); - res.bishop[WHITE] = evaluateBishop(structureEval.allPiecesSide[BLACK]); - BENCH(times->stop("eval bishop")); + BENCH_START("eval bishop") + res.bishop[BLACK] = evaluateBishop(chessboard, structureEval.allPiecesSide[WHITE]); + res.bishop[WHITE] = evaluateBishop(chessboard, structureEval.allPiecesSide[BLACK]); + BENCH_STOP("eval bishop") - BENCH(times->start("eval queen")); - res.queens[BLACK] = evaluateQueen(structureEval.allPiecesSide[WHITE]); - res.queens[WHITE] = evaluateQueen(structureEval.allPiecesSide[BLACK]); - BENCH(times->stop("eval queen")); + BENCH_START("eval queen") + res.queens[BLACK] = evaluateQueen(chessboard, structureEval.allPiecesSide[WHITE]); + res.queens[WHITE] = evaluateQueen(chessboard, structureEval.allPiecesSide[BLACK]); + BENCH_STOP("eval queen") - BENCH(times->start("eval rook")); - res.rooks[BLACK] = evaluateRook(chessboard[KING_BLACK], structureEval.allPiecesSide[WHITE], + BENCH_START("eval rook") + res.rooks[BLACK] = evaluateRook(chessboard, + structureEval.allPiecesSide[WHITE], structureEval.allPiecesSide[BLACK]); - res.rooks[WHITE] = evaluateRook(chessboard[KING_WHITE], structureEval.allPiecesSide[BLACK], + res.rooks[WHITE] = evaluateRook(chessboard, + structureEval.allPiecesSide[BLACK], structureEval.allPiecesSide[WHITE]); - BENCH(times->stop("eval rook")); + BENCH_STOP("eval rook") - BENCH(times->start("eval knight")); - res.knights[BLACK] = evaluateKnight(~structureEval.allPiecesSide[BLACK]); - res.knights[WHITE] = evaluateKnight(~structureEval.allPiecesSide[WHITE]); - BENCH(times->stop("eval knight")); + BENCH_START("eval knight") + res.knights[BLACK] = evaluateKnight(chessboard, ~structureEval.allPiecesSide[BLACK]); + res.knights[WHITE] = evaluateKnight(chessboard, ~structureEval.allPiecesSide[WHITE]); + BENCH_STOP("eval knight") - BENCH(times->start("eval king")); - res.kings[BLACK] = evaluateKing(BLACK, ~structureEval.allPiecesSide[BLACK]); - res.kings[WHITE] = evaluateKing(WHITE, ~structureEval.allPiecesSide[WHITE]); - BENCH(times->stop("eval king")); + BENCH_START("eval king") + res.kings[BLACK] = evaluateKing(chessboard, BLACK, ~structureEval.allPiecesSide[BLACK]); + res.kings[WHITE] = evaluateKing(chessboard, WHITE, ~structureEval.allPiecesSide[WHITE]); + BENCH_STOP("eval king") } - template - int evaluatePawn(); + template + int evaluatePawn(const _Tchessboard &chessboard); - template - int evaluateBishop(const u64); + template + int evaluateBishop(const _Tchessboard &chessboard, const u64); - template - int evaluateQueen(const u64 enemies); + template + int evaluateQueen(const _Tchessboard &chessboard, const u64 enemies); - template - int evaluateKnight(const u64); + template + int evaluateKnight(const _Tchessboard &chessboard, const u64); - template - int evaluateRook(const u64, u64 enemies, u64 friends); + template + int evaluateRook(const _Tchessboard &chessboard, u64 enemies, u64 friends); template<_Tphase phase> - int evaluateKing(int side, u64 squares); + int evaluateKing(const _Tchessboard &chessboard, const uchar side, const u64 squares); - template - int lazyEvalSide() { + template + int lazyEvalSide(const _Tchessboard &chessboard) const { return bitCount(chessboard[PAWN_BLACK + side]) * VALUEPAWN + - bitCount(chessboard[ROOK_BLACK + side]) * VALUEROOK + - bitCount(chessboard[BISHOP_BLACK + side]) * VALUEBISHOP + - bitCount(chessboard[KNIGHT_BLACK + side]) * VALUEKNIGHT + - bitCount(chessboard[QUEEN_BLACK + side]) * VALUEQUEEN; + bitCount(chessboard[ROOK_BLACK + side]) * VALUEROOK + + bitCount(chessboard[BISHOP_BLACK + side]) * VALUEBISHOP + + bitCount(chessboard[KNIGHT_BLACK + side]) * VALUEKNIGHT + + bitCount(chessboard[QUEEN_BLACK + side]) * VALUEQUEEN; } }; @@ -224,53 +247,60 @@ class Eval: public GenMoves { namespace _eval { constexpr int BISHOP_OUTPOST[2][64] = { - {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 3, 3, 3, 3, 1, 0, - 0, 3, 5, 5, 5, 5, 3, 0, - 0, 1, 2, 2, 2, 2, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 2, 2, 2, 2, 1, 0, - 0, 3, 5, 5, 5, 5, 3, 0, - 0, 1, 3, 3, 3, 3, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0} + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 3, 3, 3, 3, 1, 0, + 0, 3, 5, 5, 5, 5, 3, 0, + 0, 1, 2, 2, 2, 2, 1, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 1, 2, 2, 2, 2, 1, 0, + 0, 3, 5, 5, 5, 5, 3, 0, + 0, 1, 3, 3, 3, 3, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} }; constexpr int KNIGHT_OUTPOST[2][64] = { - {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 4, 4, 4, 4, 1, 0, - 0, 2, 6, 8, 8, 6, 2, 0, - 0, 1, 4, 4, 4, 4, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 4, 4, 4, 4, 1, 0, + 0, 2, 6, 8, 8, 6, 2, 0, + 0, 1, 4, 4, 4, 4, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 4, 4, 4, 4, 1, 0, - 0, 2, 6, 8, 8, 6, 2, 0, - 0, 1, 4, 4, 4, 4, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0} + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 4, 4, 4, 4, 1, 0, + 0, 2, 6, 8, 8, 6, 2, 0, + 0, 1, 4, 4, 4, 4, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} }; static constexpr int - MOB_QUEEN[3][29] = {{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {-10, -9, -5, 0, 3, 6, 7, 10, 11, 12, 15, 18, 28, 30, 32, 35, 40, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61}, - {-20, -15, -10, 0, 1, 3, 4, 9, 11, 12, 15, 18, 28, 30, 32, 33, 34, 36, 37, 39, 40, 41, 42, - 43, 44, 45, 56, 47, 48}}; + MOB_QUEEN[3][29] = + {{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1}, + {-10, -9, -5, 0, 3, 6, 7, 10, 11, 12, 15, 18, 28, 30, 32, 35, 40, 50, 51, + 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61}, + {-20, -15, -10, 0, 1, 3, 4, 9, 11, 12, 15, 18, 28, 30, 32, 33, 34, 36, 37, + 39, 40, 41, 42, + 43, 44, 45, 56, 47, 48} + }; - static constexpr int MOB_ROOK[3][15] = {{-1, 0, 1, 4, 5, 6, 7, 9, 12, 14, 19, 22, 23, 24, 25}, - {-9, -8, 1, 8, 9, 10, 15, 20, 28, 30, 40, 45, 50, 51, 52}, - {-15, -10, -5, 0, 9, 11, 16, 22, 30, 32, 40, 45, 50, 51, 52}}; + static constexpr int MOB_ROOK[3][15] = + {{-1, 0, 1, 4, 5, 6, 7, 9, 12, 14, 19, 22, 23, 24, 25}, + {-9, -8, 1, 8, 9, 10, 15, 20, 28, 30, 40, 45, 50, 51, 52}, + {-15, -10, -5, 0, 9, 11, 16, 22, 30, 32, 40, 45, 50, 51, 52} + }; static constexpr int MOB_KNIGHT[9] = {-8, -4, @@ -280,1078 +310,2046 @@ namespace _eval { 20, 30, 35, - 40}; + 40 + }; - static constexpr int MOB_BISHOP[3][14] = {{-8, -7, 2, 8, 9, 10, 15, 20, 28, 30, 40, 45, 50, 50}, - {-20, -10, -4, 0, 5, 10, 15, 20, 28, 30, 40, 45, 50, 50}, - {-20, -10, -4, 0, 3, 8, 13, 18, 25, 30, 40, 45, 50, 50}}; + static constexpr int MOB_BISHOP[3][14] = + {{-8, -7, 2, 8, 9, 10, 15, 20, 28, 30, 40, 45, 50, 50}, + {-20, -10, -4, 0, 5, 10, 15, 20, 28, 30, 40, 45, 50, 50}, + {-20, -10, -4, 0, 3, 8, 13, 18, 25, 30, 40, 45, 50, 50} + }; - static constexpr int MOB_KING[3][9] = {{1, 2, 2, 1, 0, 0, 0, 0, 0}, - {-5, 0, 5, 5, 5, 0, 0, 0, 0}, - {-50, -30, -10, 10, 25, 40, 50, 55, 60}}; + static constexpr int MOB_KING[3][9] = {{1, 2, 2, 1, 0, 0, 0, 0, 0}, + {-5, 0, 5, 5, 5, 0, 0, 0, 0}, + {-50, -30, -10, 10, 25, 40, 50, 55, 60} + }; static constexpr int MOB_CASTLE[3][3] = {{-50, 30, 50}, - {-1, 10, 10}, - {0, 0, 0}}; + {-1, 10, 10}, + {0, 0, 0} + }; - static constexpr int BONUS_ATTACK_KING[18] = {-1, 2, 8, 64, 128, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512}; + static constexpr int BONUS_ATTACK_KING[18] = + {-1, 2, 8, 64, 128, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512 + }; static constexpr u64 PAWN_PROTECTED_MASK[2][64] = - {{0x200ULL, 0x500ULL, 0xa00ULL, 0x1400ULL, 0x2800ULL, 0x5000ULL, 0xa000ULL, 0x4000ULL, 0x20000ULL, 0x50000ULL, - 0xa0000ULL, 0x140000ULL, 0x280000ULL, 0x500000ULL, 0xa00000ULL, 0x400000ULL, 0x2000000ULL, 0x5000000ULL, - 0xa000000ULL, 0x14000000ULL, 0x28000000ULL, 0x50000000ULL, 0xa0000000ULL, 0x40000000ULL, 0x200000000ULL, - 0x500000000ULL, 0xa00000000ULL, 0x1400000000ULL, 0x2800000000ULL, 0x5000000000ULL, 0xa000000000ULL, - 0x4000000000ULL, 0x20000000000ULL, 0x50000000000ULL, 0xa0000000000ULL, 0x140000000000ULL, 0x280000000000ULL, - 0x500000000000ULL, 0xa00000000000ULL, 0x400000000000ULL, 0x2000000000000ULL, 0x5000000000000ULL, - 0xa000000000000ULL, 0x14000000000000ULL, 0x28000000000000ULL, 0x50000000000000ULL, 0xa0000000000000ULL, - 0x40000000000000ULL, 0xFF000000000000ULL, 0xFF000000000000ULL, 0xFF000000000000ULL, 0xFF000000000000ULL, - 0xFF000000000000ULL, 0xFF000000000000ULL, 0xFF000000000000ULL, 0xFF000000000000ULL, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0xFF00ULL, 0xFF00ULL, 0xFF00ULL, 0xFF00ULL, 0xFF00ULL, 0xFF00ULL, 0xFF00ULL, - 0xFF00ULL, 0x200ULL, 0x500ULL, 0xa00ULL, 0x1400ULL, 0x2800ULL, 0x5000ULL, 0xa000ULL, 0x4000ULL, 0x20000ULL, - 0x50000ULL, 0xa0000ULL, 0x140000ULL, 0x280000ULL, 0x500000ULL, 0xa00000ULL, 0x400000ULL, 0x2000000ULL, - 0x5000000ULL, 0xa000000ULL, 0x14000000ULL, 0x28000000ULL, 0x50000000ULL, 0xa0000000ULL, 0x40000000ULL, - 0x200000000ULL, 0x500000000ULL, 0xa00000000ULL, 0x1400000000ULL, 0x2800000000ULL, 0x5000000000ULL, - 0xa000000000ULL, 0x4000000000ULL, 0x20000000000ULL, 0x50000000000ULL, 0xa0000000000ULL, 0x140000000000ULL, - 0x280000000000ULL, 0x500000000000ULL, 0xa00000000000ULL, 0x400000000000ULL, 0xFF00000000000000ULL, - 0xFF00000000000000ULL, 0xFF00000000000000ULL, 0xFF00000000000000ULL, 0xFF00000000000000ULL, - 0xFF00000000000000ULL, 0xFF00000000000000ULL, 0xFF00000000000000ULL}}; + {{0x200ULL, 0x500ULL, 0xa00ULL, 0x1400ULL, 0x2800ULL, 0x5000ULL, + 0xa000ULL, 0x4000ULL, 0x20000ULL, 0x50000ULL, + 0xa0000ULL, 0x140000ULL, 0x280000ULL, 0x500000ULL, 0xa00000ULL, + 0x400000ULL, 0x2000000ULL, 0x5000000ULL, + 0xa000000ULL, 0x14000000ULL, 0x28000000ULL, 0x50000000ULL, + 0xa0000000ULL, 0x40000000ULL, 0x200000000ULL, + 0x500000000ULL, 0xa00000000ULL, 0x1400000000ULL, 0x2800000000ULL, + 0x5000000000ULL, 0xa000000000ULL, + 0x4000000000ULL, 0x20000000000ULL, 0x50000000000ULL, 0xa0000000000ULL, + 0x140000000000ULL, 0x280000000000ULL, + 0x500000000000ULL, 0xa00000000000ULL, 0x400000000000ULL, + 0x2000000000000ULL, 0x5000000000000ULL, + 0xa000000000000ULL, 0x14000000000000ULL, 0x28000000000000ULL, + 0x50000000000000ULL, 0xa0000000000000ULL, + 0x40000000000000ULL, 0xFF000000000000ULL, 0xFF000000000000ULL, + 0xFF000000000000ULL, 0xFF000000000000ULL, + 0xFF000000000000ULL, 0xFF000000000000ULL, 0xFF000000000000ULL, + 0xFF000000000000ULL, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0xFF00ULL, 0xFF00ULL, 0xFF00ULL, 0xFF00ULL, + 0xFF00ULL, 0xFF00ULL, 0xFF00ULL, + 0xFF00ULL, 0x200ULL, 0x500ULL, 0xa00ULL, 0x1400ULL, 0x2800ULL, 0x5000ULL, + 0xa000ULL, 0x4000ULL, 0x20000ULL, + 0x50000ULL, 0xa0000ULL, 0x140000ULL, 0x280000ULL, 0x500000ULL, 0xa00000ULL, + 0x400000ULL, 0x2000000ULL, + 0x5000000ULL, 0xa000000ULL, 0x14000000ULL, 0x28000000ULL, 0x50000000ULL, + 0xa0000000ULL, 0x40000000ULL, + 0x200000000ULL, 0x500000000ULL, 0xa00000000ULL, 0x1400000000ULL, + 0x2800000000ULL, 0x5000000000ULL, + 0xa000000000ULL, 0x4000000000ULL, 0x20000000000ULL, 0x50000000000ULL, + 0xa0000000000ULL, 0x140000000000ULL, + 0x280000000000ULL, 0x500000000000ULL, 0xa00000000000ULL, 0x400000000000ULL, + 0xFF00000000000000ULL, + 0xFF00000000000000ULL, 0xFF00000000000000ULL, 0xFF00000000000000ULL, + 0xFF00000000000000ULL, + 0xFF00000000000000ULL, 0xFF00000000000000ULL, 0xFF00000000000000ULL} + }; static constexpr u64 PAWN_BACKWARD_MASK[2][64] = - {{0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 131584ULL, 328960ULL, 657920ULL, 1315840ULL, 2631680ULL, - 5263360ULL, 10526720ULL, 4210688ULL, 33685504ULL, 84213760ULL, 168427520ULL, 336855040ULL, 673710080ULL, - 1347420160ULL, 2694840320ULL, 1077936128ULL, 8623489024ULL, 21558722560ULL, 43117445120ULL, 86234890240ULL, - 172469780480ULL, 344939560960ULL, 689879121920ULL, 275951648768ULL, 2207613190144ULL, 5519032975360ULL, - 11038065950720ULL, 22076131901440ULL, 44152263802880ULL, 88304527605760ULL, 176609055211520ULL, - 70643622084608ULL, 565148976676864ULL, 1412872441692160ULL, 2825744883384320ULL, 5651489766768640ULL, - 11302979533537280ULL, 22605959067074560ULL, 45211918134149120ULL, 18084767253659648ULL, 562949953421312ULL, - 1407374883553280ULL, 2814749767106560ULL, 5629499534213120ULL, 11258999068426240ULL, 22517998136852480ULL, - 45035996273704960ULL, 18014398509481984ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0}, - {0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 512ULL, 1280ULL, 2560ULL, 5120ULL, 10240ULL, 20480ULL, - 40960ULL, 16384ULL, 131584ULL, 328960ULL, 657920ULL, 1315840ULL, 2631680ULL, 5263360ULL, 10526720ULL, - 4210688ULL, 33685504ULL, 84213760ULL, 168427520ULL, 336855040ULL, 673710080ULL, 1347420160ULL, 2694840320ULL, - 1077936128ULL, 8623489024ULL, 21558722560ULL, 43117445120ULL, 86234890240ULL, 172469780480ULL, - 344939560960ULL, 689879121920ULL, 275951648768ULL, 2207613190144ULL, 5519032975360ULL, 11038065950720ULL, - 22076131901440ULL, 44152263802880ULL, 88304527605760ULL, 176609055211520ULL, 70643622084608ULL, - 565148976676864ULL, 1412872441692160ULL, 2825744883384320ULL, 5651489766768640ULL, 11302979533537280ULL, - 22605959067074560ULL, 45211918134149120ULL, 18084767253659648ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, - 0}}; + {{0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 131584ULL, 328960ULL, + 657920ULL, 1315840ULL, 2631680ULL, + 5263360ULL, 10526720ULL, 4210688ULL, 33685504ULL, 84213760ULL, + 168427520ULL, 336855040ULL, 673710080ULL, + 1347420160ULL, 2694840320ULL, 1077936128ULL, 8623489024ULL, + 21558722560ULL, 43117445120ULL, 86234890240ULL, + 172469780480ULL, 344939560960ULL, 689879121920ULL, 275951648768ULL, + 2207613190144ULL, 5519032975360ULL, + 11038065950720ULL, 22076131901440ULL, 44152263802880ULL, + 88304527605760ULL, 176609055211520ULL, + 70643622084608ULL, 565148976676864ULL, 1412872441692160ULL, + 2825744883384320ULL, 5651489766768640ULL, + 11302979533537280ULL, 22605959067074560ULL, 45211918134149120ULL, + 18084767253659648ULL, 562949953421312ULL, + 1407374883553280ULL, 2814749767106560ULL, 5629499534213120ULL, + 11258999068426240ULL, 22517998136852480ULL, + 45035996273704960ULL, 18014398509481984ULL, 0ULL, 0ULL, 0ULL, 0ULL, + 0ULL, 0ULL, 0ULL, 0}, + {0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 512ULL, 1280ULL, 2560ULL, + 5120ULL, 10240ULL, 20480ULL, + 40960ULL, 16384ULL, 131584ULL, 328960ULL, 657920ULL, 1315840ULL, + 2631680ULL, 5263360ULL, 10526720ULL, + 4210688ULL, 33685504ULL, 84213760ULL, 168427520ULL, 336855040ULL, + 673710080ULL, 1347420160ULL, 2694840320ULL, + 1077936128ULL, 8623489024ULL, 21558722560ULL, 43117445120ULL, + 86234890240ULL, 172469780480ULL, + 344939560960ULL, 689879121920ULL, 275951648768ULL, 2207613190144ULL, + 5519032975360ULL, 11038065950720ULL, + 22076131901440ULL, 44152263802880ULL, 88304527605760ULL, + 176609055211520ULL, 70643622084608ULL, + 565148976676864ULL, 1412872441692160ULL, 2825744883384320ULL, + 5651489766768640ULL, 11302979533537280ULL, + 22605959067074560ULL, 45211918134149120ULL, 18084767253659648ULL, 0ULL, + 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, + 0} + }; static constexpr u64 PAWN_PASSED_MASK[2][64] = - {{0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x3ULL, 0x7ULL, 0xeULL, 0x1cULL, 0x38ULL, - 0x70ULL, 0xe0ULL, 0xc0ULL, 0x303ULL, 0x707ULL, 0xe0eULL, 0x1c1cULL, 0x3838ULL, 0x7070ULL, 0xe0e0ULL, - 0xc0c0ULL, 0x30303ULL, 0x70707ULL, 0xe0e0eULL, 0x1c1c1cULL, 0x383838ULL, 0x707070ULL, 0xe0e0e0ULL, - 0xc0c0c0ULL, 0x3030303ULL, 0x7070707ULL, 0xe0e0e0eULL, 0x1c1c1c1cULL, 0x38383838ULL, 0x70707070ULL, - 0xe0e0e0e0ULL, 0xc0c0c0c0ULL, 0x303030303ULL, 0x707070707ULL, 0xe0e0e0e0eULL, 0x1c1c1c1c1cULL, - 0x3838383838ULL, 0x7070707070ULL, 0xe0e0e0e0e0ULL, 0xc0c0c0c0c0ULL, 0x30303030303ULL, 0x70707070707ULL, - 0xe0e0e0e0e0eULL, 0x1c1c1c1c1c1cULL, 0x383838383838ULL, 0x707070707070ULL, 0xe0e0e0e0e0e0ULL, - 0xc0c0c0c0c0c0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0}, - {0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x303030303030000ULL, 0x707070707070000ULL, - 0xe0e0e0e0e0e0000ULL, 0x1c1c1c1c1c1c0000ULL, 0x3838383838380000ULL, 0x7070707070700000ULL, - 0xe0e0e0e0e0e00000ULL, 0xc0c0c0c0c0c00000ULL, 0x303030303000000ULL, 0x707070707000000ULL, - 0xe0e0e0e0e000000ULL, 0x1c1c1c1c1c000000ULL, 0x3838383838000000ULL, 0x7070707070000000ULL, - 0xe0e0e0e0e0000000ULL, 0xc0c0c0c0c0000000ULL, 0x303030300000000ULL, 0x707070700000000ULL, - 0xe0e0e0e00000000ULL, 0x1c1c1c1c00000000ULL, 0x3838383800000000ULL, 0x7070707000000000ULL, - 0xe0e0e0e000000000ULL, 0xc0c0c0c000000000ULL, 0x303030000000000ULL, 0x707070000000000ULL, - 0xe0e0e0000000000ULL, 0x1c1c1c0000000000ULL, 0x3838380000000000ULL, 0x7070700000000000ULL, - 0xe0e0e00000000000ULL, 0xc0c0c00000000000ULL, 0x303000000000000ULL, 0x707000000000000ULL, - 0xe0e000000000000ULL, 0x1c1c000000000000ULL, 0x3838000000000000ULL, 0x7070000000000000ULL, - 0xe0e0000000000000ULL, 0xc0c0000000000000ULL, 0x300000000000000ULL, 0x700000000000000ULL, - 0xe00000000000000ULL, 0x1c00000000000000ULL, 0x3800000000000000ULL, 0x7000000000000000ULL, - 0xe000000000000000ULL, 0xc000000000000000ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0}}; + {{0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x3ULL, + 0x7ULL, 0xeULL, 0x1cULL, 0x38ULL, + 0x70ULL, 0xe0ULL, 0xc0ULL, 0x303ULL, 0x707ULL, 0xe0eULL, 0x1c1cULL, + 0x3838ULL, 0x7070ULL, 0xe0e0ULL, + 0xc0c0ULL, 0x30303ULL, 0x70707ULL, 0xe0e0eULL, 0x1c1c1cULL, + 0x383838ULL, 0x707070ULL, 0xe0e0e0ULL, + 0xc0c0c0ULL, 0x3030303ULL, 0x7070707ULL, 0xe0e0e0eULL, 0x1c1c1c1cULL, + 0x38383838ULL, 0x70707070ULL, + 0xe0e0e0e0ULL, 0xc0c0c0c0ULL, 0x303030303ULL, 0x707070707ULL, + 0xe0e0e0e0eULL, 0x1c1c1c1c1cULL, + 0x3838383838ULL, 0x7070707070ULL, 0xe0e0e0e0e0ULL, 0xc0c0c0c0c0ULL, + 0x30303030303ULL, 0x70707070707ULL, + 0xe0e0e0e0e0eULL, 0x1c1c1c1c1c1cULL, 0x383838383838ULL, + 0x707070707070ULL, 0xe0e0e0e0e0e0ULL, + 0xc0c0c0c0c0c0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, + 0x0ULL, 0x0}, + {0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, + 0x303030303030000ULL, 0x707070707070000ULL, + 0xe0e0e0e0e0e0000ULL, 0x1c1c1c1c1c1c0000ULL, 0x3838383838380000ULL, + 0x7070707070700000ULL, + 0xe0e0e0e0e0e00000ULL, 0xc0c0c0c0c0c00000ULL, 0x303030303000000ULL, + 0x707070707000000ULL, + 0xe0e0e0e0e000000ULL, 0x1c1c1c1c1c000000ULL, 0x3838383838000000ULL, + 0x7070707070000000ULL, + 0xe0e0e0e0e0000000ULL, 0xc0c0c0c0c0000000ULL, 0x303030300000000ULL, + 0x707070700000000ULL, + 0xe0e0e0e00000000ULL, 0x1c1c1c1c00000000ULL, 0x3838383800000000ULL, + 0x7070707000000000ULL, + 0xe0e0e0e000000000ULL, 0xc0c0c0c000000000ULL, 0x303030000000000ULL, + 0x707070000000000ULL, + 0xe0e0e0000000000ULL, 0x1c1c1c0000000000ULL, 0x3838380000000000ULL, + 0x7070700000000000ULL, + 0xe0e0e00000000000ULL, 0xc0c0c00000000000ULL, 0x303000000000000ULL, + 0x707000000000000ULL, + 0xe0e000000000000ULL, 0x1c1c000000000000ULL, 0x3838000000000000ULL, + 0x7070000000000000ULL, + 0xe0e0000000000000ULL, 0xc0c0000000000000ULL, 0x300000000000000ULL, + 0x700000000000000ULL, + 0xe00000000000000ULL, 0x1c00000000000000ULL, 0x3800000000000000ULL, + 0x7000000000000000ULL, + 0xe000000000000000ULL, 0xc000000000000000ULL, 0x0ULL, 0x0ULL, 0x0ULL, + 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0} + }; static constexpr short PAWN_PASSED[2][64] = {{0, 0, 0, 0, 0, 0, 0, 0, - 90, 90, 90, 90, 90, 90, 90, 90, - 70, 70, 70, 70, 70, 70, 70, 70, - 45, 45, 45, 45, 45, 45, 45, 45, - 12, 12, 12, 12, 12, 12, 12, 12, - 5, 5, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}, + 90, 90, 90, 90, 90, 90, 90, + 90, + 70, 70, 70, 70, 70, 70, 70, + 70, + 45, 45, 45, 45, 45, 45, 45, + 45, + 12, 12, 12, 12, 12, 12, 12, + 12, + 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, - 12, 12, 12, 12, 12, 12, 12, 12, - 45, 45, 45, 45, 45, 45, 45, 45, - 70, 70, 70, 70, 70, 70, 70, 70, - 90, 90, 90, 90, 90, 90, 90, 90, - 0, 0, 0, 0, 0, 0, 0, 0}}; + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, + 12, 12, 12, 12, 12, 12, 12, 12, + 45, 45, 45, 45, 45, 45, 45, 45, + 70, 70, 70, 70, 70, 70, 70, 70, + 90, 90, 90, 90, 90, 90, 90, 90, + 0, 0, 0, 0, 0, 0, 0, 0} + }; - static constexpr u64 PAWN_ISOLATED_MASK[64] = {0x202020202020202ULL, 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, - 0x1414141414141414ULL, 0x2828282828282828ULL, 0x5050505050505050ULL, - 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL, 0x202020202020202ULL, - 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, - 0x2828282828282828ULL, 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, - 0x4040404040404040ULL, 0x202020202020202ULL, 0x505050505050505ULL, - 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, 0x2828282828282828ULL, - 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL, - 0x202020202020202ULL, 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, - 0x1414141414141414ULL, 0x2828282828282828ULL, 0x5050505050505050ULL, - 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL, 0x202020202020202ULL, - 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, - 0x2828282828282828ULL, 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, - 0x4040404040404040ULL, 0x202020202020202ULL, 0x505050505050505ULL, - 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, 0x2828282828282828ULL, - 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, - 0x4040404040404040ULL, 0x202020202020202ULL, 0x505050505050505ULL, - 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, 0x2828282828282828ULL, - 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL, - 0x202020202020202ULL, 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, - 0x1414141414141414ULL, 0x2828282828282828ULL, 0x5050505050505050ULL, - 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL}; + static constexpr u64 PAWN_ISOLATED_MASK[64] = + {0x202020202020202ULL, 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, + 0x1414141414141414ULL, 0x2828282828282828ULL, 0x5050505050505050ULL, + 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL, 0x202020202020202ULL, + 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, + 0x2828282828282828ULL, 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, + 0x4040404040404040ULL, 0x202020202020202ULL, 0x505050505050505ULL, + 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, 0x2828282828282828ULL, + 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL, + 0x202020202020202ULL, 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, + 0x1414141414141414ULL, 0x2828282828282828ULL, 0x5050505050505050ULL, + 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL, 0x202020202020202ULL, + 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, + 0x2828282828282828ULL, 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, + 0x4040404040404040ULL, 0x202020202020202ULL, 0x505050505050505ULL, + 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, 0x2828282828282828ULL, + 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, + 0x4040404040404040ULL, 0x202020202020202ULL, 0x505050505050505ULL, + 0xA0A0A0A0A0A0A0AULL, 0x1414141414141414ULL, 0x2828282828282828ULL, + 0x5050505050505050ULL, 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL, + 0x202020202020202ULL, 0x505050505050505ULL, 0xA0A0A0A0A0A0A0AULL, + 0x1414141414141414ULL, 0x2828282828282828ULL, 0x5050505050505050ULL, + 0xA0A0A0A0A0A0A0A0ULL, 0x4040404040404040ULL + }; - static constexpr char DISTANCE_KING_OPENING[64] = {-8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -12, -12, -12, -12, -8, -8, -8, -8, -12, -16, -16, -12, - -8, -8, -8, -8, -12, -16, -16, -12, -8, -8, -8, -8, -12, -12, - -12, -12, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8}; + static constexpr char DISTANCE_KING_OPENING[64] = + {-8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -12, -12, -12, -12, -8, -8, -8, -8, -12, -16, -16, -12, + -8, -8, -8, -8, -12, -16, -16, -12, -8, -8, -8, -8, -12, -12, + -12, -12, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8 + }; - static constexpr char DISTANCE_KING_ENDING[64] = {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 16, 16, 16, 16, 12, 12, 12, 12, 16, 20, 20, 16, 12, 12, - 12, 12, 16, 20, 20, 16, 12, 12, 12, 12, 16, 16, 16, 16, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}; + static constexpr char DISTANCE_KING_ENDING[64] = + {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 16, 16, 16, 16, 12, 12, 12, 12, 16, 20, 20, 16, 12, 12, + 12, 12, 16, 20, 20, 16, 12, 12, 12, 12, 16, 16, 16, 16, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 + }; static constexpr u64 LINK_ROOKS[64][64] = { - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2ULL, 0x6ULL, 0xeULL, 0x1eULL, 0x3eULL, 0x7eULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x100ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10100ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x101010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101010100ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010101010100ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4ULL, 0xcULL, 0x1cULL, 0x3cULL, 0x7cULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20200ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020200ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20202020200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020202020200ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0x2ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8ULL, 0x18ULL, 0x38ULL, 0x78ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x40400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040400ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040400ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4040404040400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0x6ULL, 0x4ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10ULL, 0x30ULL, 0x70ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8080800ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080800ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080800ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808080800ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xeULL, 0xcULL, 0x8ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20ULL, 0x60ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x1010101000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010101000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101010101000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0x1eULL, 0x1cULL, 0x18ULL, 0x10ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x40ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x2000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x202020202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x20202020202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0x3eULL, 0x3cULL, 0x38ULL, 0x30ULL, 0x20ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x40404000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040404000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040404000ULL, 0xffffffffffffffffULL}, - {0x7eULL, 0x7cULL, 0x78ULL, 0x70ULL, 0x60ULL, 0x40ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x80808000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080808000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080808000ULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200ULL, 0x600ULL, 0xe00ULL, 0x1e00ULL, 0x3e00ULL, 0x7e00ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x10101010000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010101010000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400ULL, 0xc00ULL, 0x1c00ULL, 0x3c00ULL, - 0x7c00ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202020000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x2020202020000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800ULL, 0x1800ULL, 0x3800ULL, 0x7800ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4040000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404040000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x600ULL, 0x400ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000ULL, 0x3000ULL, 0x7000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x808080000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808080000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xe00ULL, 0xc00ULL, - 0x800ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000ULL, 0x6000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x100000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10100000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010100000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x101010100000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x10101010100000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1e00ULL, - 0x1c00ULL, 0x1800ULL, 0x1000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x4000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x200000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20200000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020200000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020200000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20202020200000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x3e00ULL, - 0x3c00ULL, 0x3800ULL, 0x3000ULL, 0x2000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40400000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4040400000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040400000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040400000ULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x7e00ULL, - 0x7c00ULL, 0x7800ULL, 0x7000ULL, 0x6000ULL, 0x4000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8080800000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080800000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080800000ULL}, - {0x100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20000ULL, 0x60000ULL, 0xe0000ULL, 0x1e0000ULL, 0x3e0000ULL, 0x7e0000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x1010101000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0x200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000ULL, 0xc0000ULL, 0x1c0000ULL, 0x3c0000ULL, 0x7c0000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x2000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020202000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000ULL, 0x180000ULL, 0x380000ULL, 0x780000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x404000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x60000ULL, 0x40000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x100000ULL, 0x300000ULL, 0x700000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x80808000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xe0000ULL, 0xc0000ULL, 0x80000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200000ULL, 0x600000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x10101010000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x2000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1e0000ULL, 0x1c0000ULL, 0x180000ULL, - 0x100000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202020000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x3e0000ULL, 0x3c0000ULL, 0x380000ULL, - 0x300000ULL, 0x200000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4040000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040000000ULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x7e0000ULL, 0x7c0000ULL, 0x780000ULL, - 0x700000ULL, 0x600000ULL, 0x400000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8080000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080000000ULL}, - {0x10100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000ULL, - 0x6000000ULL, 0xe000000ULL, 0x1e000000ULL, 0x3e000000ULL, 0x7e000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x100000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10100000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x1010100000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0x20200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4000000ULL, 0xc000000ULL, 0x1c000000ULL, 0x3c000000ULL, 0x7c000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x200000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20200000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020200000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x40000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8000000ULL, 0x18000000ULL, 0x38000000ULL, 0x78000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x400000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40400000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040400000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x6000000ULL, 0x4000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000000ULL, 0x30000000ULL, 0x70000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8080800000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x100000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xe000000ULL, 0xc000000ULL, 0x8000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000ULL, 0x60000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x10101000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1e000000ULL, 0x1c000000ULL, 0x18000000ULL, 0x10000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x400000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x3e000000ULL, 0x3c000000ULL, 0x38000000ULL, 0x30000000ULL, - 0x20000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404000000000ULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x7e000000ULL, 0x7c000000ULL, 0x78000000ULL, 0x70000000ULL, - 0x60000000ULL, 0x40000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x808000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x80808000000000ULL}, - {0x1010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200000000ULL, 0x600000000ULL, - 0xe00000000ULL, 0x1e00000000ULL, 0x3e00000000ULL, 0x7e00000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0x2020200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400000000ULL, - 0xc00000000ULL, 0x1c00000000ULL, 0x3c00000000ULL, 0x7c00000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4040000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x200000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x800000000ULL, 0x1800000000ULL, 0x3800000000ULL, 0x7800000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x40000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080800ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x600000000ULL, 0x400000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x1000000000ULL, 0x3000000000ULL, 0x7000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8080000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10100000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xe00000000ULL, 0xc00000000ULL, 0x800000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000000ULL, 0x6000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x100000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10100000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20200000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x1e00000000ULL, 0x1c00000000ULL, 0x1800000000ULL, 0x1000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20200000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x40400000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x3e00000000ULL, 0x3c00000000ULL, 0x3800000000ULL, 0x3000000000ULL, 0x2000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x400000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x40400000000000ULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x80000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x7e00000000ULL, 0x7c00000000ULL, 0x7800000000ULL, 0x7000000000ULL, 0x6000000000ULL, - 0x4000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x800000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x80800000000000ULL}, - {0x101010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x100000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000000ULL, 0x60000000000ULL, 0xe0000000000ULL, - 0x1e0000000000ULL, 0x3e0000000000ULL, 0x7e0000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0x202020200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000000ULL, 0xc0000000000ULL, - 0x1c0000000000ULL, 0x3c0000000000ULL, 0x7c0000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x404040000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000000000ULL, 0x180000000000ULL, - 0x380000000000ULL, 0x780000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080800ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x808000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x60000000000ULL, - 0x40000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x100000000000ULL, - 0x300000000000ULL, 0x700000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010101000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010100000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x1000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xe0000000000ULL, - 0xc0000000000ULL, 0x80000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x200000000000ULL, 0x600000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x10000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x2020202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020200000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1e0000000000ULL, - 0x1c0000000000ULL, 0x180000000000ULL, 0x100000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x400000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4040400000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x3e0000000000ULL, - 0x3c0000000000ULL, 0x380000000000ULL, 0x300000000000ULL, 0x200000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x40000000000000ULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080800000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8080000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x7e0000000000ULL, - 0x7c0000000000ULL, 0x780000000000ULL, 0x700000000000ULL, 0x600000000000ULL, 0x400000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x80000000000000ULL}, - {0x10101010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101010000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x10100000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x2000000000000ULL, 0x6000000000000ULL, 0xe000000000000ULL, 0x1e000000000000ULL, - 0x3e000000000000ULL, 0x7e000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0x20202020200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202020000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20200000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000000000ULL, 0xc000000000000ULL, 0x1c000000000000ULL, - 0x3c000000000000ULL, 0x7c000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x40404040000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40400000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000000000ULL, 0x18000000000000ULL, 0x38000000000000ULL, - 0x78000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080800ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x80808000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x6000000000000ULL, 0x4000000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000000000000ULL, 0x30000000000000ULL, - 0x70000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010101000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010100000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x101000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x100000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xe000000000000ULL, 0xc000000000000ULL, - 0x8000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000000000ULL, - 0x60000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x202020202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020200000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x200000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1e000000000000ULL, 0x1c000000000000ULL, - 0x18000000000000ULL, 0x10000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x40000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040404000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x404040400000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x3e000000000000ULL, 0x3c000000000000ULL, - 0x38000000000000ULL, 0x30000000000000ULL, 0x20000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080808000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080800000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x808080000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x7e000000000000ULL, 0x7c000000000000ULL, - 0x78000000000000ULL, 0x70000000000000ULL, 0x60000000000000ULL, 0x40000000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL}, - {0x1010101010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010101010000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010101000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x1010100000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x200000000000000ULL, 0x600000000000000ULL, 0xe00000000000000ULL, 0x1e00000000000000ULL, 0x3e00000000000000ULL, - 0x7e00000000000000ULL}, - {0xffffffffffffffffULL, 0x2020202020200ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020202020000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020202000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020200000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x2020000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x400000000000000ULL, 0xc00000000000000ULL, 0x1c00000000000000ULL, - 0x3c00000000000000ULL, 0x7c00000000000000ULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404040400ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4040404040000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040400000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x4000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200000000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800000000000000ULL, 0x1800000000000000ULL, - 0x3800000000000000ULL, 0x7800000000000000ULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808080800ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808080000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x8080808000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080800000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x600000000000000ULL, 0x400000000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000000000000000ULL, - 0x3000000000000000ULL, 0x7000000000000000ULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x10101010101000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x10101010100000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x10101010000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x10101000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x10100000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x10000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xe00000000000000ULL, 0xc00000000000000ULL, 0x800000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x2000000000000000ULL, 0x6000000000000000ULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20202020202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20202020200000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20202020000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20202000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20200000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0x20000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x1e00000000000000ULL, 0x1c00000000000000ULL, 0x1800000000000000ULL, 0x1000000000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000000000000ULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040404000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040400000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40400000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000000000ULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x3e00000000000000ULL, 0x3c00000000000000ULL, 0x3800000000000000ULL, 0x3000000000000000ULL, - 0x2000000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080808000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080800000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000000000000ULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, - 0x7e00000000000000ULL, 0x7c00000000000000ULL, 0x7800000000000000ULL, 0x7000000000000000ULL, - 0x6000000000000000ULL, 0x4000000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL} + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2ULL, 0x6ULL, 0xeULL, + 0x1eULL, 0x3eULL, 0x7eULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x100ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x10100ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010100ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x101010100ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10101010100ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1010101010100ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4ULL, 0xcULL, 0x1cULL, 0x3cULL, 0x7cULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20200ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2020200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020200ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20202020200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020202020200ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0x2ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8ULL, 0x18ULL, 0x38ULL, 0x78ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40400ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x404040400ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040404040400ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0x6ULL, 0x4ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10ULL, 0x30ULL, 0x70ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x808080800ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808080800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808080800ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0xeULL, 0xcULL, 0x8ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20ULL, 0x60ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x101000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1010101000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x101010101000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x10101010101000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0x1eULL, 0x1cULL, 0x18ULL, 0x10ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x202000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x20202000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020202000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x202020202000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x20202020202000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0x3eULL, 0x3cULL, 0x38ULL, 0x30ULL, 0x20ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40404000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040404000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x404040404000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040404000ULL, + 0xffffffffffffffffULL}, + {0x7eULL, 0x7cULL, 0x78ULL, 0x70ULL, 0x60ULL, 0x40ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x8000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x80808000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080808000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x808080808000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080808000ULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200ULL, 0x600ULL, + 0xe00ULL, 0x1e00ULL, 0x3e00ULL, 0x7e00ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1010000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10101010000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1010101010000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x400ULL, 0xc00ULL, 0x1c00ULL, 0x3c00ULL, + 0x7c00ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x202020000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202020000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020202020000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x200ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x800ULL, 0x1800ULL, 0x3800ULL, 0x7800ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404040000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40404040000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404040000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x600ULL, 0x400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1000ULL, 0x3000ULL, 0x7000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x808080000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x80808080000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x8080808080000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xe00ULL, 0xc00ULL, + 0x800ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000ULL, 0x6000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x100000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x10100000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010100000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x101010100000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x10101010100000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1e00ULL, + 0x1c00ULL, 0x1800ULL, 0x1000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x200000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20200000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2020200000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202020200000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20202020200000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x3e00ULL, + 0x3c00ULL, 0x3800ULL, 0x3000ULL, 0x2000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x400000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40400000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040400000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404040400000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40404040400000ULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x7e00ULL, + 0x7c00ULL, 0x7800ULL, 0x7000ULL, 0x6000ULL, 0x4000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x800000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080800000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x808080800000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808080800000ULL}, + {0x100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000ULL, 0x60000ULL, 0xe0000ULL, 0x1e0000ULL, + 0x3e0000ULL, 0x7e0000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x101000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1010101000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0x200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000ULL, 0xc0000ULL, + 0x1c0000ULL, 0x3c0000ULL, 0x7c0000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x202000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x20202000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020202000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x20000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000ULL, 0x180000ULL, + 0x380000ULL, 0x780000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40404000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4040404000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x60000ULL, 0x40000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x100000ULL, 0x300000ULL, 0x700000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x8000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x80808000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080808000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xe0000ULL, 0xc0000ULL, 0x80000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x200000ULL, 0x600000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1010000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10101010000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1e0000ULL, 0x1c0000ULL, 0x180000ULL, + 0x100000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x400000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x202020000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202020000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x3e0000ULL, 0x3c0000ULL, 0x380000ULL, + 0x300000ULL, 0x200000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404040000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40404040000000ULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x8000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x7e0000ULL, 0x7c0000ULL, 0x780000ULL, + 0x700000ULL, 0x600000ULL, 0x400000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x808080000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808080000000ULL}, + {0x10100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x10000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000000ULL, + 0x6000000ULL, 0xe000000ULL, 0x1e000000ULL, 0x3e000000ULL, 0x7e000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x100000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10100000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1010100000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0x20200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4000000ULL, 0xc000000ULL, 0x1c000000ULL, + 0x3c000000ULL, 0x7c000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x200000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20200000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2020200000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8000000ULL, 0x18000000ULL, 0x38000000ULL, + 0x78000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x400000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40400000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4040400000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x6000000ULL, 0x4000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000000ULL, + 0x30000000ULL, 0x70000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x800000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080800000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x101000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x100000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xe000000ULL, 0xc000000ULL, + 0x8000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000ULL, + 0x60000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10101000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x202000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x200000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1e000000ULL, + 0x1c000000ULL, 0x18000000ULL, 0x10000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x202000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20202000000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x400000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x3e000000ULL, + 0x3c000000ULL, 0x38000000ULL, 0x30000000ULL, + 0x20000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40404000000000ULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x808000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x7e000000ULL, + 0x7c000000ULL, 0x78000000ULL, 0x70000000ULL, + 0x60000000ULL, 0x40000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x808000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x80808000000000ULL}, + {0x1010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1010000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x200000000ULL, 0x600000000ULL, + 0xe00000000ULL, 0x1e00000000ULL, 0x3e00000000ULL, 0x7e00000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x10000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0x2020200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x400000000ULL, + 0xc00000000ULL, 0x1c00000000ULL, 0x3c00000000ULL, 0x7c00000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2020000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x200000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x800000000ULL, 0x1800000000ULL, 0x3800000000ULL, 0x7800000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x8080800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x600000000ULL, 0x400000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1000000000ULL, 0x3000000000ULL, 0x7000000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10101000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x10100000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xe00000000ULL, 0xc00000000ULL, 0x800000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000000ULL, + 0x6000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x100000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10100000000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20202000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20200000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x20000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1e00000000ULL, 0x1c00000000ULL, 0x1800000000ULL, + 0x1000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x200000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x20200000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40400000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x3e00000000ULL, 0x3c00000000ULL, 0x3800000000ULL, + 0x3000000000ULL, 0x2000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x400000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x40400000000000ULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80800000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x80000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x7e00000000ULL, 0x7c00000000ULL, 0x7800000000ULL, + 0x7000000000ULL, 0x6000000000ULL, + 0x4000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x800000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x80800000000000ULL}, + {0x101010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x101010000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x100000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000000ULL, + 0x60000000000ULL, 0xe0000000000ULL, + 0x1e0000000000ULL, 0x3e0000000000ULL, 0x7e0000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0x202020200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x202020000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x202000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40000000000ULL, 0xc0000000000ULL, + 0x1c0000000000ULL, 0x3c0000000000ULL, 0x7c0000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404040000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x400000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80000000000ULL, 0x180000000000ULL, + 0x380000000000ULL, 0x780000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x808080800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x808000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x800000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x60000000000ULL, + 0x40000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x100000000000ULL, + 0x300000000000ULL, 0x700000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1010101000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1010100000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xe0000000000ULL, + 0xc0000000000ULL, 0x80000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x200000000000ULL, 0x600000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020202000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020200000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2020000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1e0000000000ULL, + 0x1c0000000000ULL, 0x180000000000ULL, 0x100000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x400000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20000000000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040400000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x3e0000000000ULL, + 0x3c0000000000ULL, 0x380000000000ULL, 0x300000000000ULL, + 0x200000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x40000000000000ULL, 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x8080808000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080800000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x7e0000000000ULL, + 0x7c0000000000ULL, 0x780000000000ULL, 0x700000000000ULL, + 0x600000000000ULL, 0x400000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x80000000000000ULL}, + {0x10101010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x10101010000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x10101000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10100000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x10000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000000000000ULL, 0x6000000000000ULL, + 0xe000000000000ULL, 0x1e000000000000ULL, + 0x3e000000000000ULL, 0x7e000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0x20202020200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20202020000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x20202000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x20200000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4000000000000ULL, + 0xc000000000000ULL, 0x1c000000000000ULL, + 0x3c000000000000ULL, 0x7c000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40404040000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x40404000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40400000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000000000ULL, + 0x18000000000000ULL, 0x38000000000000ULL, + 0x78000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808080800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x80808080000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x80808000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x80800000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x6000000000000ULL, 0x4000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x10000000000000ULL, 0x30000000000000ULL, + 0x70000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x101010101000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x101010100000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x101010000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x101000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x100000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xe000000000000ULL, 0xc000000000000ULL, + 0x8000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000000000000ULL, + 0x60000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x202020202000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x202020200000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x202020000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x202000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x200000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1e000000000000ULL, 0x1c000000000000ULL, + 0x18000000000000ULL, 0x10000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x40000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x404040404000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404040400000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x404040000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x404000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x400000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x3e000000000000ULL, 0x3c000000000000ULL, + 0x38000000000000ULL, 0x30000000000000ULL, 0x20000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x808080808000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x808080800000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x808080000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x808000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x800000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x7e000000000000ULL, 0x7c000000000000ULL, + 0x78000000000000ULL, 0x70000000000000ULL, 0x60000000000000ULL, + 0x40000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0x1010101010100ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1010101010000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x1010101000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1010100000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x1010000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x200000000000000ULL, 0x600000000000000ULL, 0xe00000000000000ULL, + 0x1e00000000000000ULL, 0x3e00000000000000ULL, + 0x7e00000000000000ULL}, + {0xffffffffffffffffULL, 0x2020202020200ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020202020000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x2020202000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x2020200000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2020000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x400000000000000ULL, 0xc00000000000000ULL, + 0x1c00000000000000ULL, + 0x3c00000000000000ULL, 0x7c00000000000000ULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040404040400ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040404040000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4040404000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4040400000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x4040000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x4000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x200000000000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x800000000000000ULL, + 0x1800000000000000ULL, + 0x3800000000000000ULL, 0x7800000000000000ULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x8080808080800ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8080808080000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080808000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x8080800000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x8080000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x8000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x600000000000000ULL, + 0x400000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x1000000000000000ULL, + 0x3000000000000000ULL, 0x7000000000000000ULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x10101010101000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x10101010100000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x10101010000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x10101000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x10100000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x10000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xe00000000000000ULL, 0xc00000000000000ULL, 0x800000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x2000000000000000ULL, 0x6000000000000000ULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20202020202000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20202020200000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20202020000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20202000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20200000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0x20000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x1e00000000000000ULL, 0x1c00000000000000ULL, 0x1800000000000000ULL, + 0x1000000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x4000000000000000ULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040404000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040400000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404040000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40404000000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40400000000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0x40000000000000ULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x3e00000000000000ULL, 0x3c00000000000000ULL, 0x3800000000000000ULL, + 0x3000000000000000ULL, + 0x2000000000000000ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL}, + {0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808080808000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808080800000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808080000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80808000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80800000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0x80000000000000ULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL, + 0x7e00000000000000ULL, 0x7c00000000000000ULL, 0x7800000000000000ULL, + 0x7000000000000000ULL, + 0x6000000000000000ULL, 0x4000000000000000ULL, 0xffffffffffffffffULL, + 0xffffffffffffffffULL} }; } diff --git a/src/GenMoves.cpp b/src/GenMoves.cpp index 6648328d..ae6144e8 100644 --- a/src/GenMoves.cpp +++ b/src/GenMoves.cpp @@ -18,15 +18,13 @@ #include "GenMoves.h" -bool GenMoves::forceCheck = false; - GenMoves::GenMoves() : perftMode(false), listId(-1) { currentPly = 0; - gen_list = (_TmoveP *) calloc(MAX_PLY, sizeof(_TmoveP)); - _assert(gen_list) + genList = (_TmoveP *) calloc(MAX_PLY, sizeof(_TmoveP)); + _assert(genList) for (int i = 0; i < MAX_PLY; i++) { - gen_list[i].moveList = (_Tmove *) calloc(MAX_MOVE, sizeof(_Tmove)); - _assert(gen_list[i].moveList) + genList[i].moveList = (_Tmove *) calloc(MAX_MOVE, sizeof(_Tmove)); + _assert(genList[i].moveList) } repetitionMap = (u64 *) malloc(sizeof(u64) * MAX_REP_COUNT); _assert(repetitionMap) @@ -34,12 +32,12 @@ GenMoves::GenMoves() : perftMode(false), listId(-1) { init(); } -void GenMoves::generateMoves(const int side, const u64 allpieces) { +void GenMoves::generateMoves(const uchar side, const u64 allpieces) { ASSERT_RANGE(side, 0, 1) side ? generateMoves(allpieces) : generateMoves(allpieces); } -bool GenMoves::generateCaptures(const int side, const u64 enemies, const u64 friends) { +bool GenMoves::generateCaptures(const uchar side, const u64 enemies, const u64 friends) { ASSERT_RANGE(side, 0, 1) return side ? generateCaptures(enemies, friends) : generateCaptures(enemies, friends); } @@ -53,37 +51,54 @@ void GenMoves::clearHeuristic() { memset(killer, 0, sizeof(killer)); } -_Tmove *GenMoves::getNextMove(_TmoveP *list, const int depth, const Hash::_ThashData *hash, const int first) { - BENCH(times->start("getNextMove")) +_Tmove *GenMoves::getNextMoveQ(_TmoveP *list, const int first) { + BENCH_AUTO_CLOSE("getNextMoveQ") + int bestId = -1; + int bestScore = -INT_MAX; + + for (int i = first; i < list->size; i++) { + const auto move = list->moveList[i]; + ASSERT_RANGE(move.pieceFrom, 0, 11) + ASSERT_RANGE(move.to, 0, 63) + ASSERT_RANGE(move.from, 0, 63) + + const int score = CAPTURES[move.pieceFrom][move.capturedPiece]; + if (score > bestScore) { + bestScore = score; + bestId = i; + } + } + if (bestId == -1) { + return nullptr; + } + return swap(list, first, bestId); +} +_Tmove *GenMoves::getNextMove(_TmoveP *list, const int depth, const u64 &hash, const int first) { + BENCH_AUTO_CLOSE("getNextMove") int bestId = -1; int bestScore = -1; for (int i = first; i < list->size; i++) { - auto mos = list->moveList[i]; + const auto move = list->moveList[i]; int score = 0; - if (mos.s.type & 0x3) { - if (mos.s.capturedPiece == KING_BLACK + (mos.s.side ^ 1)) { - score = _INFINITE; - } else { - ASSERT_RANGE(mos.s.pieceFrom, 0, 11); - ASSERT_RANGE(mos.s.to, 0, 63); - ASSERT_RANGE(mos.s.from, 0, 63); + if (move.type & 0x3) { - if (hash && (hash->dataS.from == mos.s.from && hash->dataS.to == mos.s.to)) { - score = _INFINITE / 2; - } - score += historyHeuristic[mos.s.from][mos.s.to]; - score += (PIECES_VALUE[mos.s.capturedPiece] > PIECES_VALUE[mos.s.pieceFrom]) ? - (PIECES_VALUE[mos.s.capturedPiece] - PIECES_VALUE[mos.s.pieceFrom]) * 2 - : PIECES_VALUE[mos.s.capturedPiece]; - if (isKillerMate(mos.s.from, mos.s.to, depth)) score += 100; - else if (isKiller(0, mos.s.from, mos.s.to, depth)) score += 90; - else if (isKiller(1, mos.s.from, mos.s.to, depth)) score += 80; + ASSERT_RANGE(move.pieceFrom, 0, 11) + ASSERT_RANGE(move.to, 0, 63) + ASSERT_RANGE(move.from, 0, 63) + if (GET_FROM(hash) == move.from && GET_TO(hash) == move.to) { + return swap(list, first, i); } - } else if (mos.s.type & 0xc) { //castle - ASSERT(chessboard[RIGHT_CASTLE_IDX]); + score += historyHeuristic[move.from][move.to]; + score += CAPTURES[move.pieceFrom][move.capturedPiece]; + + if (isKiller(0, move.from, move.to, depth)) score += 50; + else if (isKiller(1, move.from, move.to, depth)) score += 30; + + } else if (move.type & 0xc) { //castle + assert(rightCastle); score = 100; } if (score > bestScore) { @@ -92,103 +107,96 @@ _Tmove *GenMoves::getNextMove(_TmoveP *list, const int depth, const Hash::_Thash } } if (bestId == -1) { - BENCH(times->stop("getNextMove")) return nullptr; } -// swap(list->moveList[first], list->moveList[bestId]); - const auto tmp = list->moveList[first].u; - list->moveList[first].u = list->moveList[bestId].u; - list->moveList[bestId].u = tmp; - - BENCH(times->stop("getNextMove")) - return &list->moveList[first]; + return swap(list, first, bestId); } GenMoves::~GenMoves() { for (int i = 0; i < MAX_PLY; i++) { - free(gen_list[i].moveList); + free(genList[i].moveList); } - free(gen_list); + free(genList); free(repetitionMap); } -void GenMoves::performCastle(const int side, const uchar type) { +void GenMoves::performCastle(const uchar side, const uchar type) { ASSERT_RANGE(side, 0, 1) if (side == WHITE) { - ASSERT(chessboard[KING_WHITE] & POW2[startPosWhiteKing]) + assert(chessboard[KING_WHITE] & POW2(startPosWhiteKing)); if (type & KING_SIDE_CASTLE_MOVE_MASK) { if (startPosWhiteKing != G1) { updateZobristKey(KING_WHITE, startPosWhiteKing); updateZobristKey(KING_WHITE, G1); - chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2_1) & NOTPOW2[startPosWhiteKing]; + chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2_1) & NOTPOW2(startPosWhiteKing); } if (startPosWhiteRookKingSide != F1) { updateZobristKey(ROOK_WHITE, F1); updateZobristKey(ROOK_WHITE, startPosWhiteRookKingSide); - chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2_2) & NOTPOW2[startPosWhiteRookKingSide]; + chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2_2) & NOTPOW2(startPosWhiteRookKingSide); } - ASSERT(chessboard[KING_WHITE] & POW2[G1]) - ASSERT(chessboard[ROOK_WHITE] & POW2[F1]) + assert(chessboard[KING_WHITE] & POW2(G1)); + assert(chessboard[ROOK_WHITE] & POW2(F1)); } else { if (startPosWhiteKing != C1) { - chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2_5) & NOTPOW2[startPosWhiteKing]; + chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2_5) & NOTPOW2(startPosWhiteKing); updateZobristKey(KING_WHITE, C1); updateZobristKey(KING_WHITE, startPosWhiteKing); } if (startPosWhiteRookQueenSide != D1) { - chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2_4) & NOTPOW2[startPosWhiteRookQueenSide]; + chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2_4) & NOTPOW2(startPosWhiteRookQueenSide); updateZobristKey(ROOK_WHITE, D1); updateZobristKey(ROOK_WHITE, startPosWhiteRookQueenSide); } - ASSERT(chessboard[KING_WHITE] & POW2[C1]) - ASSERT(chessboard[ROOK_WHITE] & POW2[D1]) + assert(chessboard[KING_WHITE] & POW2(C1)); + assert(chessboard[ROOK_WHITE] & POW2(D1)); } } else { - ASSERT(chessboard[KING_BLACK] & POW2[startPosBlackKing]) + assert(chessboard[KING_BLACK] & POW2(startPosBlackKing)); if (type & KING_SIDE_CASTLE_MOVE_MASK) { if (startPosBlackKing != G8) { - chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2_57) & NOTPOW2[startPosBlackKing]; + chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2_57) & NOTPOW2(startPosBlackKing); updateZobristKey(KING_BLACK, G8); updateZobristKey(KING_BLACK, startPosBlackKing); } if (startPosBlackRookKingSide != F8) { - chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2_58) & NOTPOW2[startPosBlackRookKingSide]; + chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2_58) & NOTPOW2(startPosBlackRookKingSide); updateZobristKey(ROOK_BLACK, F8); updateZobristKey(ROOK_BLACK, startPosBlackRookKingSide); } - ASSERT(chessboard[KING_BLACK] & POW2[G8]) - ASSERT(chessboard[ROOK_BLACK] & POW2[F8]) + assert(chessboard[KING_BLACK] & POW2(G8)); + assert(chessboard[ROOK_BLACK] & POW2(F8)); } else { if (startPosBlackKing != C8) { - chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2_61) & NOTPOW2[startPosBlackKing]; + chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2_61) & NOTPOW2(startPosBlackKing); updateZobristKey(KING_BLACK, C8); updateZobristKey(KING_BLACK, startPosBlackKing); } if (startPosBlackRookQueenSide != D8) { - chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2_60) & NOTPOW2[startPosBlackRookQueenSide]; + chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2_60) & NOTPOW2(startPosBlackRookQueenSide); updateZobristKey(ROOK_BLACK, D8); updateZobristKey(ROOK_BLACK, startPosBlackRookQueenSide); } - ASSERT(chessboard[KING_BLACK] & POW2[C8]) - ASSERT(chessboard[ROOK_BLACK] & POW2[D8]) + assert(chessboard[KING_BLACK] & POW2(C8)); + assert(chessboard[ROOK_BLACK] & POW2(D8)); } } - ASSERT(chessboard[KING_WHITE]) - ASSERT(chessboard[KING_BLACK]) + assert(chessboard[KING_WHITE]); + assert(chessboard[KING_BLACK]); } bool GenMoves::allowCastleBlackQueen(const u64 allpieces) const { - return POW2_59 & chessboard[KING_BLACK] && chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_BLACK_MASK && + return POW2_59 & chessboard[KING_BLACK] && rightCastle & RIGHT_QUEEN_CASTLE_BLACK_MASK && !(allpieces & 0x7000000000000000ULL) && chessboard[ROOK_BLACK] & POW2_63 && !board::isAttacked(59, allpieces, chessboard) && !board::isAttacked(60, allpieces, chessboard) && @@ -197,14 +205,14 @@ bool GenMoves::allowCastleBlackQueen(const u64 allpieces) const { bool GenMoves::allowCastleWhiteQueen(const u64 allpieces) const { return POW2_3 & chessboard[KING_WHITE] && !(allpieces & 0x70ULL) && - chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_WHITE_MASK && chessboard[ROOK_WHITE] & POW2_7 && + rightCastle & RIGHT_QUEEN_CASTLE_WHITE_MASK && chessboard[ROOK_WHITE] & POW2_7 && !board::isAttacked(3, allpieces, chessboard) && !board::isAttacked(4, allpieces, chessboard) && !board::isAttacked(5, allpieces, chessboard); } bool GenMoves::allowCastleBlackKing(const u64 allpieces) const { - return POW2_59 & chessboard[KING_BLACK] && chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_BLACK_MASK && + return POW2_59 & chessboard[KING_BLACK] && rightCastle & RIGHT_KING_CASTLE_BLACK_MASK && !(allpieces & 0x600000000000000ULL) && chessboard[ROOK_BLACK] & POW2_56 && !board::isAttacked(57, allpieces, chessboard) && !board::isAttacked(58, allpieces, chessboard) && @@ -213,197 +221,183 @@ bool GenMoves::allowCastleBlackKing(const u64 allpieces) const { bool GenMoves::allowCastleWhiteKing(const u64 allpieces) const { return POW2_3 & chessboard[KING_WHITE] && !(allpieces & 0x6ULL) && - chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_WHITE_MASK && chessboard[ROOK_WHITE] & POW2_0 && + rightCastle & RIGHT_KING_CASTLE_WHITE_MASK && chessboard[ROOK_WHITE] & POW2_0 && !board::isAttacked(1, allpieces, chessboard) && !board::isAttacked(2, allpieces, chessboard) && !board::isAttacked(3, allpieces, chessboard); } -void GenMoves::unPerformCastle(const int side, const uchar type) { +void GenMoves::unPerformCastle(const uchar side, const uchar type) { ASSERT_RANGE(side, 0, 1) - ASSERT(chessboard[KING_WHITE]) - ASSERT(chessboard[KING_BLACK]) + assert(chessboard[KING_WHITE]); + assert(chessboard[KING_BLACK]); if (side == WHITE) { if (type & KING_SIDE_CASTLE_MOVE_MASK) { - ASSERT(board::getPieceAt(side, POW2_1, chessboard) == KING_WHITE) - ASSERT(board::getPieceAt(side, POW2_2, chessboard) == ROOK_WHITE) + assert(board::getPieceAt(side, POW2_1, chessboard) == KING_WHITE); + assert(board::getPieceAt(side, POW2_2, chessboard) == ROOK_WHITE); if (startPosWhiteKing != 1) - chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2[startPosWhiteKing]) & NOTPOW2_1; + chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2(startPosWhiteKing)) & NOTPOW2_1; if (startPosWhiteRookKingSide != F1) - chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2[startPosWhiteRookKingSide]) & NOTPOW2_2; + chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2(startPosWhiteRookKingSide)) & NOTPOW2_2; } else { - ASSERT(board::getPieceAt(side, POW2_5, chessboard) == KING_WHITE) - ASSERT(board::getPieceAt(side, POW2_4, chessboard) == ROOK_WHITE) + assert(board::getPieceAt(side, POW2_5, chessboard) == KING_WHITE); + assert(board::getPieceAt(side, POW2_4, chessboard) == ROOK_WHITE); if (startPosWhiteKing != C1) - chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2[startPosWhiteKing]) & NOTPOW2_5; + chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2(startPosWhiteKing)) & NOTPOW2_5; if (startPosWhiteRookQueenSide != D1) - chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2[startPosWhiteRookQueenSide]) & NOTPOW2_4; + chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2(startPosWhiteRookQueenSide)) & NOTPOW2_4; } - - ASSERT(chessboard[KING_WHITE] & POW2[startPosWhiteKing]) + assert(chessboard[KING_WHITE] & POW2(startPosWhiteKing)); } else { - if (type & KING_SIDE_CASTLE_MOVE_MASK) { - ASSERT(board::getPieceAt(side, POW2_57, chessboard) == KING_BLACK) - ASSERT(board::getPieceAt(side, POW2_58, chessboard) == ROOK_BLACK) + assert(board::getPieceAt(side, POW2_57, chessboard) == KING_BLACK); + assert(board::getPieceAt(side, POW2_58, chessboard) == ROOK_BLACK); if (startPosBlackKing != G8) - chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2[startPosBlackKing]) & NOTPOW2_57; + chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2(startPosBlackKing)) & NOTPOW2_57; if (startPosBlackRookKingSide != F8) - chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2[startPosBlackRookKingSide]) & NOTPOW2_58; + chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2(startPosBlackRookKingSide)) & NOTPOW2_58; } else { - ASSERT(board::getPieceAt(side, POW2_61, chessboard) == KING_BLACK) - ASSERT(board::getPieceAt(side, POW2_60, chessboard) == ROOK_BLACK) + assert(board::getPieceAt(side, POW2_61, chessboard) == KING_BLACK); + assert(board::getPieceAt(side, POW2_60, chessboard) == ROOK_BLACK); if (startPosBlackKing != C8) - chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2[startPosBlackKing]) & NOTPOW2_61; + chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2(startPosBlackKing)) & NOTPOW2_61; if (startPosBlackRookQueenSide != D8) - chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2[startPosBlackRookQueenSide]) & NOTPOW2_60; + chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2(startPosBlackRookQueenSide)) & NOTPOW2_60; } - ASSERT(chessboard[KING_BLACK] & POW2[startPosBlackKing]) + assert(chessboard[KING_BLACK] & POW2(startPosBlackKing)); } } -void GenMoves::takeback(_Tmove *move, const u64 oldkey, bool rep) { - if (rep) { - popStackMove(); - } +void GenMoves::takeback(const _Tmove *move, const u64 oldkey, const uchar oldEnpassant, const bool rep) { + BENCH_AUTO_CLOSE("takeback") + if (rep) popStackMove(); chessboard[ZOBRISTKEY_IDX] = oldkey; - chessboard[ENPASSANT_IDX] = NO_ENPASSANT; - int pieceFrom, posTo, posFrom, movecapture; - chessboard[RIGHT_CASTLE_IDX] = move->s.type & 0xf0; - if ((move->s.type & 0x3) == STANDARD_MOVE_MASK || (move->s.type & 0x3) == ENPASSANT_MOVE_MASK) { - posTo = move->s.to; - posFrom = move->s.from; - movecapture = move->s.capturedPiece; - ASSERT_RANGE(posFrom, 0, 63) - ASSERT_RANGE(posTo, 0, 63) - pieceFrom = move->s.pieceFrom; - chessboard[pieceFrom] = (chessboard[pieceFrom] & NOTPOW2[posTo]) | POW2[posFrom]; - if (movecapture != SQUARE_EMPTY) { - if (((move->s.type & 0x3) != ENPASSANT_MOVE_MASK)) { - chessboard[movecapture] |= POW2[posTo]; - } else { - ASSERT(movecapture == (move->s.side ^ 1)) - if (move->s.side) { - chessboard[movecapture] |= POW2[posTo - 8]; - } else { - chessboard[movecapture] |= POW2[posTo + 8]; - } + enPassant = oldEnpassant; + rightCastle = move->type & 0xf0; + + if (move->type & 0x1) { + ASSERT_RANGE(move->from, 0, 63) + ASSERT_RANGE(move->to, 0, 63) + chessboard[move->pieceFrom] = (chessboard[move->pieceFrom] & NOTPOW2(move->to)) | POW2(move->from); + if (move->capturedPiece != SQUARE_EMPTY) { + if (((move->type & 0x3) != ENPASSANT_MOVE_MASK)) chessboard[move->capturedPiece] |= POW2(move->to); + else { + assert(move->capturedPiece == X(move->side)); + if (move->side) chessboard[move->capturedPiece] |= POW2(move->to - 8); + else chessboard[move->capturedPiece] |= POW2(move->to + 8); } } - } else if ((move->s.type & 0x3) == PROMOTION_MOVE_MASK) { - posTo = move->s.to; - posFrom = move->s.from; - movecapture = move->s.capturedPiece; - ASSERT(posTo >= 0 && move->s.side >= 0 && move->s.promotionPiece >= 0) - chessboard[(uchar) move->s.side] |= POW2[posFrom]; - chessboard[(uchar) move->s.promotionPiece] &= NOTPOW2[posTo]; - if (movecapture != SQUARE_EMPTY) { - chessboard[movecapture] |= POW2[posTo]; - } - } else if (move->s.type & 0xc) { //castle - unPerformCastle(move->s.side, move->s.type); + } else if ((move->type & 0x3) == PROMOTION_MOVE_MASK) { + assert(move->to >= 0 && move->side >= 0 && move->promotionPiece >= 0); + chessboard[move->side] |= POW2(move->from); + chessboard[move->promotionPiece] &= NOTPOW2(move->to); + if (move->capturedPiece != SQUARE_EMPTY) chessboard[move->capturedPiece] |= POW2(move->to); + } else { + //castle + assert(move->type & 0xc); + unPerformCastle(move->side, move->type); } } bool GenMoves::makemove(const _Tmove *move, const bool rep, const bool checkInCheck) { - ASSERT(move) - ASSERT(bitCount(chessboard[KING_WHITE]) == 1 && bitCount(chessboard[KING_BLACK]) == 1) - int pieceFrom = SQUARE_EMPTY, posTo, posFrom, movecapture = SQUARE_EMPTY; - const uchar rightCastleOld = chessboard[RIGHT_CASTLE_IDX]; - - if (!(move->s.type & 0xc)) { //no castle - posTo = move->s.to; - posFrom = move->s.from; - movecapture = move->s.capturedPiece; - ASSERT_RANGE(posFrom, 0, 63) - ASSERT_RANGE(posTo, 0, 63) - pieceFrom = move->s.pieceFrom; - if ((move->s.type & 0x3) == PROMOTION_MOVE_MASK) { - chessboard[pieceFrom] &= NOTPOW2[posFrom]; - updateZobristKey(pieceFrom, posFrom); - ASSERT(move->s.promotionPiece >= 0) - chessboard[(uchar) move->s.promotionPiece] |= POW2[posTo]; - updateZobristKey((uchar) move->s.promotionPiece, posTo); + BENCH_AUTO_CLOSE("makemove") + assert(move); + assert(bitCount(chessboard[KING_WHITE]) == 1 && bitCount(chessboard[KING_BLACK]) == 1); + const uchar rightCastleOld = rightCastle; + if (!(move->type & 0xc)) { //no castle + ASSERT_RANGE(move->from, 0, 63) + ASSERT_RANGE(move->to, 0, 63) + if ((move->type & 0x3) == PROMOTION_MOVE_MASK) { + chessboard[move->pieceFrom] &= NOTPOW2(move->from); + updateZobristKey(move->pieceFrom, move->from); + assert(move->promotionPiece >= 0); + chessboard[move->promotionPiece] |= POW2(move->to); + updateZobristKey(move->promotionPiece, move->to); } else { - chessboard[pieceFrom] = (chessboard[pieceFrom] | POW2[posTo]) & NOTPOW2[posFrom]; - updateZobristKey(pieceFrom, posFrom); - updateZobristKey(pieceFrom, posTo); + chessboard[move->pieceFrom] = (chessboard[move->pieceFrom] | POW2(move->to)) & NOTPOW2(move->from); + updateZobristKey(move->pieceFrom, move->from); + updateZobristKey(move->pieceFrom, move->to); } - if (movecapture != SQUARE_EMPTY) { - if ((move->s.type & 0x3) != ENPASSANT_MOVE_MASK) { - chessboard[movecapture] &= NOTPOW2[posTo]; - updateZobristKey(movecapture, posTo); + if (move->capturedPiece != SQUARE_EMPTY) { + if ((move->type & 0x3) != ENPASSANT_MOVE_MASK) { + assert(chessboard[move->capturedPiece] & POW2(move->to)); + chessboard[move->capturedPiece] &= NOTPOW2(move->to); + updateZobristKey(move->capturedPiece, move->to); } else { //en passant - ASSERT(movecapture == (move->s.side ^ 1)) - if (move->s.side) { - chessboard[movecapture] &= NOTPOW2[posTo - 8]; - updateZobristKey(movecapture, posTo - 8); - } else { - chessboard[movecapture] &= NOTPOW2[posTo + 8]; - updateZobristKey(movecapture, posTo + 8); - } + assert(move->capturedPiece == X(move->side)); + const int y = move->side ? -8 : 8; + chessboard[move->capturedPiece] &= NOTPOW2(move->to + y); + updateZobristKey(move->capturedPiece, move->to + y); } } //lost castle right - switch (pieceFrom) { - case KING_WHITE: - chessboard[RIGHT_CASTLE_IDX] &= 0xcf; - break; - case KING_BLACK: - chessboard[RIGHT_CASTLE_IDX] &= 0x3f; - break; - case ROOK_WHITE: - if (posFrom == startPosWhiteRookKingSide) - chessboard[RIGHT_CASTLE_IDX] &= 0xef; - else if (posFrom == startPosWhiteRookQueenSide) - chessboard[RIGHT_CASTLE_IDX] &= 0xdf; - break; - case ROOK_BLACK: - if (posFrom == startPosBlackRookKingSide) - chessboard[RIGHT_CASTLE_IDX] &= 0xbf; - else if (posFrom == startPosBlackRookQueenSide) - chessboard[RIGHT_CASTLE_IDX] &= 0x7f; - break; - //en passant + if (POW2(move->to) & 0xff000000000000ffULL) { + if (move->to == startPosWhiteRookKingSide) rightCastle &= 0xef; + else if (move->to == startPosWhiteRookQueenSide) rightCastle &= 0xdf; + else if (move->to == startPosBlackRookKingSide) rightCastle &= 0xbf; + else if (move->to == startPosBlackRookQueenSide) rightCastle &= 0x7f; + } + if (move->pieceFrom & 0xb) { + switch (move->pieceFrom) { + case KING_WHITE: + rightCastle &= 0xcf; + break; + case KING_BLACK: + rightCastle &= 0x3f; + break; + case ROOK_WHITE: + if (move->from == startPosWhiteRookKingSide) + rightCastle &= 0xef; + else if (move->from == startPosWhiteRookQueenSide) + rightCastle &= 0xdf; + break; + case ROOK_BLACK: + if (move->from == startPosBlackRookKingSide) + rightCastle &= 0xbf; + else if (move->from == startPosBlackRookQueenSide) + rightCastle &= 0x7f; + break; + default:; + } + //en passant + } + switch (move->pieceFrom) { case PAWN_WHITE: - if ((RANK_2 & POW2[posFrom]) && (RANK_3 & POW2[posTo])) { - chessboard[ENPASSANT_IDX] = posTo; - updateZobristKey(13, chessboard[ENPASSANT_IDX]); + if ((RANK_2 & POW2(move->from)) && (RANK_3 & POW2(move->to))) { + enPassant = move->to; + updateZobristKey(ENPASSANT_IDX, enPassant); } break; case PAWN_BLACK: - if ((RANK_7 & POW2[posFrom]) && (RANK_5 & POW2[posTo])) { - chessboard[ENPASSANT_IDX] = posTo; - updateZobristKey(13, chessboard[ENPASSANT_IDX]); + if ((RANK_7 & POW2(move->from)) && (RANK_5 & POW2(move->to))) { + enPassant = move->to; + updateZobristKey(ENPASSANT_IDX, enPassant); } break; default:; } - } else { //castle - performCastle(move->s.side, move->s.type); - if (move->s.side == WHITE) { - chessboard[RIGHT_CASTLE_IDX] &= 0xcf; - } else { - chessboard[RIGHT_CASTLE_IDX] &= 0x3f; - } + } else { //castle + performCastle(move->side, move->type); + if (move->side == WHITE) rightCastle &= 0xcf; else rightCastle &= 0x3f; } - for (u64 x2 = rightCastleOld ^chessboard[RIGHT_CASTLE_IDX]; x2; RESET_LSB(x2)) { + for (u64 x2 = rightCastleOld ^rightCastle; x2; RESET_LSB(x2)) { const int position = BITScanForward(x2); updateZobristKey(14, position); } if (rep) { - if (movecapture != SQUARE_EMPTY || pieceFrom == WHITE || pieceFrom == BLACK || move->s.type & 0xc) { + if (move->capturedPiece != SQUARE_EMPTY || move->pieceFrom == WHITE || move->pieceFrom == BLACK || + move->type & 0xc) { pushStackMove(0); } pushStackMove(chessboard[ZOBRISTKEY_IDX]); } if ((forceCheck || (checkInCheck && !perftMode)) && - ((move->s.side == WHITE && board::inCheck1(chessboard)) || - (move->s.side == BLACK && board::inCheck1(chessboard)))) { + ((move->side == WHITE && board::inCheck1(chessboard)) || + (move->side == BLACK && board::inCheck1(chessboard)))) { return false; } return true; @@ -411,12 +405,7 @@ bool GenMoves::makemove(const _Tmove *move, const bool rep, const bool checkInCh void GenMoves::init() { numMoves = numMovesq = listId = 0; -#ifdef DEBUG_MODE - nCutFp = nCutRazor = 0; - betaEfficiency = 0.0; - nCutAB = 0; - nNullMoveCut = 0; -#endif + DEBUG(nCutFp = nCutRazor = nCutAB = nNullMoveCut = nCutBadCaputure = 0) } u64 GenMoves::getTotMoves() const { @@ -427,18 +416,8 @@ void GenMoves::setRepetitionMapCount(const int i) { repetitionMapCount = i; } -int GenMoves::loadFen(string fen) { - int side = ChessBoard::loadFen(fen); - if (side == 2) { - fatal("Bad FEN position format ", fen) - std::_Exit(1); - } - - return side; -} - -int GenMoves::getMoveFromSan(const string fenStr, _Tmove *move) { - chessboard[ENPASSANT_IDX] = NO_ENPASSANT; +int GenMoves::getMoveFromSan(const string &fenStr, _Tmove *move) { + enPassant = NO_ENPASSANT; memset(move, 0, sizeof(_Tmove)); movesCount++; if ( @@ -455,22 +434,22 @@ int GenMoves::getMoveFromSan(const string fenStr, _Tmove *move) { ) ) { if (MATCH_QUEENSIDE.find(fenStr) != string::npos) { - move->s.type = QUEEN_SIDE_CASTLE_MOVE_MASK; - move->s.from = QUEEN_SIDE_CASTLE_MOVE_MASK; + move->type = QUEEN_SIDE_CASTLE_MOVE_MASK; + move->from = QUEEN_SIDE_CASTLE_MOVE_MASK; } else { - move->s.from = KING_SIDE_CASTLE_MOVE_MASK; - move->s.type = KING_SIDE_CASTLE_MOVE_MASK; + move->from = KING_SIDE_CASTLE_MOVE_MASK; + move->type = KING_SIDE_CASTLE_MOVE_MASK; } if (fenStr.find("1") != string::npos) { - move->s.side = WHITE; + move->side = WHITE; } else if (fenStr.find("8") != string::npos) { - move->s.side = BLACK; + move->side = BLACK; } else { _assert(0) } - move->s.from = -1; - move->s.capturedPiece = SQUARE_EMPTY; - return move->s.side; + move->from = -1; + move->capturedPiece = SQUARE_EMPTY; + return move->side; } int from = -1; int to = -1; @@ -495,59 +474,59 @@ int GenMoves::getMoveFromSan(const string fenStr, _Tmove *move) { _assert(0) } int pieceFrom; - if ((pieceFrom = board::getPieceAt(POW2[from], chessboard)) != 12) { - move->s.side = WHITE; - } else if ((pieceFrom = board::getPieceAt(POW2[from], chessboard)) != 12) { - move->s.side = BLACK; + if ((pieceFrom = board::getPieceAt(POW2(from), chessboard)) != 12) { + move->side = WHITE; + } else if ((pieceFrom = board::getPieceAt(POW2(from), chessboard)) != 12) { + move->side = BLACK; } else { display(); cout << "fenStr: >" << fenStr << "< from: " << from << endl; _assert(0) } - move->s.from = from; - move->s.to = to; + move->from = from; + move->to = to; if (fenStr.length() == 4) { - move->s.type = STANDARD_MOVE_MASK; + move->type = STANDARD_MOVE_MASK; if (pieceFrom == PAWN_WHITE || pieceFrom == PAWN_BLACK) { if (FILE_AT[from] != FILE_AT[to] && - (move->s.side ^ 1 ? board::getPieceAt(POW2[to], chessboard) : board::getPieceAt(POW2[to], - chessboard)) == + (X(move->side) ? board::getPieceAt(POW2(to), chessboard) : board::getPieceAt(POW2(to), + chessboard)) == SQUARE_EMPTY) { - move->s.type = ENPASSANT_MOVE_MASK; + move->type = ENPASSANT_MOVE_MASK; } } } else if (fenStr.length() == 5) { - move->s.type = PROMOTION_MOVE_MASK; - if (move->s.side == WHITE) { - move->s.promotionPiece = INV_FEN[toupper(fenStr.at(4))]; + move->type = PROMOTION_MOVE_MASK; + if (move->side == WHITE) { + move->promotionPiece = INV_FEN[toupper(fenStr.at(4))]; } else { - move->s.promotionPiece = INV_FEN[(uchar) fenStr.at(4)]; + move->promotionPiece = INV_FEN[(uchar) fenStr.at(4)]; } - ASSERT(move->s.promotionPiece != -1) + assert(move->promotionPiece != NO_PROMOTION); } - if (move->s.side == WHITE) { - move->s.capturedPiece = board::getPieceAt(POW2[move->s.to], chessboard); - move->s.pieceFrom = board::getPieceAt(POW2[move->s.from], chessboard); + if (move->side == WHITE) { + move->capturedPiece = board::getPieceAt(POW2(move->to), chessboard); + move->pieceFrom = board::getPieceAt(POW2(move->from), chessboard); } else { - move->s.capturedPiece = board::getPieceAt(POW2[move->s.to], chessboard); - move->s.pieceFrom = board::getPieceAt(POW2[move->s.from], chessboard); + move->capturedPiece = board::getPieceAt(POW2(move->to), chessboard); + move->pieceFrom = board::getPieceAt(POW2(move->from), chessboard); } - if (move->s.type == ENPASSANT_MOVE_MASK) { - move->s.capturedPiece = !move->s.side; + if (move->type == ENPASSANT_MOVE_MASK) { + move->capturedPiece = !move->side; } - return move->s.side; + return move->side; } void GenMoves::writeRandomFen(const vector pieces) { while (1) { - memset(chessboard, 0, sizeof(_Tchessboard)); - chessboard[ENPASSANT_IDX] = NO_ENPASSANT; - chessboard[SIDETOMOVE_IDX] = rand() % 2; - chessboard[KING_BLACK] = POW2[rand() % 64]; - chessboard[KING_WHITE] = POW2[rand() % 64]; + clearChessboard(); + sideToMove = rand() % 2; + rightCastle = 0; + chessboard[KING_BLACK] = POW2(rand() % 64); + chessboard[KING_WHITE] = POW2(rand() % 64); u64 check = chessboard[KING_BLACK] | chessboard[KING_WHITE]; for (unsigned long i = 0; i < pieces.size(); i++) { - chessboard[pieces[i]] |= POW2[rand() % 64]; + chessboard[pieces[i]] |= POW2(rand() % 64); check |= chessboard[pieces[i]]; } @@ -573,7 +552,7 @@ bool GenMoves::generatePuzzle(const string type) { vector pieces; for (unsigned k = 0; k < TOT; k++) { - int side = WHITE; + uchar side = WHITE; pieces.clear(); _assert(toupper(type.at(0)) == 'K') for (unsigned i = 1; i < type.size(); i++) { diff --git a/src/GenMoves.h b/src/GenMoves.h index ec632224..925c0692 100644 --- a/src/GenMoves.h +++ b/src/GenMoves.h @@ -20,11 +20,11 @@ #include "ChessBoard.h" #include "Hash.h" +#include "util/bench/Bench.h" #include "util/Bitboard.h" #include #include "namespaces/board.h" - class GenMoves : public ChessBoard { public: @@ -36,30 +36,35 @@ class GenMoves : public ChessBoard { void setPerft(const bool b); - bool generateCaptures(const int side, u64, u64); + bool generateCaptures(const uchar side, const u64, const u64); - void generateMoves(const int side, const u64); + void generateMoves(const uchar side, const u64); - template + template void generateMoves(const u64 allpieces) { - ASSERT_RANGE(side, 0, 1); - ASSERT(chessboard[KING_BLACK]); - ASSERT(chessboard[KING_WHITE]); + ASSERT_RANGE(side, 0, 1) + assert(chessboard[KING_BLACK]); + assert(chessboard[KING_WHITE]); tryAllCastle(allpieces); performDiagShift(BISHOP_BLACK + side, allpieces); performRankFileShift(ROOK_BLACK + side, allpieces); performRankFileShift(QUEEN_BLACK + side, allpieces); performDiagShift(QUEEN_BLACK + side, allpieces); performPawnShift(~allpieces); - performKnightShiftCapture(KNIGHT_BLACK + side, ~allpieces, false); + performKnightShiftCapture(~allpieces, false); performKingShiftCapture(~allpieces, false); } - template + static bool isAttacked(const _Tmove &move, const _Tchessboard &chessboard, const u64 allpieces) { + assert(allpieces == (board::getBitmap(chessboard) | board::getBitmap(chessboard))); + return board::isAttacked(move.side, move.to, allpieces, chessboard); + } + + template bool generateCaptures(const u64 enemies, const u64 friends) { - ASSERT_RANGE(side, 0, 1); - ASSERT(chessboard[KING_BLACK]); - ASSERT(chessboard[KING_WHITE]); + ASSERT_RANGE(side, 0, 1) + assert(chessboard[KING_BLACK]); + assert(chessboard[KING_WHITE]); const u64 allpieces = enemies | friends; if (perftMode) { @@ -68,27 +73,13 @@ class GenMoves : public ChessBoard { isInCheck = board::isAttacked(kingPosition, allpieces, chessboard); } - if (performPawnCapture(enemies)) { - return true; - } - if (performKingShiftCapture(enemies, true)) { - return true; - } - if (performKnightShiftCapture(KNIGHT_BLACK + side, enemies, true)) { - return true; - } - if (performDiagCapture(BISHOP_BLACK + side, enemies, allpieces)) { - return true; - } - if (performRankFileCapture(ROOK_BLACK + side, enemies, allpieces)) { - return true; - } - if (performRankFileCapture(QUEEN_BLACK + side, enemies, allpieces)) { - return true; - } - if (performDiagCapture(QUEEN_BLACK + side, enemies, allpieces)) { - return true; - } + if (performPawnCapture(enemies)) return true; + if (performKingShiftCapture(enemies, true)) return true; + if (performKnightShiftCapture(enemies, true)) return true; + if (performDiagCapture(BISHOP_BLACK + side, enemies, allpieces)) return true; + if (performRankFileCapture(ROOK_BLACK + side, enemies, allpieces)) return true; + if (performRankFileCapture(QUEEN_BLACK + side, enemies, allpieces)) return true; + if (performDiagCapture(QUEEN_BLACK + side, enemies, allpieces)) return true; return false; } @@ -96,114 +87,100 @@ class GenMoves : public ChessBoard { return forceCheck; } - void setForceCheck(bool b) const { + void setForceCheck(const bool b) { forceCheck = b; } - int getMoveFromSan(const string fenStr, _Tmove *move); + int getMoveFromSan(const string &fenStr, _Tmove *move); void init(); - int loadFen(string fen = ""); - - inline u64 getDiagCapture(const int position, const u64 allpieces, const u64 enemies) const { - ASSERT_RANGE(position, 0, 63); - return Bitboard::getDiagonalAntiDiagonal(position, allpieces) & enemies; - } - - void takeback(_Tmove *move, const u64 oldkey, bool rep); + void takeback(const _Tmove *move, const u64 oldkey, const uchar oldEnpassant, const bool rep); void setRepetitionMapCount(const int i); - template + template bool performKingShiftCapture(const u64 enemies, const bool isCapture) { - BENCH(times->start("kingShiftCapture")) + BENCH_AUTO_CLOSE("kingShiftCapture") ASSERT_RANGE(side, 0, 1) const int pos = BITScanForward(chessboard[KING_BLACK + side]); - ASSERT(pos != -1) + assert(pos != -1); for (u64 x1 = enemies & NEAR_MASK1[pos]; x1; RESET_LSB(x1)) { - BENCH(times->subProcess("kingShiftCapture", "pushmove")) + BENCH_SUBPROCESS("kingShiftCapture", "pushmove") if (pushmove(pos, BITScanForward(x1), NO_PROMOTION, KING_BLACK + side, isCapture)) { - BENCH(times->stop("kingShiftCapture")) return true; } } - BENCH(times->stop("kingShiftCapture")) return false; } - - template - bool performKnightShiftCapture(const int piece, const u64 enemies, const bool isCapture) { - BENCH(times->start("knightShiftCapture")) - ASSERT_RANGE(piece, 0, 11) + template + bool performKnightShiftCapture(const u64 enemies, const bool isCapture) { + BENCH_AUTO_CLOSE("knightShiftCapture") ASSERT_RANGE(side, 0, 1) - for (u64 x = chessboard[piece]; x; RESET_LSB(x)) { + for (u64 x = chessboard[KNIGHT_BLACK + side]; x; RESET_LSB(x)) { const int pos = BITScanForward(x); for (u64 x1 = enemies & KNIGHT_MASK[pos]; x1; RESET_LSB(x1)) { - BENCH(times->subProcess("knightShiftCapture", "pushmove")) - if (pushmove(pos, BITScanForward(x1), NO_PROMOTION, piece, isCapture)) { - BENCH(times->stop("knightShiftCapture")) + BENCH_SUBPROCESS("knightShiftCapture", "pushmove") + if (pushmove(pos, BITScanForward(x1), NO_PROMOTION, KNIGHT_BLACK + side, + isCapture + )) return true; - } + } } - BENCH(times->stop("knightShiftCapture")) return false; } - template - bool performDiagCapture(const int piece, const u64 enemies, const u64 allpieces) { - BENCH(times->start("diagCapture")) + template + bool performDiagCapture(const uchar piece, const u64 enemies, const u64 allpieces) { + BENCH_AUTO_CLOSE("diagCapture") ASSERT_RANGE(piece, 0, 11) ASSERT_RANGE(side, 0, 1) for (u64 x2 = chessboard[piece]; x2; RESET_LSB(x2)) { const int position = BITScanForward(x2); - u64 diag = getDiagonalAntiDiagonal(position, allpieces) & enemies; + u64 diag = Bitboard::getDiagonalAntiDiagonal(position, allpieces) & enemies; for (; diag; RESET_LSB(diag)) { - if (pushmove(position, BITScanForward(diag), NO_PROMOTION, piece, true)) { - BENCH(times->stop("diagCapture")) + BENCH_SUBPROCESS("diagCapture", "pushmove") + if (pushmove(position, BITScanForward(diag), NO_PROMOTION, piece, true)) return true; - } + } } - BENCH(times->stop("diagCapture")) return false; } u64 getTotMoves() const; - template - bool performRankFileCapture(const int piece, const u64 enemies, const u64 allpieces) { - BENCH(times->start("rankFileCapture")) + template + bool performRankFileCapture(const uchar piece, const u64 enemies, const u64 allpieces) { + BENCH_AUTO_CLOSE("rankFileCapture") ASSERT_RANGE(piece, 0, 11) ASSERT_RANGE(side, 0, 1) for (u64 x2 = chessboard[piece]; x2; RESET_LSB(x2)) { const int position = BITScanForward(x2); - u64 rankFile = getRankFile(position, allpieces) & enemies; + u64 rankFile = Bitboard::getRankFile(position, allpieces) & enemies; for (; rankFile; RESET_LSB(rankFile)) { - if (pushmove(position, BITScanForward(rankFile), NO_PROMOTION, piece, true)) { - BENCH(times->stop("rankFileCapture")) + BENCH_SUBPROCESS("rankFileCapture", "pushmove") + if (pushmove(position, BITScanForward(rankFile), NO_PROMOTION, piece, true)) return true; - } + } } - BENCH(times->stop("rankFileCapture")) return false; } - template + template bool performPawnCapture(const u64 enemies) { - BENCH(times->start("pawnCapture")) + BENCH_AUTO_CLOSE("pawnCapture") if (!chessboard[side]) { - if (chessboard[ENPASSANT_IDX] != NO_ENPASSANT) { - updateZobristKey(13, chessboard[ENPASSANT_IDX]); + if (enPassant != NO_ENPASSANT) { + updateZobristKey(ENPASSANT_IDX, enPassant); } - chessboard[ENPASSANT_IDX] = NO_ENPASSANT; - BENCH(times->stop("pawnCapture")) + enPassant = NO_ENPASSANT; return false; } constexpr int sh = side ? -7 : 7; @@ -211,35 +188,24 @@ class GenMoves : public ChessBoard { u64 x = shiftForward(chessboard[side]) & enemies; for (; x; RESET_LSB(x)) { const int o = BITScanForward(x); - if ((side && o > 55) || (!side && o < 8)) {//PROMOTION - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh, o, QUEEN_BLACK + side, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; //queen - } - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh, o, KNIGHT_BLACK + side, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; //knight - } + if ((side && o > A7) || (!side && o < H2)) {//PROMOTION + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh, o, QUEEN_BLACK + side, side, true)) return true; + + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh, o, KNIGHT_BLACK + side, side, true)) return true; + if (perftMode) { - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh, o, ROOK_BLACK + side, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; //rock - } - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh, o, BISHOP_BLACK + side, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; //bishop - } + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh, o, ROOK_BLACK + side, side, true)) return true; + + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh, o, BISHOP_BLACK + side, side, true)) return true; } } else { - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh, o, NO_PROMOTION, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; - } + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh, o, NO_PROMOTION, side, true)) return true; + } } constexpr int sh2 = side ? -9 : 9; @@ -247,78 +213,68 @@ class GenMoves : public ChessBoard { for (; x; RESET_LSB(x)) { const int o = BITScanForward(x); - if ((side && o > 55) || (!side && o < 8)) { //PROMOTION - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh2, o, QUEEN_BLACK + side, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; //queen - } - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh2, o, KNIGHT_BLACK + side, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; //knight - } + if ((side && o > A7) || (!side && o < H2)) { //PROMOTION + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh2, o, QUEEN_BLACK + side, side, true)) return true; + + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh2, o, KNIGHT_BLACK + side, side, true)) return true; + if (perftMode) { - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh2, o, BISHOP_BLACK + side, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; //bishop - } - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh2, o, ROOK_BLACK + side, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; //rock - } + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh2, o, BISHOP_BLACK + side, side, true)) return true; + + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh2, o, ROOK_BLACK + side, side, true)) return true; } } else { - BENCH(times->subProcess("pawnCapture", "pushmove")) - if (pushmove(o + sh2, o, NO_PROMOTION, side, true)) { - BENCH(times->stop("pawnCapture")) - return true; - } + BENCH_SUBPROCESS("pawnCapture", "pushmove") + if (pushmove(o + sh2, o, NO_PROMOTION, side, true)) return true; + } } - //ENPASSANT - if (chessboard[ENPASSANT_IDX] != NO_ENPASSANT) { - x = ENPASSANT_MASK[side ^ 1][chessboard[ENPASSANT_IDX]] & chessboard[side]; + //enPassant + if (enPassant != NO_ENPASSANT) { + x = ENPASSANT_MASK[X(side)][enPassant] & chessboard[side]; for (; x; RESET_LSB(x)) { const int o = BITScanForward(x); - BENCH(times->subProcess("pawnCapture", "pushmove")) - pushmove(o, - (side ? chessboard[ENPASSANT_IDX] + 8 : chessboard[ENPASSANT_IDX] - - 8), - NO_PROMOTION, side, true); + BENCH_SUBPROCESS("pawnCapture", "pushmove") + pushmove(o, (side ? enPassant + 8 : enPassant - 8), NO_PROMOTION, side, + true); } - updateZobristKey(13, chessboard[ENPASSANT_IDX]); - chessboard[ENPASSANT_IDX] = NO_ENPASSANT; + updateZobristKey(ENPASSANT_IDX, enPassant); + enPassant = NO_ENPASSANT; } - BENCH(times->stop("pawnCapture")) return false; } - template + template void performPawnShift(const u64 xallpieces) { u64 x = chessboard[side]; - checkJumpPawn(x, xallpieces); - BENCH(times->start("pawnShift")) + performJumpPawn(x, xallpieces); + BENCH_AUTO_CLOSE("pawnShift") constexpr int sh = side ? -8 : 8; x = side ? x << 8 : x >> 8; x &= xallpieces; - BENCH(times->stop("pawnShift")) for (; x; RESET_LSB(x)) { const int o = BITScanForward(x); - ASSERT(board::getPieceAt(POW2[o + sh], chessboard) != SQUARE_EMPTY); - ASSERT(board::board::getBitmap(side, chessboard) & POW2[o + sh]); + assert(board::getPieceAt(POW2(o + sh), chessboard) != SQUARE_EMPTY); + assert(board::getBitmap(side, chessboard) & POW2(o + sh)); if (o > A7 || o < H2) { + BENCH_SUBPROCESS("pawnShift", "pushmove") pushmove(o + sh, o, QUEEN_BLACK + side, side, false); + BENCH_SUBPROCESS("pawnShift", "pushmove") pushmove(o + sh, o, KNIGHT_BLACK + side, side, false); if (perftMode) { + BENCH_SUBPROCESS("pawnShift", "pushmove") pushmove(o + sh, o, BISHOP_BLACK + side, side, false); + BENCH_SUBPROCESS("pawnShift", "pushmove") pushmove(o + sh, o, ROOK_BLACK + side, side, false); } } else { + BENCH_SUBPROCESS("pawnShift", "pushmove") pushmove(o + sh, o, NO_PROMOTION, side, false); } } @@ -326,54 +282,52 @@ class GenMoves : public ChessBoard { void clearHeuristic(); - template - void performDiagShift(const int piece, const u64 allpieces) { - BENCH(times->start("diagShift")) + template + void performDiagShift(const uchar piece, const u64 allpieces) { + BENCH_AUTO_CLOSE("diagShift") ASSERT_RANGE(piece, 0, 11) ASSERT_RANGE(side, 0, 1) for (u64 x2 = chessboard[piece]; x2; RESET_LSB(x2)) { const int position = BITScanForward(x2); - u64 diag = getDiagonalAntiDiagonal(position, allpieces) & ~allpieces; + u64 diag = Bitboard::getDiagonalAntiDiagonal(position, allpieces) & ~allpieces; for (; diag; RESET_LSB(diag)) { - BENCH(times->subProcess("diagShift", "pushmove")) + BENCH_SUBPROCESS("diagShift", "pushmove") pushmove(position, BITScanForward(diag), NO_PROMOTION, piece, false); } } - BENCH(times->stop("diagShift")) } - template - void performRankFileShift(const int piece, const u64 allpieces) { - BENCH(times->start("rankFileShift")) + template + void performRankFileShift(const uchar piece, const u64 allpieces) { + BENCH_AUTO_CLOSE("rankFileShift") ASSERT_RANGE(piece, 0, 11) ASSERT_RANGE(side, 0, 1) for (u64 x2 = chessboard[piece]; x2; RESET_LSB(x2)) { const int position = BITScanForward(x2); - u64 rankFile = getRankFile(position, allpieces) & ~allpieces; + u64 rankFile = Bitboard::getRankFile(position, allpieces) & ~allpieces; for (; rankFile; RESET_LSB(rankFile)) { - BENCH(times->subProcess("rankFileShift", "pushmove")) + BENCH_SUBPROCESS("rankFileShift", "pushmove") pushmove(position, BITScanForward(rankFile), NO_PROMOTION, piece, false); } } - BENCH(times->stop("rankFileShift")) } bool makemove(const _Tmove *move, const bool rep, const bool); void incListId() { listId++; - ASSERT(listId >= 0); - ASSERT(listId < MAX_PLY); + assert(listId >= 0); + assert(listId < MAX_PLY); } void decListId() { - ASSERT(listId > -1); - gen_list[listId--].size = 0; + assert(listId > -1); + genList[listId--].size = 0; } int getListSize() const { - return gen_list[listId].size; + return genList[listId].size; } void pushStackMove() { @@ -381,32 +335,34 @@ class GenMoves : public ChessBoard { } void resetList() { - gen_list[listId].size = 0; + genList[listId].size = 0; } bool generatePuzzle(const string type); void incHistoryHeuristic(const int from, const int to, const int value) { - ASSERT_RANGE(from, 0, 63); - ASSERT_RANGE(to, 0, 63); - ASSERT(historyHeuristic[from][to] <= historyHeuristic[from][to] + value); + ASSERT_RANGE(from, 0, 63) + ASSERT_RANGE(to, 0, 63) + assert(historyHeuristic[from][to] <= historyHeuristic[from][to] + value); historyHeuristic[from][to] += value; } #ifdef DEBUG_MODE - unsigned nCutAB, nNullMoveCut, nCutFp, nCutRazor; - double betaEfficiency; + unsigned nCutAB, nNullMoveCut, nCutFp, nCutRazor, nCutBadCaputure; + double betaEfficiency = 0.0; + unsigned betaEfficiencyCount = 0; #endif - - static constexpr int NO_PROMOTION = -1; protected: - + typedef struct { + _Tmove *moveList; + int size; + } _TmoveP; u64 pinned; bool perftMode; int listId; - _TmoveP *gen_list; + _TmoveP *genList; static constexpr u64 RANK_2 = 0xff00ULL; static constexpr u64 RANK_3 = 0xff000000ULL; @@ -425,9 +381,11 @@ class GenMoves : public ChessBoard { u64 numMoves = 0; u64 numMovesq = 0; - _Tmove *getNextMove(decltype(gen_list), const int depth, const Hash::_ThashData *c, const int first); + _Tmove *getNextMoveQ(_TmoveP *list, const int first); + + _Tmove *getNextMove(decltype(genList), const int depth, const u64 &, const int first); - template + template int getMobilityCastle(const u64 allpieces) const { ASSERT_RANGE(side, 0, 1) if (chess960) return 0; @@ -443,28 +401,29 @@ class GenMoves : public ChessBoard { } int historyHeuristic[64][64]; - unsigned short killer[3][MAX_PLY]; + unsigned short killer[2][MAX_PLY]; #ifdef DEBUG_MODE - template - bool inCheckSlow(const int from, const int to, const int pieceFrom, const int pieceTo, const int promotionPiece) { + template + bool + inCheckSlow(const int from, const int to, const uchar pieceFrom, const uchar pieceTo, const uchar promotionPiece) { bool result; switch (type & 0x3) { case STANDARD_MOVE_MASK: { u64 from1, to1 = -1; - ASSERT(pieceFrom != SQUARE_EMPTY); - ASSERT(pieceTo != KING_BLACK); - ASSERT(pieceTo != KING_WHITE); + assert(pieceFrom != SQUARE_EMPTY); + assert(pieceTo != KING_BLACK); + assert(pieceTo != KING_WHITE); from1 = chessboard[pieceFrom]; if (pieceTo != SQUARE_EMPTY) { to1 = chessboard[pieceTo]; - chessboard[pieceTo] &= NOTPOW2[to]; - }; - chessboard[pieceFrom] &= NOTPOW2[from]; - chessboard[pieceFrom] |= POW2[to]; - ASSERT(chessboard[KING_BLACK]); - ASSERT(chessboard[KING_WHITE]); + chessboard[pieceTo] &= NOTPOW2(to); + } + chessboard[pieceFrom] &= NOTPOW2(from); + chessboard[pieceFrom] |= POW2(to); + assert(chessboard[KING_BLACK]); + assert(chessboard[KING_WHITE]); result = board::isAttacked(BITScanForward(chessboard[KING_BLACK + side]), board::getBitmap(chessboard) | @@ -482,11 +441,11 @@ class GenMoves : public ChessBoard { } u64 from1 = chessboard[pieceFrom]; u64 p1 = chessboard[promotionPiece]; - chessboard[pieceFrom] &= NOTPOW2[from]; + chessboard[pieceFrom] &= NOTPOW2(from); if (pieceTo != SQUARE_EMPTY) { - chessboard[pieceTo] &= NOTPOW2[to]; + chessboard[pieceTo] &= NOTPOW2(to); } - chessboard[promotionPiece] = chessboard[promotionPiece] | POW2[to]; + chessboard[promotionPiece] = chessboard[promotionPiece] | POW2(to); result = board::isAttacked(BITScanForward(chessboard[KING_BLACK + side]), board::getBitmap(chessboard) | board::getBitmap(chessboard), chessboard); @@ -498,24 +457,24 @@ class GenMoves : public ChessBoard { break; } case ENPASSANT_MOVE_MASK: { - u64 to1 = chessboard[side ^ 1]; + u64 to1 = chessboard[X(side)]; u64 from1 = chessboard[side]; - chessboard[side] &= NOTPOW2[from]; - chessboard[side] |= POW2[to]; + chessboard[side] &= NOTPOW2(from); + chessboard[side] |= POW2(to); if (side) { - chessboard[side ^ 1] &= NOTPOW2[to - 8]; + chessboard[X(side)] &= NOTPOW2(to - 8); } else { - chessboard[side ^ 1] &= NOTPOW2[to + 8]; + chessboard[X(side)] &= NOTPOW2(to + 8); } result = board::isAttacked(BITScanForward(chessboard[KING_BLACK + side]), board::getBitmap(chessboard) | board::getBitmap(chessboard), chessboard); - chessboard[side ^ 1] = to1; - chessboard[side] = from1;; + chessboard[X(side)] = to1; + chessboard[side] = from1; break; } default: - _assert(0); + _assert(0) } return result; @@ -524,51 +483,48 @@ class GenMoves : public ChessBoard { #endif template - bool inCheck(const int from, const int to, const int pieceFrom, const int pieceTo, int promotionPiece) { - BENCH(times->start("inCheck")) + bool inCheck(const uchar from, const uchar to, const uchar pieceFrom, const uchar pieceTo, uchar promotionPiece) { + BENCH_AUTO_CLOSE("inCheck") #ifdef DEBUG_MODE _Tchessboard a; memcpy(&a, chessboard, sizeof(_Tchessboard)); + ASSERT_RANGE(from, 0, 63) + ASSERT_RANGE(to, 0, 63) + ASSERT_RANGE(side, 0, 1) + ASSERT_RANGE(pieceFrom, 0, 12) + ASSERT_RANGE(pieceTo, 0, 12) + assert(perftMode || forceCheck); + assert(!(type & 0xc)); #endif - ASSERT_RANGE(from, 0, 63); - ASSERT_RANGE(to, 0, 63); - ASSERT_RANGE(side, 0, 1); - ASSERT_RANGE(pieceFrom, 0, 12); - ASSERT_RANGE(pieceTo, 0, 12); - ASSERT(perftMode || forceCheck); - ASSERT(!(type & 0xc)); + if (pieceTo == KING_BLACK || pieceTo == KING_WHITE) return false; if (perftMode) { - if ((KING_BLACK + side) != pieceFrom && !isInCheck) { - if (!(pinned & POW2[from]) || (LINES[from][to] & chessboard[KING_BLACK + side])) { - ASSERT(!(inCheckSlow(from, to, pieceFrom, pieceTo, promotionPiece))); - BENCH(times->stop("inCheck")) + if (!(pinned & POW2(from)) || (LINES[from][to] & chessboard[KING_BLACK + side])) { + assert(!(inCheckSlow(from, to, pieceFrom, pieceTo, promotionPiece))); return false; } else { - ASSERT ((inCheckSlow(from, to, pieceFrom, pieceTo, promotionPiece))); - BENCH(times->stop("inCheck")) + assert((inCheckSlow(from, to, pieceFrom, pieceTo, promotionPiece))); return true; } } - } bool result = 0; switch (type & 0x3) { case STANDARD_MOVE_MASK: { u64 from1, to1 = -1; - ASSERT(pieceFrom != SQUARE_EMPTY); - ASSERT(pieceTo != KING_BLACK); - ASSERT(pieceTo != KING_WHITE); + assert(pieceFrom != SQUARE_EMPTY); + assert(pieceTo != KING_BLACK); + assert(pieceTo != KING_WHITE); from1 = chessboard[pieceFrom]; if (pieceTo != SQUARE_EMPTY) { to1 = chessboard[pieceTo]; - chessboard[pieceTo] &= NOTPOW2[to]; - }; - chessboard[pieceFrom] &= NOTPOW2[from]; - chessboard[pieceFrom] |= POW2[to]; - ASSERT(chessboard[KING_BLACK]); - ASSERT(chessboard[KING_WHITE]); + chessboard[pieceTo] &= NOTPOW2(to); + } + chessboard[pieceFrom] &= NOTPOW2(from); + chessboard[pieceFrom] |= POW2(to); + assert(chessboard[KING_BLACK]); + assert(chessboard[KING_WHITE]); result = board::isAttacked(BITScanForward(chessboard[KING_BLACK + side]), board::getBitmap(chessboard) | @@ -586,11 +542,11 @@ class GenMoves : public ChessBoard { } u64 from1 = chessboard[pieceFrom]; u64 p1 = chessboard[promotionPiece]; - chessboard[pieceFrom] &= NOTPOW2[from]; + chessboard[pieceFrom] &= NOTPOW2(from); if (pieceTo != SQUARE_EMPTY) { - chessboard[pieceTo] &= NOTPOW2[to]; + chessboard[pieceTo] &= NOTPOW2(to); } - chessboard[promotionPiece] = chessboard[promotionPiece] | POW2[to]; + chessboard[promotionPiece] = chessboard[promotionPiece] | POW2(to); result = board::isAttacked(BITScanForward(chessboard[KING_BLACK + side]), board::getBitmap(chessboard) | board::getBitmap(chessboard), chessboard); @@ -602,47 +558,44 @@ class GenMoves : public ChessBoard { break; } case ENPASSANT_MOVE_MASK: { - u64 to1 = chessboard[side ^ 1]; + u64 to1 = chessboard[X(side)]; u64 from1 = chessboard[side]; - chessboard[side] &= NOTPOW2[from]; - chessboard[side] |= POW2[to]; + chessboard[side] &= NOTPOW2(from); + chessboard[side] |= POW2(to); if (side) { - chessboard[side ^ 1] &= NOTPOW2[to - 8]; + chessboard[X(side)] &= NOTPOW2(to - 8); } else { - chessboard[side ^ 1] &= NOTPOW2[to + 8]; + chessboard[X(side)] &= NOTPOW2(to + 8); } result = board::isAttacked(BITScanForward(chessboard[KING_BLACK + side]), board::getBitmap(chessboard) | board::getBitmap(chessboard), chessboard); - chessboard[side ^ 1] = to1; - chessboard[side] = from1;; + chessboard[X(side)] = to1; + chessboard[side] = from1; break; } default: - _assert(0); + _assert(0) } - ASSERT(!memcmp(&a, chessboard, sizeof(_Tchessboard))); - BENCH(times->stop("inCheck")) + assert(!memcmp(&a, chessboard, sizeof(_Tchessboard))); return result; } - void performCastle(const int side, const uchar type); + void performCastle(const uchar side, const uchar type); - void unPerformCastle(const int side, const uchar type); + void unPerformCastle(const uchar side, const uchar type); - template + template void tryAllCastle(const u64 allpieces) { ASSERT_RANGE(side, 0, 1) - BENCH(times->start("castle")) + BENCH_AUTO_CLOSE("castle") if (chess960)tryAllCastle960(allpieces); - else - tryAllCastleStandard(allpieces); - BENCH(times->stop("castle")) + else tryAllCastleStandard(allpieces); } bool allowKingSideBlack(const u64 allpieces) const { - const auto a = board::isCastleRight_BlackKing(chessboard) && + const auto a = board::isCastleRight_BlackKing(rightCastle) && board::isPieceAt(KING_BLACK, startPosBlackKing, chessboard) && board::isPieceAt(ROOK_BLACK, startPosBlackRookKingSide, chessboard) && (!board::isOccupied(G8, allpieces) || startPosBlackKing == G8 || @@ -652,27 +605,27 @@ class GenMoves : public ChessBoard { !(startPosBlackKing == G8 && startPosBlackRookKingSide == F8); if (!a)return a; const u64 path = LINK_SQUARE[startPosBlackKing][G8]; - const u64 rookPath = LINK_SQUARE[startPosBlackRookKingSide][F8] & NOTPOW2[startPosBlackKing]; - const u64 kingPath = path | POW2[G8] | POW2[startPosBlackKing]; - return (!(allpieces & rookPath) && !(allpieces & (path & NOTPOW2[startPosBlackRookKingSide])) && + const u64 rookPath = LINK_SQUARE[startPosBlackRookKingSide][F8] & NOTPOW2(startPosBlackKing); + const u64 kingPath = path | POW2(G8) | POW2(startPosBlackKing); + return (!(allpieces & rookPath) && !(allpieces & (path & NOTPOW2(startPosBlackRookKingSide))) && !board::anyAttack(kingPath, allpieces, chessboard) && - !board::anyAttack(kingPath, allpieces & NOTPOW2[startPosBlackRookKingSide], chessboard)); + !board::anyAttack(kingPath, allpieces & NOTPOW2(startPosBlackRookKingSide), chessboard)); } bool allowQueenSideBlack(const u64 allpieces) const { - auto a = board::isCastleRight_BlackQueen(chessboard) && + auto a = board::isCastleRight_BlackQueen(rightCastle) && board::isPieceAt(KING_BLACK, startPosBlackKing, chessboard) && board::isPieceAt(ROOK_BLACK, startPosBlackRookQueenSide, chessboard) && (!board::isOccupied(C8, allpieces) || startPosBlackKing == C8 || startPosBlackRookQueenSide == C8) && (!board::isOccupied(D8, allpieces) || startPosBlackKing == D8 || startPosBlackRookQueenSide == D8) && !(startPosWhiteKing == C8 && startPosWhiteRookQueenSide == D8); if (!a)return false; - const u64 rookPath = LINK_SQUARE[startPosBlackRookQueenSide][D8] & NOTPOW2[startPosBlackKing]; + const u64 rookPath = LINK_SQUARE[startPosBlackRookQueenSide][D8] & NOTPOW2(startPosBlackKing); const u64 path = LINK_SQUARE[startPosBlackKing][C8]; - const u64 kingPath = path | POW2[C8] | POW2[startPosBlackKing]; - return (!(allpieces & rookPath) && !(allpieces & (path & NOTPOW2[startPosBlackRookQueenSide])) && + const u64 kingPath = path | POW2(C8) | POW2(startPosBlackKing); + return (!(allpieces & rookPath) && !(allpieces & (path & NOTPOW2(startPosBlackRookQueenSide))) && !board::anyAttack(kingPath, allpieces, chessboard) && - !board::anyAttack(kingPath, allpieces & NOTPOW2[startPosBlackRookQueenSide], + !board::anyAttack(kingPath, allpieces & NOTPOW2(startPosBlackRookQueenSide), chessboard)); } @@ -685,7 +638,7 @@ class GenMoves : public ChessBoard { bool allowCastleWhiteKing(const u64 allpieces) const; bool allowQueenSideWhite(const u64 allpieces) const { - const auto a = board::isCastleRight_WhiteQueen(chessboard) && + const auto a = board::isCastleRight_WhiteQueen(rightCastle) && board::isPieceAt(KING_WHITE, startPosWhiteKing, chessboard) && board::isPieceAt(ROOK_WHITE, startPosWhiteRookQueenSide, chessboard) && (!board::isOccupied(C1, allpieces) || startPosWhiteKing == C1 || @@ -695,15 +648,15 @@ class GenMoves : public ChessBoard { !(startPosWhiteKing == C1 && startPosWhiteRookQueenSide == D1); if (!a)return false; const u64 path = LINK_SQUARE[startPosWhiteKing][C1]; - const u64 rookPath = LINK_SQUARE[startPosWhiteRookQueenSide][D1] & NOTPOW2[startPosWhiteKing]; - const u64 kingPath = path | POW2[C1] | POW2[startPosWhiteKing]; - return (!(allpieces & rookPath) && !(allpieces & (path & NOTPOW2[startPosWhiteRookQueenSide])) && + const u64 rookPath = LINK_SQUARE[startPosWhiteRookQueenSide][D1] & NOTPOW2(startPosWhiteKing); + const u64 kingPath = path | POW2(C1) | POW2(startPosWhiteKing); + return (!(allpieces & rookPath) && !(allpieces & (path & NOTPOW2(startPosWhiteRookQueenSide))) && !board::anyAttack(kingPath, allpieces, chessboard) && - !board::anyAttack(kingPath, allpieces & NOTPOW2[startPosWhiteRookQueenSide], chessboard)); + !board::anyAttack(kingPath, allpieces & NOTPOW2(startPosWhiteRookQueenSide), chessboard)); } bool allowKingSideWhite(const u64 allpieces) const { - const auto a = board::isCastleRight_WhiteKing(chessboard) && + const auto a = board::isCastleRight_WhiteKing(rightCastle) && board::isPieceAt(KING_WHITE, startPosWhiteKing, chessboard) && board::isPieceAt(ROOK_WHITE, startPosWhiteRookKingSide, chessboard) && (!board::isOccupied(G1, allpieces) || startPosWhiteKing == G1 || @@ -713,171 +666,142 @@ class GenMoves : public ChessBoard { !(startPosWhiteKing == G1 && startPosWhiteRookKingSide == F1); if (!a)return a; const u64 path = LINK_SQUARE[startPosWhiteKing][G1]; - const u64 rookPath = LINK_SQUARE[startPosWhiteRookKingSide][F1] & NOTPOW2[startPosWhiteKing]; - const u64 kingPath = path | POW2[G1] | POW2[startPosWhiteKing]; - return (!(allpieces & rookPath) && !(allpieces & (path & NOTPOW2[startPosWhiteRookKingSide])) && + const u64 rookPath = LINK_SQUARE[startPosWhiteRookKingSide][F1] & NOTPOW2(startPosWhiteKing); + const u64 kingPath = path | POW2(G1) | POW2(startPosWhiteKing); + return (!(allpieces & rookPath) && !(allpieces & (path & NOTPOW2(startPosWhiteRookKingSide))) && !board::anyAttack(kingPath, allpieces, chessboard) && - !board::anyAttack(kingPath, allpieces & NOTPOW2[startPosWhiteRookKingSide], chessboard)); + !board::anyAttack(kingPath, allpieces & NOTPOW2(startPosWhiteRookKingSide), chessboard)); } - template + template void tryAllCastle960(const u64 allpieces) { if (side == WHITE) { - if (allowKingSideWhite(allpieces)) { - - pushmove(-1, -1, NO_PROMOTION, -1, false); + pushmove(NO_POSITION, NO_POSITION, NO_PROMOTION, NO_PIECE, false); } - if (allowQueenSideWhite(allpieces)) { - - pushmove(-1, -1, NO_PROMOTION, -1, false); + pushmove(NO_POSITION, NO_POSITION, NO_PROMOTION, NO_PIECE, false); } } else { if (allowKingSideBlack(allpieces)) { - - pushmove(-1, -1, NO_PROMOTION, -1, false); + pushmove(NO_POSITION, NO_POSITION, NO_PROMOTION, NO_PIECE, false); } - if (allowQueenSideBlack(allpieces)) { - - pushmove(-1, -1, NO_PROMOTION, -1, false); + pushmove(NO_POSITION, NO_POSITION, NO_PROMOTION, NO_PIECE, false); } } } - template + template void tryAllCastleStandard(const u64 allpieces) { if (side == WHITE) { if (allowCastleWhiteKing(allpieces)) - pushmove(-1, -1, NO_PROMOTION, -1, false); + pushmove(NO_POSITION, NO_POSITION, NO_PROMOTION, NO_PIECE, false); if (allowCastleWhiteQueen(allpieces)) { - pushmove(-1, -1, NO_PROMOTION, -1, false); + pushmove(NO_POSITION, NO_POSITION, NO_PROMOTION, NO_PIECE, false); } } else { if (allowCastleBlackKing(allpieces)) - pushmove(-1, -1, NO_PROMOTION, -1, false); + pushmove(NO_POSITION, NO_POSITION, NO_PROMOTION, NO_PIECE, false); if (allowCastleBlackQueen(allpieces)) - pushmove(-1, -1, NO_PROMOTION, -1, false); + pushmove(NO_POSITION, NO_POSITION, NO_PROMOTION, NO_PIECE, false); } } - template - bool pushmove(const int from, const int to, const int promotionPiece, const int pieceFrom, const bool isCapture) { -#ifdef DEBUG_MODE - if (((type & 0x3) != ENPASSANT_MOVE_MASK) && !(type & 0xc)) { - auto a = board::getPieceAt(POW2[to], chessboard); - if (from != -1 && (isCapture && a == SQUARE_EMPTY || !isCapture && a != SQUARE_EMPTY)) { - if (((type & 0x3) != ENPASSANT_MOVE_MASK)) { - display(); - cout << isCapture << " " << BOARD[from] << " " << BOARD[to] << endl << flush; - cout << 1; - } - } - } -#endif - BENCH(times->start("pushmove")) - ASSERT(chessboard[KING_BLACK]); - ASSERT(chessboard[KING_WHITE]); - int piece_captured = SQUARE_EMPTY; + + template + bool + pushmove(const uchar from, const uchar to, const uchar promotionPiece, const uchar pieceFrom, + const bool isCapture) { + BENCH_AUTO_CLOSE("pushmove") + assert(chessboard[KING_BLACK]); + assert(chessboard[KING_WHITE]); + uchar capturedPiece = SQUARE_EMPTY; bool res = false; if (((type & 0x3) != ENPASSANT_MOVE_MASK) && !(type & 0xc)) { if (isCapture) { - piece_captured = board::getPieceAt(POW2[to], chessboard); - if (piece_captured == KING_BLACK + (side ^ 1)) { + capturedPiece = board::getPieceAt(POW2(to), chessboard); + if (capturedPiece == KING_BLACK + (X(side))) { res = true; } } } else if (!(type & 0xc)) {//en passant - piece_captured = side ^ 1; + capturedPiece = X(side); } if (!(type & 0xc) && (forceCheck || perftMode)) { - BENCH(times->subProcess("pushmove", "inCheck")) - if (inCheck(from, to, pieceFrom, piece_captured, promotionPiece)) { - BENCH(times->stop("pushmove")); - return false; - } - } - ASSERT_RANGE(listId, 0, MAX_PLY - 1); - ASSERT(getListSize() < MAX_MOVE); - auto mos = &gen_list[listId].moveList[getListSize()]; - ++gen_list[listId].size; - mos->s.type = (uchar) chessboard[RIGHT_CASTLE_IDX] | type; - mos->s.side = (char) side; - mos->s.capturedPiece = piece_captured; + BENCH_SUBPROCESS("pushmove", "inCheck") + if (inCheck(from, to, pieceFrom, capturedPiece, promotionPiece)) return false; + } + ASSERT_RANGE(listId, 0, MAX_PLY - 1) + assert(getListSize() < MAX_MOVE); + auto move = &genList[listId].moveList[getListSize()]; + ++genList[listId].size; + move->type = rightCastle | type; + move->side = side; + move->capturedPiece = capturedPiece; if (type & 0x3) { - mos->s.from = (uchar) from; - mos->s.to = (uchar) to; - mos->s.pieceFrom = pieceFrom; - mos->s.promotionPiece = (char) promotionPiece; - + move->from = (uchar) from; + move->to = (uchar) to; + move->pieceFrom = pieceFrom; + move->promotionPiece = (char) promotionPiece; } - ASSERT(getListSize() < MAX_MOVE); - BENCH(times->stop("pushmove")); + assert(getListSize() < MAX_MOVE); return res; } _Tmove *getMove(const int i) const { - return &gen_list[listId].moveList[i]; + return &genList[listId].moveList[i]; } - void setRunning(const int t) { + virtual void setRunning(const int t) { running = t; } - int getRunning() const { + virtual int getRunning() const { return running; } - void setHistoryHeuristic(const int from, const int to, const int value) { - ASSERT_RANGE(from, 0, 63); - ASSERT_RANGE(to, 0, 63); + void setHistoryHeuristic(const int from, const int to, const int depth) { + ASSERT_RANGE(from, 0, 63) + ASSERT_RANGE(to, 0, 63) + const int value = (depth < 30) ? 2 << depth : 0x40000000; historyHeuristic[from][to] = value; } - void setKiller(const int from, const int to, const int ply, const bool isMate) { - ASSERT_RANGE(from, 0, 63); - ASSERT_RANGE(to, 0, 63); - if (isMate) killer[2][ply] = from | (to << 8); - else { - killer[1][ply] = killer[0][ply]; - killer[0][ply] = from | (to << 8); - } + void setKiller(const int from, const int to, const int ply) { + ASSERT_RANGE(from, 0, 63) + ASSERT_RANGE(to, 0, 63) + killer[1][ply] = killer[0][ply]; + killer[0][ply] = from | (to << 8); } bool isKiller(const int idx, const int from, const int to, const int ply) { - ASSERT_RANGE(from, 0, 63); - ASSERT_RANGE(to, 0, 63); - unsigned short v = from | (to << 8); - if (v == killer[idx][ply])return true; - return false; - } - - bool isKillerMate(const int from, const int to, const int ply) { - ASSERT_RANGE(from, 0, 63); - ASSERT_RANGE(to, 0, 63); - unsigned short v = from | (to << 8); - if (v == killer[2][ply])return true; - return false; + ASSERT_RANGE(from, 0, 63) + ASSERT_RANGE(to, 0, 63) + const unsigned short v = from | (to << 8); + return v == killer[idx][ply]; } + bool forceCheck; private: + int running; bool isInCheck; - static bool forceCheck; static constexpr u64 TABJUMPPAWN = 0xFF00000000FF00ULL; void writeRandomFen(const vector); - template - void checkJumpPawn(u64 x, const u64 xallpieces) { - BENCH(times->start("checkJumpPawn")) + _Tmove *swap(_TmoveP *list, const int i, const int j) { + std::swap(list->moveList[i], list->moveList[j]); + return &list->moveList[i]; + } + template + void performJumpPawn(u64 x, const u64 xallpieces) { + BENCH_AUTO_CLOSE("performJumpPawn") x &= TABJUMPPAWN; - if (!x) { - BENCH(times->stop("checkJumpPawn")); - return; - } + if (!x) return; + if (side) { x = (((x << 8) & xallpieces) << 8) & xallpieces; } else { @@ -885,21 +809,20 @@ class GenMoves : public ChessBoard { } for (; x; RESET_LSB(x)) { const int o = BITScanForward(x); - BENCH(times->subProcess("checkJumpPawn", "pushmove")) + BENCH_SUBPROCESS("performJumpPawn", "pushmove") pushmove(o + (side ? -16 : 16), o, NO_PROMOTION, side, false); } - BENCH(times->stop("checkJumpPawn")) } void popStackMove() { - ASSERT_RANGE(repetitionMapCount, 1, MAX_REP_COUNT - 1); + ASSERT_RANGE(repetitionMapCount, 1, MAX_REP_COUNT - 1) if (--repetitionMapCount && repetitionMap[repetitionMapCount - 1] == 0) { repetitionMapCount--; } } void pushStackMove(const u64 key) { - ASSERT(repetitionMapCount < MAX_REP_COUNT - 1); + assert(repetitionMapCount < MAX_REP_COUNT - 1); repetitionMap[repetitionMapCount++] = key; } diff --git a/src/GetOpt.h b/src/GetOpt.h index 744aee61..a085138d 100644 --- a/src/GetOpt.h +++ b/src/GetOpt.h @@ -1,256 +1,271 @@ -/* - Cinnamon UCI chess engine - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#pragma once - -#include "util/Singleton.h" -#include "perft/Perft.h" - -static const string - PERFT_HELP = "-perft [-d depth] [-c nCpu] [-h hash size (mb) [-F dump file]] [-Chess960] [-f \"fen position\"]"; -static const string DTM_GTB_HELP = "-dtm-gtb -f \"fen position\" -p path [-s scheme] [-i installed pieces]"; -static const string WDL_GTB_HELP = "-wdl-gtb -f \"fen position\" -p path [-s scheme] [-i installed pieces]"; -static const string DTZ_SYZYGY_HELP = "-dtz-syzygy -f \"fen position\" -p path"; -static const string WDL_SYZYGY_HELP = "-wdl-syzygy -f \"fen position\" -p path"; -static const string PUZZLE_HELP = "-puzzle_epd -t K?K? ex: KRKP | KQKP | KBBKN | KQKR | KRKB | KRKN ..."; - -class GetOpt { - -private: - static void printHeader() { - - cout << NAME << " UCI chess engine by Giuseppe Cannella\n"; - -#ifdef HAS_64BIT - cout << "64-bit "; -#else - cout << "32-bit "; -#endif -#ifdef HAS_POPCNT - cout << "popcnt "; -#endif -#ifdef HAS_BSF - cout << "bsf "; -#endif -#ifdef USE_BMI2 - cout << "bmi2 "; -#endif - cout << "compiled " << __DATE__ << " with "; -#if defined(__clang__) - cout << "Clang/LLVM " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__; -#elif defined(__ICC) || defined(__INTEL_COMPILER) - cout << "Intel ICC "<<__VERSION__; -#elif defined(__GNUC__) || defined(__GNUG__) - cout << "GNU GCC " << __VERSION__; -#elif defined(__HP_cc) || defined(__HP_aCC) - cout << "Hewlett-Packard aC++" <<__HP_aCC; -#elif defined(__IBMC__) || defined(__IBMCPP__) - cout << "IBM XL C++ <<"__IBMCPP__; -#elif defined(_MSC_VER) - cout << "Microsoft Visual Studio. "<<_MSC_VER; -#elif defined(__PGI) - cout << "Portland Group PGCC/PGCPP "<<__PGIC__; -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) - cout << "Oracle Solaris Studio "<<__SUNPRO_CC; -#else - cout << "Unknown compiler"; -#endif - cout << "\nLicense GPLv3+: GNU GPL version 3 or later \n\n"; -#ifdef CLOP - cout << "CLOP ENABLED\n"; -#endif -#ifdef DEBUG_MODE - cout << "DEBUG_MODE\n"; - cout << "Log level: " << LOG_LEVEL_STRING[DLOG_LEVEL] << endl; -#endif - cout << flush; - } - - static void help(char **argv) { - string exe = FileUtil::getFileName(argv[0]); - cout << "Perft test: " << exe << " " << PERFT_HELP << endl; - cout << "DTM (gtb): " << exe << " " << DTM_GTB_HELP << endl; - cout << "WDL (gtb): " << exe << " " << WDL_GTB_HELP << endl; - cout << "DTZ (syzygy): " << exe << " " << DTZ_SYZYGY_HELP << endl; - cout << "WDL (syzygy): " << exe << " " << WDL_SYZYGY_HELP << endl; - cout << "Generate puzzle epd: " << exe << " " << PUZZLE_HELP << endl; - } - - static void perft(int argc, char **argv) { - if (string(optarg) != "erft") { - help(argv); - return; - }; - int nCpu = 0; - int perftDepth = 0; - string fen; - int perftHashSize = 0; - string dumpFile; - bool chess960 = false; - int opt; - string iniFile; - while ((opt = getopt(argc, argv, "d:f:h:f:c:F:9:C:")) != -1) { - if (opt == 'd') { //depth - perftDepth = atoi(optarg); - } else if (opt == 'F') { //use dump - dumpFile = optarg; - if (dumpFile.empty()) { - cout << "use: " << argv[0] << " " << PERFT_HELP << endl; - return; - } - } else if (opt == 'c') { //N cpu - nCpu = atoi(optarg); - } else if (opt == 'h') { //hash - perftHashSize = atoi(optarg); - } else if (opt == 'f') { //fen - fen = optarg; - } else if (opt == 'C') { //chess960 - if (!string(optarg).compare("hess960")) - chess960 = true; - } - } - Perft *perft = &Perft::getInstance(); - perft->setParam(fen, perftDepth, nCpu, perftHashSize, dumpFile, chess960); - perft->start(); - perft->join(); - } - - static void dtmWdlGtb(int argc, char **argv, const bool dtm) { - SearchManager &searchManager = Singleton::getInstance(); - - GTB *gtb = >B::getInstance(); - string fen, token; - IterativeDeeping it; - int opt; - while ((opt = getopt(argc, argv, "f:p:s:i:")) != -1) { - if (opt == 'f') { //fen - fen = optarg; - } else if (opt == 'p') { //path - token = optarg; - gtb->setPath(token); - } else if (opt == 's') { //scheme - token = optarg; - if (!gtb->setScheme(token)) { - cout << "set scheme error" << endl; - return; - } - } else if (opt == 'i') { - token = optarg; - if (!gtb->setInstalledPieces(stoi(token))) { - cout << "set installed pieces error" << endl; - return; - } - } - } - if (gtb == nullptr) { - cout << "error GTB not found" << endl; - return; - } - searchManager.loadFen(fen); - searchManager.printDtmGtb(dtm); - } - - static void createSyzygy(int argc, char **argv) { - string fen, token; - IterativeDeeping it; - int opt; - SearchManager &searchManager = Singleton::getInstance(); - - while ((opt = getopt(argc, argv, "f:p:s:i:")) != -1) { - if (opt == 'f') { //fen - fen = optarg; - searchManager.loadFen(fen); - } else if (opt == 'p') { //path - token = optarg; - SYZYGY::getInstance().createSYZYGY(token); - } - } - } - - static void wdlSyzygy(int argc, char **argv) { - createSyzygy(argc, argv); - SearchManager &searchManager = Singleton::getInstance(); - searchManager.printWdlSyzygy(); - } - - static void dtmSyzygy(int argc, char **argv) { - createSyzygy(argc, argv); - SearchManager &searchManager = Singleton::getInstance(); - searchManager.printDtmSyzygy(); - } - -public: - - static void parse(int argc, char **argv) { - if (!(argc > 1 && !strcmp("-puzzle_epd", argv[1]))) - printHeader(); - if (argc == 2 && !strcmp(argv[1], "--help")) { - help(argv); - return; - } - - int opt; - - while ((opt = getopt(argc, argv, "p:e:hd:b:f:w:")) != -1) { - if (opt == 'h') { - help(argv); - return; - } - if (opt == 'p') { // perft test - if (string(optarg) == "erft") { - perft(argc, argv); - } else if (string(optarg) == "uzzle_epd") { - while ((opt = getopt(argc, argv, "t:")) != -1) { - if (opt == 't') { //file - Search a; - if (!a.generatePuzzle(optarg)) { - cout << "error use: " << PUZZLE_HELP << endl; - } - return; - } - } - } - return; - } else { - if (opt == 'e') { - help(argv); - return; - } else if (opt == 'd') { - if (string(optarg) == "tm-gtb") { - dtmWdlGtb(argc, argv, true); - return; - } else if (string(optarg) == "tz-syzygy") { - dtmSyzygy(argc, argv); - return; - } - return; - } else if (opt == 'w') { - if (string(optarg) == "dl-gtb") { - dtmWdlGtb(argc, argv, false); - return; - } else if (string(optarg) == "dl-syzygy") { - wdlSyzygy(argc, argv); - return; - } - return; - } - } - } - Uci::getInstance(); - } -}; +/* + Cinnamon UCI chess engine + Copyright (C) Giuseppe Cannella + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "util/Singleton.h" +#include "perft/Perft.h" +#include "util/getopt.h" +#include "util/tuning/Texel.h" + +static const string + PERFT_HELP = "-perft [-d depth] [-c nCpu] [-h hash size (mb) [-F dump file]] [-Chess960] [-f \"fen position\"]"; +static const string DTM_GTB_HELP = "-dtm-gtb -f \"fen position\" -p path [-s scheme] [-i installed pieces]"; +static const string WDL_GTB_HELP = "-wdl-gtb -f \"fen position\" -p path [-s scheme] [-i installed pieces]"; +static const string DTZ_SYZYGY_HELP = "-dtz-syzygy -f \"fen position\" -p path"; +static const string WDL_SYZYGY_HELP = "-wdl-syzygy -f \"fen position\" -p path"; +static const string PUZZLE_HELP = "-puzzle_epd -t K?K? ex: KRKP | KQKP | KBBKN | KQKR | KRKB | KRKN ..."; + +class GetOpt { + +private: + static void printHeader(const string &exe) { + + cout << NAME << " UCI chess engine by Giuseppe Cannella\n"; + +#ifdef HAS_POPCNT + cout << "popcnt "; +#endif +#ifdef HAS_BSF + cout << "bsf "; +#endif +#ifdef USE_BMI2 + cout << "bmi2 "; +#endif + cout << "compiled " << __DATE__ << " with "; +#if defined(__clang__) + cout << "Clang/LLVM " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__; +#elif defined(__ICC) || defined(__INTEL_COMPILER) + cout << "Intel ICC " << __VERSION__; +#elif defined(__GNUC__) || defined(__GNUG__) + cout << "GNU GCC " << __VERSION__; +#elif defined(__HP_cc) || defined(__HP_aCC) + cout << "Hewlett-Packard aC++" << __HP_aCC; +#elif defined(__IBMC__) || defined(__IBMCPP__) + cout << "IBM XL C++ <<"__IBMCPP__; +#elif defined(_MSC_VER) + cout << "Microsoft Visual Studio. " << _MSC_VER; +#elif defined(__PGI) + cout << "Portland Group PGCC/PGCPP " << __PGIC__; +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) + cout << "Oracle Solaris Studio " << __SUNPRO_CC; +#else + cout << "Unknown compiler"; +#endif + cout << "\nLicense GPLv3+: GNU GPL version 3 or later \n"; + cout << "Run " << exe << " -h for more commands." << endl << endl; + + DEBUG(cout << "DEBUG_MODE" << endl) + DEBUG(cout << "Log level: " << LOG_LEVEL_STRING[DLOG_LEVEL] << endl) + cout << flush; + } + + static void help(char **argv) { + string exe = FileUtil::getFileName(argv[0]); + cout << "Perft test: " << exe << " " << PERFT_HELP << endl; + cout << "DTM (gtb): " << exe << " " << DTM_GTB_HELP << endl; + cout << "WDL (gtb): " << exe << " " << WDL_GTB_HELP << endl; + cout << "DTZ (syzygy): " << exe << " " << DTZ_SYZYGY_HELP << endl; + cout << "WDL (syzygy): " << exe << " " << WDL_SYZYGY_HELP << endl; + cout << "Generate puzzle epd: " << exe << " " << PUZZLE_HELP << endl; + } + + static void perft(int argc, char **argv) { + if (string(optarg) != "erft") { + help(argv); + return; + } + int nCpu = 0; + int perftDepth = 0; + string fen; + int perftHashSize = 0; + string dumpFile; + bool chess960 = false; + int opt; + string iniFile; + bool useDump = false; + while ((opt = getopt1(argc, argv, "d:f:h:f:c:F:9:C:")) != -1) { + if (opt == 'd') { //depth + perftDepth = atoi(optarg); + } else if (opt == 'c') { //N cpu + nCpu = atoi(optarg); + } else if (opt == 'h') { //hash + perftHashSize = atoi(optarg); + } else if (opt == 'F') { //use dump + dumpFile = optarg; + if (dumpFile.empty()) { + cout << "use: " << argv[0] << " " << PERFT_HELP << endl; + return; + } + useDump = true; + } else if (opt == 'f') { //fen + fen = optarg; + } else if (opt == 'C') { //chess960 + if (!string(optarg).compare("hess960")) + chess960 = true; + } + } + if (useDump && !FileUtil::fileExists(dumpFile) && !perftHashSize) { + cout << "Error: with '-F' parameter you have to specify either an existing dump file or a hash size (-h)" + << endl << endl; + help(argv); + return; + } + if (useDump && FileUtil::fileExists(dumpFile) && perftHashSize) { + cout << "Error: with '-F' parameter and existing dump file you can't specify hash size (-h)" << endl + << endl; + help(argv); + return; + } + Perft *perft = &Perft::getInstance(); + perft->setParam(fen, perftDepth, nCpu, perftHashSize, dumpFile, chess960); + perft->start(); + perft->join(); + } + + static void dtmWdlGtb(int argc, char **argv, const bool dtm) { + SearchManager &searchManager = Singleton::getInstance(); + + GTB *gtb = >B::getInstance(); + string fen, token; + IterativeDeeping it; + int opt; + while ((opt = getopt1(argc, argv, "f:p:s:i:")) != -1) { + if (opt == 'f') { //fen + fen = optarg; + } else if (opt == 'p') { //path + token = optarg; + gtb->setPath(token); + } else if (opt == 's') { //scheme + token = optarg; + if (!gtb->setScheme(token)) { + cout << "set scheme error" << endl; + return; + } + } else if (opt == 'i') { + token = optarg; + if (!gtb->setInstalledPieces(stoi(token))) { + cout << "set installed pieces error" << endl; + return; + } + } + } + if (gtb == nullptr) { + cout << "error GTB not found" << endl; + return; + } + searchManager.loadFen(fen); + searchManager.printDtmGtb(dtm); + } + + static void createSyzygy(int argc, char **argv) { + string fen, token; + IterativeDeeping it; + int opt; + SearchManager &searchManager = Singleton::getInstance(); + + while ((opt = getopt1(argc, argv, "f:p:s:i:")) != -1) { + if (opt == 'f') { //fen + fen = optarg; + searchManager.loadFen(fen); + } else if (opt == 'p') { //path + token = optarg; + SYZYGY::getInstance().createSYZYGY(token); + } + } + } + + static void wdlSyzygy(int argc, char **argv) { + createSyzygy(argc, argv); + SearchManager &searchManager = Singleton::getInstance(); + searchManager.printWdlSyzygy(); + } + + static void dtmSyzygy(int argc, char **argv) { + createSyzygy(argc, argv); + SearchManager &searchManager = Singleton::getInstance(); + searchManager.printDtmSyzygy(); + } + +public: + + static void parse(int argc, char **argv) { +#ifdef TUNING + + cout << Texel::help << endl; + cout << "run " << FileUtil::getFileName(argv[0]) << " path" << endl; + return; + +#endif + if (!(argc > 1 && !strcmp("-puzzle_epd", argv[1]))) + printHeader(FileUtil::getFileName(argv[0])); + if (argc == 2 && !strcmp(argv[1], "--help")) { + help(argv); + return; + } + + int opt; + + while ((opt = getopt1(argc, argv, "p:e:hd:b:f:w:")) != -1) { + if (opt == 'h') { + help(argv); + return; + } + if (opt == 'p') { // perft test + if (string(optarg) == "erft") { + perft(argc, argv); + } else if (string(optarg) == "uzzle_epd") { + while ((opt = getopt1(argc, argv, "t:")) != -1) { + if (opt == 't') { //file + Search a; + if (!a.generatePuzzle(optarg)) { + cout << "error use: " << PUZZLE_HELP << endl; + } + return; + } + } + } + return; + } else { + if (opt == 'e') { + help(argv); + return; + } else if (opt == 'd') { + if (string(optarg) == "tm-gtb") { + dtmWdlGtb(argc, argv, true); + return; + } else if (string(optarg) == "tz-syzygy") { + dtmSyzygy(argc, argv); + return; + } + return; + } else if (opt == 'w') { + if (string(optarg) == "dl-gtb") { + dtmWdlGtb(argc, argv, false); + return; + } else if (string(optarg) == "dl-syzygy") { + wdlSyzygy(argc, argv); + return; + } + return; + } + } + } + Uci::getInstance(); + } +}; diff --git a/src/Hash.cpp b/src/Hash.cpp index b55ca68b..1b146d45 100644 --- a/src/Hash.cpp +++ b/src/Hash.cpp @@ -16,60 +16,43 @@ along with this program. If not, see . */ -#include #include "Hash.h" -Hash::Hash() { - HASH_SIZE = 0; - hashArray[HASH_ALWAYS] = hashArray[HASH_GREATER] = nullptr; +unsigned Hash::HASH_SIZE; +Hash::_Thash *Hash::hashArray; #ifdef DEBUG_MODE - n_cut_hashA = n_cut_hashB = cutFailed = probeHash = readCollisions = 0; - nRecordHashA = nRecordHashB = nRecordHashE = collisions = 0; +unsigned Hash::nRecordHashA, Hash::nRecordHashB, Hash::nRecordHashE, Hash::collisions, Hash::readCollisions, + Hash::n_cut_hashA, Hash::n_cut_hashB, Hash::n_cut_hashE, Hash::readHashCount; #endif - setHashSize(HASH_SIZE_DEFAULT); -} - -void Hash::clearAge() { - for (unsigned i = 0; i < HASH_SIZE; i++) { - hashArray[HASH_ALWAYS][i].u.dataS.entryAge = 0; - } +Hash::Hash() { + HASH_SIZE = 0; + hashArray = nullptr; + DEBUG(n_cut_hashA = n_cut_hashB = readCollisions = nRecordHashA = nRecordHashB = nRecordHashE = readCollisions = collisions = 0) + setHashSize(HASH_SIZE_DEFAULT); } void Hash::clearHash() { - if (!HASH_SIZE) { - return; - } - memset(static_cast(hashArray[HASH_GREATER]), 0, sizeof(_Thash) * HASH_SIZE); - memset(static_cast(hashArray[HASH_ALWAYS]), 0, sizeof(_Thash) * HASH_SIZE); + if (!HASH_SIZE) return; + memset(static_cast(hashArray), 0, sizeof(_Thash) * (HASH_SIZE + BUCKETS)); } -void Hash::setHashSize(int mb) { +void Hash::setHashSize(const int mb) { dispose(); if (mb > 0) { - u64 tmp = (u64)mb * 1024 * 1024 / (sizeof(_Thash) * 2); - hashArray[HASH_ALWAYS] = (_Thash *) calloc(tmp, sizeof(_Thash)); - if (!hashArray[HASH_ALWAYS]) { - fatal("info string error - no memory"); + u64 tmp = (u64) mb * 1024 * 1024 / (sizeof(_Thash)); + hashArray = (_Thash *) calloc(tmp, sizeof(_Thash)); + if (!hashArray) { + fatal("info string error - no memory") exit(1); } - hashArray[HASH_GREATER] = (_Thash *) calloc(tmp, sizeof(_Thash)); - if (!hashArray[HASH_GREATER]) { - fatal("info string error - no memory"); - exit(1); - } - HASH_SIZE = tmp; + HASH_SIZE = tmp - BUCKETS; } } void Hash::dispose() { - if (hashArray[HASH_ALWAYS] != nullptr) { - free(hashArray[HASH_ALWAYS]); - } - if (hashArray[HASH_GREATER] != nullptr) { - free(hashArray[HASH_GREATER]); - } - hashArray[HASH_ALWAYS] = hashArray[HASH_GREATER] = nullptr; + if (hashArray != nullptr) free(hashArray); + hashArray = nullptr; HASH_SIZE = 0; } diff --git a/src/Hash.h b/src/Hash.h index 09516e51..325e116c 100644 --- a/src/Hash.h +++ b/src/Hash.h @@ -24,8 +24,7 @@ #include "namespaces/constants.h" #include "util/Singleton.h" #include "util/logger.h" -#include "threadPool/Spinlock.h" -#include +#include using namespace constants; using namespace _logger; @@ -35,37 +34,22 @@ class Hash : public Singleton { public: - static constexpr int HASH_ALWAYS = 1; - static constexpr int HASH_GREATER = 0; - - typedef union _ThashData { - u64 dataU; - - struct __dataS { - short score; - char depth; - uchar from; - uchar to; - uchar entryAge; - uchar flags; - - __dataS() {}; - - __dataS(const short score, const char depth, const uchar from, const uchar to, const uchar entryAge, - const uchar flags) : - score(score), depth(depth), from(from), to(to), entryAge(entryAge), flags(flags) {}; - } dataS; - - _ThashData() {}; - - _ThashData(const short score, const char depth, const uchar from, const uchar to, const uchar entryAge, - const uchar flags) : - dataS(score, depth, from, to, entryAge, flags) {}; - } __Tdata; - - typedef struct { + typedef struct _Thash { u64 key; - _ThashData u; + // 123456789ABCDEF|12345678|12345678|12345678|12345678|123456789ABCDEF| + // age | flags | from | to | depth | score | + u64 data; + + _Thash(const u64 zobristKeyR, const short score, const char depth, const uchar from, const uchar to, + const uchar flags) { + key = zobristKeyR; + data = score; + data &= 0xffffULL; + data |= (u64) depth << 16; + data |= (u64) to << (16 + 8); + data |= (u64) from << (16 + 8 + 8); + data |= (u64) flags << (16 + 8 + 8 + 8); + } } _Thash; enum : char { @@ -73,75 +57,140 @@ class Hash : public Singleton { }; #ifdef DEBUG_MODE - unsigned nRecordHashA, nRecordHashB, nRecordHashE, collisions, readCollisions; - - int n_cut_hashA, n_cut_hashB, cutFailed, probeHash; + static unsigned nRecordHashA, nRecordHashB, nRecordHashE, collisions, readCollisions, n_cut_hashA, n_cut_hashB, n_cut_hashE, readHashCount; #endif - void setHashSize(int mb); - - void clearHash(); - - void clearAge(); - - u64 readHash(const int type, const u64 zobristKeyR) -#ifndef DEBUG_MODE - const -#endif - { - const _Thash *hash = &(hashArray[type][zobristKeyR % HASH_SIZE]); - const u64 data = hash->u.dataU; - const u64 k = hash->key; - if (zobristKeyR == (k ^ data)) { - return data; + static void setHashSize(const int mb); + + static void clearHash(); + +#define SET_AGE(u, v) (u=(u&0xffffffffffffULL)|(((u64)v)<<(16 + 8 + 8 + 8 + 8))) +#define GET_DEPTH(v) ((uchar)(v>>16)) +#define GET_FLAGS(v) ((uchar)(v>>(16 + 8 + 8 + 8))) +#define GET_FROM(v) ((uchar)(v>>(16 + 8 + 8))) +#define GET_TO(v) ((uchar)(v>>(16 + 8))) +#define GET_SCORE(v) ((short ) v) +#define GET_AGE(v) ((unsigned short)(v>> (16 + 8 + 8 + 8 + 8))) +#define GET_KEY(hash) (hash->key ^ (hash->data & 0xffffffffffffULL)) + + static inline int readHash( + const int alpha, + const int beta, + const int depth, + const u64 zobristKeyR, u64 &checkHashStruct, const bool currentPly) { + INC(readHashCount); + const Hash::_Thash *hash = &(hashArray[zobristKeyR % HASH_SIZE]); + DEBUG(u64 d = 0) + checkHashStruct = 0; + bool found = false; + for (int i = 0; i < BUCKETS; i++, hash++) { + if (found)break; + u64 data = hash->data; + DEBUG(d |= data) + if (zobristKeyR == GET_KEY(hash)) { + found = true; + checkHashStruct = data; + if (GET_DEPTH(checkHashStruct) >= depth) { + if (currentPly) { + switch (GET_FLAGS(checkHashStruct)) { + case Hash::hashfEXACT: + case Hash::hashfBETA: + if (GET_SCORE(checkHashStruct) >= beta) { + INC(n_cut_hashB); + return beta; + } + break; + case Hash::hashfALPHA: + if (GET_SCORE(checkHashStruct) <= alpha) { + INC(n_cut_hashA); + return alpha; + } + break; + default: + fatal("Error checkHash") + exit(1); + } + } + } + } } - - DEBUG(if (data) readCollisions++) - - return 0; + DEBUG(if (d && !found)readCollisions++) + return INT_MAX; } - void recordHash(const u64 zobristKey, _ThashData &tmp) { - ASSERT(zobristKey); - const unsigned kMod = zobristKey % HASH_SIZE; - _Thash *rootHashG = &(hashArray[HASH_ALWAYS][kMod]); - - rootHashG->key = (zobristKey ^ tmp.dataU); - rootHashG->u.dataU = tmp.dataU; - + static void recordHash(const _Thash &toStore, const int ply) { #ifdef DEBUG_MODE - if (tmp.dataS.flags == hashfALPHA) { - nRecordHashA++; - } else if (tmp.dataS.flags == hashfBETA) { - nRecordHashB++; - } else { - nRecordHashE++; - } + assert(toStore.key); + if (GET_FLAGS(toStore.data) == hashfALPHA) nRecordHashA++; + else if (GET_FLAGS(toStore.data) == hashfBETA) nRecordHashB++; + else nRecordHashE++; #endif - - _Thash *rootHashA = &(hashArray[HASH_GREATER][kMod]); - - DEBUG(if (rootHashA->u.dataU) INC(collisions)) - - if (rootHashA->u.dataS.depth >= tmp.dataS.depth && rootHashA->u.dataS.entryAge) { + assert(GET_DEPTH(toStore.data) < MAX_PLY); + const unsigned kMod = toStore.key % HASH_SIZE; + + _Thash *empty = nullptr; + + { // update + _Thash *hash = &(hashArray[kMod]); + bool found = false; + for (int i = 0; i < BUCKETS; i++, hash++) { + const u64 data = hash->data; + if (toStore.key == GET_KEY(hash)) { + found = true; + if (GET_DEPTH(data) <= GET_DEPTH(toStore.data)) { + hash->key = (toStore.key ^ toStore.data); + hash->data = toStore.data; + SET_AGE(hash->data, ply); + return; + } + } else if (!hash->key) { + empty = hash; + if (found)break; + } + } + } + if (empty) { //empty slot + empty->key = (toStore.key ^ toStore.data); + empty->data = toStore.data; + SET_AGE(empty->data, ply); return; } - tmp.dataS.entryAge = 1; - rootHashA->key = (zobristKey ^ tmp.dataU); - rootHashA->u.dataU = tmp.dataU; + + { // age + _Thash *hash = &(hashArray[kMod]); + _Thash *old = &(hashArray[kMod]); + int i; + int oldTT = -INT_MAX; + for (i = 0; i < BUCKETS; i++, hash++) { + const u64 data = hash->data; + const auto age = ((ply - GET_AGE(data)) & 255) * 256 + 255 - GET_DEPTH(data); + if (age > oldTT) { + old = hash; + oldTT = age; + } + } + if (i == BUCKETS) hash = old; + + DEBUG(if (hash->key && hash->key != (toStore.key ^ toStore.data)) INC(collisions)) + hash->key = (toStore.key ^ toStore.data); + hash->data = toStore.data; + SET_AGE(hash->data, ply); + } } private: Hash(); - unsigned HASH_SIZE; + + static constexpr int BUCKETS = 3; + static unsigned HASH_SIZE; #ifdef JS_MODE static constexpr int HASH_SIZE_DEFAULT = 1; #else static constexpr int HASH_SIZE_DEFAULT = 64; #endif - void dispose(); + static void dispose(); - _Thash *hashArray[2]; + static _Thash *hashArray; }; diff --git a/src/IterativeDeeping.cpp b/src/IterativeDeeping.cpp index b022ac70..108ff571 100644 --- a/src/IterativeDeeping.cpp +++ b/src/IterativeDeeping.cpp @@ -18,9 +18,9 @@ #include "IterativeDeeping.h" -IterativeDeeping::IterativeDeeping() : maxDepth(MAX_PLY), running(false), openBook(nullptr), ponderEnabled(false) { - setUseBook(false); +IterativeDeeping::IterativeDeeping() : maxDepth(MAX_PLY), running(false), ponderEnabled(false) { setId(-1); + ply = 0; SET(checkSmp2, 0); } @@ -39,30 +39,6 @@ bool IterativeDeeping::getPonderEnabled() const { return ponderEnabled; } -bool IterativeDeeping::getUseBook() const { - return openBook; -} - -void IterativeDeeping::loadBook(const string f) { - openBook = OpenBook::getInstance(f); -} - -void IterativeDeeping::setUseBook(const bool b) { - if (!openBook && b) { - openBook = OpenBook::getInstance("cinnamon.bin"); - return; - } - if (!b && openBook) { - openBook->dispose(); - openBook = nullptr; - } -} - -string IterativeDeeping::go() { - run(); - return getBestmove(); -} - void IterativeDeeping::run() { if (LOCK_TEST_AND_SET(running)) { @@ -70,28 +46,11 @@ void IterativeDeeping::run() { } bestmove.clear(); INC(checkSmp2); - int timeTaken = 0; + int timeTaken; searchManager.setRunning(2); searchManager.setRunningThread(true); - //openbook - if (openBook) { - ASSERT(openBook); - string obMove = openBook->search(searchManager.boardToFen()); - if (!obMove.empty()) { - _Tmove move; - searchManager.getMoveFromSan(obMove, &move); - searchManager.makemove(&move); - cout << "bestmove " << obMove << endl; - ADD(checkSmp2, -1); - ASSERT(!checkSmp2); - LOCK_RELEASE(running); - return; - } - } - //Tablebase - string tb = searchManager.probeRootTB(); if (!tb.empty()) { debug("info string returned move from TB\n") @@ -100,7 +59,7 @@ void IterativeDeeping::run() { searchManager.makemove(&move); cout << "bestmove " << tb << endl; ADD(checkSmp2, -1); - ASSERT(!checkSmp2); + assert(!checkSmp2); LOCK_RELEASE(running); return; } @@ -111,7 +70,7 @@ void IterativeDeeping::run() { searchManager.startClock(); searchManager.clearHeuristic(); - hash.clearAge(); + ply++; searchManager.setForceCheck(false); auto start1 = std::chrono::high_resolution_clock::now(); @@ -123,7 +82,6 @@ void IterativeDeeping::run() { string pvv; _Tmove resultMove; - DEBUG(u64 totMovesPrec = -1) while (searchManager.getRunning(0)) { @@ -131,7 +89,7 @@ void IterativeDeeping::run() { ++mply; searchManager.init(); - auto sc = searchManager.search(mply); + auto sc = searchManager.search(ply, mply); searchManager.setRunningThread(1); searchManager.setRunning(1); @@ -140,49 +98,41 @@ void IterativeDeeping::run() { break; } - searchManager.incHistoryHeuristic(resultMove.s.from, resultMove.s.to, 0x800); + searchManager.incHistoryHeuristic(resultMove.from, resultMove.to, 0x1000); auto end1 = std::chrono::high_resolution_clock::now(); timeTaken = Time::diffTime(end1, start1) + 1; totMoves += searchManager.getTotMoves(); - if (sc > _INFINITE - MAX_PLY) { - sc = 0x7fffffff; - } #ifdef DEBUG_MODE - int totStoreHash = hash.nRecordHashA + hash.nRecordHashB + hash.nRecordHashE + 1; - int percStoreHashA = hash.nRecordHashA * 100 / totStoreHash; - int percStoreHashB = hash.nRecordHashB * 100 / totStoreHash; - int percStoreHashE = hash.nRecordHashE * 100 / totStoreHash; - int totCutHash = hash.n_cut_hashA + hash.n_cut_hashB + 1; - int percCutHashA = hash.n_cut_hashA * 100 / totCutHash; - int percCutHashB = hash.n_cut_hashB * 100 / totCutHash; - cout << "\ninfo string ply: " << mply << endl; - cout << "info string tot moves: " << totMoves << endl; - unsigned cumulativeMovesCount = searchManager.getCumulativeMovesCount(); - cout << "info string hash stored " << totStoreHash * 100 / (1 + cumulativeMovesCount) << "% (alpha=" << - percStoreHashA << "% beta=" << percStoreHashB << "% exact=" << percStoreHashE << "%)" << endl; + const int totStoreHash = hash.nRecordHashA + hash.nRecordHashB + hash.nRecordHashE + 1; + const int percStoreHashA = hash.nRecordHashA * 100 / totStoreHash; + const int percStoreHashB = hash.nRecordHashB * 100 / totStoreHash; + const int percStoreHashE = hash.nRecordHashE * 100 / totStoreHash; + const int totCutHash = hash.n_cut_hashA + hash.n_cut_hashB + hash.n_cut_hashE + 1; + const int percCutHashA = hash.n_cut_hashA * 100 / totCutHash; + const int percCutHashB = hash.n_cut_hashB * 100 / totCutHash; + const int percCutHashE = hash.n_cut_hashE * 100 / totCutHash; - cout << "info string cut hash " << totCutHash * 100 / (1 + searchManager.getCumulativeMovesCount()) << - "% (alpha=" << percCutHashA << "% beta=" << percCutHashB << "%)" << endl; + const unsigned cumulativeMovesCount = searchManager.getCumulativeMovesCount(); u64 nps = 0; if (timeTaken) { nps = totMoves * 1000 / timeTaken; } - int nCutAB = searchManager.getNCutAB(); - double betaEfficiency = searchManager.getBetaEfficiency(); - int LazyEvalCuts = searchManager.getLazyEvalCuts(); - int nCutFp = searchManager.getNCutFp(); - int nCutRazor = searchManager.getNCutRazor(); - - int collisions = hash.collisions; - unsigned readCollisions = hash.readCollisions; - int nNullMoveCut = hash.cutFailed; - unsigned totGen = searchManager.getTotGen(); - if (nCutAB) { - cout << "info string beta efficiency: " << (int) (betaEfficiency / totGen * 10) << "%" << endl; - } + const int nCutAB = searchManager.getNCutAB(); + + const int LazyEvalCuts = searchManager.getLazyEvalCuts(); + const int nCutFp = searchManager.getNCutFp(); + const int nCutRazor = searchManager.getNCutRazor(); + const int nBadCaputure = searchManager.getTotBadCaputure(); + const int nullMoveCut = searchManager.getNullMoveCut(); + + cout << "\ninfo string ply: " << mply << endl; + cout << "info string tot moves: " << totMoves << endl; + + if (nCutAB) cout << "info string beta efficiency: " << (searchManager.getBetaEfficiency()) << "%" << endl; + if (totMovesPrec != 0xffffffffffffffffULL) cout << "info string effective branching factor: " << setiosflags(ios::fixed) << setprecision(2) << ((double) totMoves / (double) totMovesPrec) << endl; @@ -191,42 +141,51 @@ void IterativeDeeping::run() { cout << "info string alphaBeta cut: " << nCutAB << endl; cout << "info string lazy eval cut: " << LazyEvalCuts << endl; cout << "info string futility pruning cut: " << nCutFp << endl; + cout << "info string null move cut: " << nullMoveCut << endl; cout << "info string razor cut: " << nCutRazor << endl; - cout << "info string null move cut: " << nNullMoveCut << endl; + cout << "info string bad caputure cut: " << nBadCaputure << endl; + printf("info string hash stored %d%% (alpha=%d%% beta=%d%% exact=%d%%)\n", + totStoreHash * 100 / (1 + cumulativeMovesCount), percStoreHashA, percStoreHashB, percStoreHashE); + + printf("info string hash cut %d%% (alpha=%d%% beta=%d%% exact=%d%%)\n", + totCutHash * 100 / (1 + searchManager.getCumulativeMovesCount()), percCutHashA, percCutHashB, + percCutHashE); + printf("info string hash write collisions: %d%%\n", hash.collisions * 100 / (totStoreHash + 1)); + printf("info string hash read collisions: %d%%\n", hash.readCollisions * 100 / (hash.readHashCount + 1)); - cout << "info string hash write collisions : " << collisions * 100 / totStoreHash << "%" << endl; - cout << "info string hash read collisions : " << readCollisions * 100 / totStoreHash << "%" << endl; #endif - ///is a valid move? + bool trace = true; if (abs(sc) > _INFINITE - MAX_PLY) { const bool b = searchManager.getForceCheck(); const u64 oldKey = searchManager.getZobristKey(0); + const int oldEnpassant = searchManager.getEnpassant(0); searchManager.setForceCheck(true); const bool valid = searchManager.makemove(&resultMove); if (!valid) { extension++; trace = false; } - searchManager.takeback(&resultMove, oldKey, true); + searchManager.takeback(&resultMove, oldKey, oldEnpassant, true); searchManager.setForceCheck(b); } if (trace) { - resultMove.s.capturedPiece = searchManager.getPieceAt(resultMove.s.side ^ 1, POW2[resultMove.s.to]); - bestmove = searchManager.decodeBoardinv(resultMove.s.type, resultMove.s.from, resultMove.s.side); - if (!(resultMove.s.type & (KING_SIDE_CASTLE_MOVE_MASK | QUEEN_SIDE_CASTLE_MOVE_MASK))) { - bestmove += searchManager.decodeBoardinv(resultMove.s.type, resultMove.s.to, resultMove.s.side); - if (resultMove.s.promotionPiece != -1) { - bestmove += tolower(FEN_PIECE[(uchar) resultMove.s.promotionPiece]); + resultMove.capturedPiece = searchManager.getPieceAt(X(resultMove.side), POW2(resultMove.to)); + bestmove = searchManager.decodeBoardinv(resultMove.type, resultMove.from, resultMove.side); + if (!(resultMove.type & (KING_SIDE_CASTLE_MOVE_MASK | QUEEN_SIDE_CASTLE_MOVE_MASK))) { + bestmove += searchManager.decodeBoardinv(resultMove.type, resultMove.to, resultMove.side); + if (resultMove.promotionPiece != NO_PROMOTION) { + bestmove += tolower(FEN_PIECE[resultMove.promotionPiece]); } } - if (sc > _INFINITE - MAX_PLY) { - cout << "info depth " << mply << " score mate 1"; - } else { - cout << "info depth " << mply - extension << " score cp " << sc; - } + if (sc > _INFINITE - MAX_PLY) + cout << "info depth " << mply << " score mate " << max(1, (_INFINITE - sc) / 2); + else if (sc < -_INFINITE + MAX_PLY) + cout << "info depth " << mply << " score mate -" << max(1, (_INFINITE + sc) / 2); + else cout << "info depth " << mply - extension << " score cp " << sc; + cout << " time " << timeTaken << " nodes " << totMoves; if (timeTaken)cout << " nps " << (int) ((double) totMoves / (double) timeTaken * 1000.0); cout << " pv " << pvv << endl; @@ -249,29 +208,18 @@ void IterativeDeeping::run() { } } -#ifdef BENCH_MODE - - Times *times = &Times::getInstance(); - times->print(); + BENCH_PRINT() - -#endif - - cout << "bestmove " << bestmove; - if (ponderEnabled && ponderMove.size()) { - cout << " ponder " << ponderMove; - } + if (bestmove.empty())cout << "bestmove (none)"; + else cout << "bestmove " << bestmove; + if (ponderEnabled && ponderMove.size()) cout << " ponder " << ponderMove; cout << endl; ADD(checkSmp2, -1); - ASSERT(!checkSmp2); + assert(!checkSmp2); LOCK_RELEASE(running); } -int IterativeDeeping::loadFen(const string fen) { +int IterativeDeeping::loadFen(const string &fen) { return searchManager.loadFen(fen); } - -bool IterativeDeeping::setNthread(const int i) { - return searchManager.setNthread(i); -} diff --git a/src/IterativeDeeping.h b/src/IterativeDeeping.h index d43f04cc..be8649bb 100644 --- a/src/IterativeDeeping.h +++ b/src/IterativeDeeping.h @@ -20,70 +20,60 @@ #include #include -#include "util/String.h" +#include "namespaces/String.h" #include "SearchManager.h" #include "threadPool/Thread.h" -#include "db/OpenBook.h" #include #include -#include +#include "unistd.h" #include class IterativeDeeping : public Thread { public: - + int ply; IterativeDeeping(); virtual ~ IterativeDeeping(); - string go(); - void run(); void endRun() {}; bool getPonderEnabled() const; - bool getUseBook() const; - - void setUseBook(const bool b); - void enablePonder(const bool); void setMaxDepth(const int); - void loadBook(const string); - - bool setParameter(String param, int value); - - int loadFen(const string fen = ""); - - string getFen() { - return searchManager.getFen(); - } - - bool setNthread(const int i); + int loadFen(const string &fen = ""); int getRunning() const { return running; } +#ifdef JS_MODE + string go() { + run(); + return bestmove; + } +#endif + +#if defined(FULL_TEST) const string &getBestmove() const { return bestmove; } +#endif private: - DEBUG(atomic_int checkSmp2) SearchManager &searchManager = Singleton::getInstance(); int maxDepth; string bestmove; - Hash& hash = Hash::getInstance(); + Hash &hash = Hash::getInstance(); volatile long running; - OpenBook *openBook = nullptr; bool ponderEnabled; }; diff --git a/src/Makefile b/src/Makefile index 83b69a93..eea39f6b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -15,16 +15,14 @@ # along with this program. If not, see . COMP=g++ - ifndef SystemRoot # *nix ifeq ($(shell uname -s),Darwin) LIBS= -static-libstdc++ -lpthread OS=OSX else - LIBS=-s -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -static - PROFILE_USE_THREAD=" -fprofile-correction -fprofile-use " - OS=Linux + LIBS=-s -Wl,--whole-archive -static -lpthread -Wl,--no-whole-archive + OS=Linux endif RM=rm -f @@ -41,7 +39,7 @@ else STRIP=strip.exe endif -CFLAGS=" -std=c++11 -DDLOG_LEVEL=_FATAL -Wall -Ofast -DNDEBUG -fsigned-char -fno-exceptions -fno-rtti -funroll-loops " +CFLAGS=" -std=c++11 -Wall -fno-stack-protector -fno-rtti -fno-exceptions -fomit-frame-pointer -O3 -Wpedantic -W -DNDEBUG -fsigned-char -funroll-loops " help: @@ -61,8 +59,8 @@ help: @echo "make cinnamon-js > Javascript build" @echo "" @echo "add:" - @echo " COMP=compiler > Use another compiler" - @echo " FULL_TEST=yes > Unit test (googletest)" + @echo " COMP=compiler > Use another compiler (default g++)" + @echo " FULL_TEST=yes > Run unit test (googletest)" @echo "" build: @@ -75,29 +73,31 @@ else endif $(STRIP) $(EXE) + @echo "create static library..." + ar rcs libCinnamon.a Bitboard.o board.o ChessBoard.o Uci.o Timer.o WrapperCinnamon.o Search.o IterativeDeeping.o Eval.o GenMoves.o Perft.o Hash.o PerftThread.o SearchManager.o cinnamon-js: - emcc -std=c++11 -w -DJS_MODE -DDLOG_LEVEL=_FATAL util/Bitboard.cpp -fsigned-char namespaces/board.cpp ChessBoard.cpp Eval.cpp Hash.cpp IterativeDeeping.cpp GenMoves.cpp js/main.cpp \ - db/OpenBook.cpp Search.cpp SearchManager.cpp perft/Perft.cpp util/String.cpp util/IniFile.cpp util/Timer.cpp perft/PerftThread.cpp \ + emcc -std=c++11 -w -DNDEBUG -DJS_MODE -DDLOG_LEVEL=_FATAL util/Bitboard.cpp -fsigned-char namespaces/board.cpp ChessBoard.cpp Eval.cpp Hash.cpp IterativeDeeping.cpp GenMoves.cpp js/main.cpp \ + Search.cpp SearchManager.cpp perft/Perft.cpp util/Timer.cpp perft/PerftThread.cpp \ -s WASM=0 -s EXPORTED_FUNCTIONS="['_main','_perft','_command','_isvalid']" -s EXTRA_EXPORTED_RUNTIME_METHODS='["cwrap"]' -s NO_EXIT_RUNTIME=1 -o cinnamon.js -O3 --memory-init-file 0 cinnamon32-generic: - $(MAKE) LIBS="$(LIBS) lib/$(OS)/32/libgtb.a" ARC="$(ARC) -m32" build + $(MAKE) ARC="$(ARC) -m32" build cinnamon32-modern: $(MAKE) ARC="$(ARC) -mfpmath=sse -DHAS_POPCNT -DHAS_BSF" cinnamon32-generic cinnamon32-ARM: - $(MAKE) -j4 LIBS="$(LIBS) lib/ARM/32/libgtb.a" ARC="$(ARC) -DHAS_POPCNT -fno-gcse -DHAS_BSF" build + $(MAKE) -j4 ARC="$(ARC) -DHAS_POPCNT -fno-gcse -DHAS_BSF" build cinnamon64-ARM: - $(MAKE) LIBS="$(LIBS) lib/ARM/64/libgtb.a" ARC="$(ARC) -DHAS_64BIT " build + $(MAKE) -j4 ARC="$(ARC) -DHAS_POPCNT -DHAS_BSF" build cinnamon64-generic: - $(MAKE) -j LIBS="$(LIBS) lib/$(OS)/64/libgtb.a" ARC="$(ARC) -DHAS_64BIT -m64" build + $(MAKE) -j ARC="$(ARC) -m64" build cinnamon64-modern: - $(MAKE) ARC="$(ARC) -DHAS_POPCNT -mpopcnt -msse3 -DHAS_POPCNT -DHAS_BSF " cinnamon64-generic + $(MAKE) ARC="$(ARC) -DHAS_POPCNT -mpopcnt -msse3 -DHAS_BSF " cinnamon64-generic cinnamon64-modern-AMD: $(MAKE) ARC="$(ARC) -msse4a -march=athlon64 " cinnamon64-modern @@ -108,8 +108,8 @@ cinnamon64-modern-INTEL: cinnamon64-BMI2: $(MAKE) ARC="$(ARC) -mbmi2 -DUSE_BMI2 " cinnamon64-modern-INTEL -all: main.o ChessBoard.o board.o Eval.o test.o String.o GenMoves.o WrapperCinnamon.o Bitboard.o Timer.o IniFile.o IterativeDeeping.o Perft.o PerftThread.o Search.o SearchManager.o Hash.o Uci.o OpenBook.o GTB.o SYZYGY.o tbprobe.o - $(COMP) $(ARC) ${CFLAGS} -o ${EXE} main.o test.o ChessBoard.o board.o GenMoves.o WrapperCinnamon.o Bitboard.o Timer.o Eval.o IniFile.o String.o IterativeDeeping.o Perft.o PerftThread.o Search.o SearchManager.o Hash.o Uci.o OpenBook.o GTB.o SYZYGY.o tbprobe.o ${LIBS} +all: main.o ChessBoard.o board.o Eval.o test.o GenMoves.o WrapperCinnamon.o Bitboard.o Timer.o IterativeDeeping.o Perft.o PerftThread.o Search.o SearchManager.o Hash.o Uci.o GTB.o SYZYGY.o tbprobe.o Lzma86Dec.o LzFind.o Lzma86Enc.o Alloc.o LzmaDec.o Bra86.o LzmaEnc.o wrap.o gtb-dec.o gtb-att.o sysport.o gtb-probe.o + $(COMP) $(ARC) ${CFLAGS} -o ${EXE} main.o test.o ChessBoard.o board.o GenMoves.o WrapperCinnamon.o Bitboard.o Timer.o Eval.o IterativeDeeping.o Perft.o PerftThread.o Search.o SearchManager.o Hash.o Uci.o GTB.o SYZYGY.o tbprobe.o Lzma86Dec.o LzFind.o Lzma86Enc.o Alloc.o LzmaDec.o Bra86.o LzmaEnc.o wrap.o gtb-dec.o gtb-att.o sysport.o gtb-probe.o ${LIBS} default: help @@ -150,24 +150,51 @@ GenMoves.o: GenMoves.cpp Hash.o: Hash.cpp $(COMP) -c Hash.cpp ${CFLAGS} ${ARC} -OpenBook.o: db/OpenBook.cpp - $(COMP) -c db/OpenBook.cpp ${CFLAGS} ${ARC} - GTB.o: db/gaviota/GTB.cpp $(COMP) -c db/gaviota/GTB.cpp ${CFLAGS} ${ARC} +Lzma86Dec.o: db/gaviota/gtb/compression/lzma/Lzma86Dec.c + $(COMP) -c db/gaviota/gtb/compression/lzma/Lzma86Dec.c ${CFLAGS} ${ARC} + +LzFind.o: db/gaviota/gtb/compression/lzma/LzFind.c + $(COMP) -c db/gaviota/gtb/compression/lzma/LzFind.c ${CFLAGS} ${ARC} + +Lzma86Enc.o: db/gaviota/gtb/compression/lzma/Lzma86Enc.c + $(COMP) -c db/gaviota/gtb/compression/lzma/Lzma86Enc.c ${CFLAGS} ${ARC} + +LzmaDec.o: db/gaviota/gtb/compression/lzma/LzmaDec.c + $(COMP) -c db/gaviota/gtb/compression/lzma/LzmaDec.c ${CFLAGS} ${ARC} + +Alloc.o: db/gaviota/gtb/compression/lzma/Alloc.c + $(COMP) -c db/gaviota/gtb/compression/lzma/Alloc.c ${CFLAGS} ${ARC} + +Bra86.o: db/gaviota/gtb/compression/lzma/Bra86.c + $(COMP) -c db/gaviota/gtb/compression/lzma/Bra86.c ${CFLAGS} ${ARC} + +LzmaEnc.o: db/gaviota/gtb/compression/lzma/LzmaEnc.c + $(COMP) -c db/gaviota/gtb/compression/lzma/LzmaEnc.c ${CFLAGS} ${ARC} + +wrap.o: db/gaviota/gtb/compression/wrap.c + $(COMP) -c db/gaviota/gtb/compression/wrap.c ${CFLAGS} ${ARC} + +gtb-dec.o: db/gaviota/gtb/gtb-dec.c + $(COMP) -c db/gaviota/gtb/gtb-dec.c ${CFLAGS} ${ARC} + +gtb-att.o: db/gaviota/gtb/gtb-att.c + $(COMP) -c db/gaviota/gtb/gtb-att.c ${CFLAGS} ${ARC} + +sysport.o: db/gaviota/gtb/sysport/sysport.c + $(COMP) -c db/gaviota/gtb/sysport/sysport.c ${CFLAGS} ${ARC} + +gtb-probe.o: db/gaviota/gtb/gtb-probe.c + $(COMP) -c db/gaviota/gtb/gtb-probe.c ${CFLAGS} ${ARC} + SYZYGY.o: db/syzygy/SYZYGY.cpp $(COMP) -c db/syzygy/SYZYGY.cpp ${CFLAGS} ${ARC} tbprobe.o: db/syzygy/tbprobe.c $(COMP) -c db/syzygy/tbprobe.c ${CFLAGS} ${ARC} -String.o: util/String.cpp - $(COMP) -c util/String.cpp ${CFLAGS} ${ARC} - -IniFile.o: util/IniFile.cpp - $(COMP) -c util/IniFile.cpp ${CFLAGS} ${ARC} - Timer.o: util/Timer.cpp $(COMP) -c util/Timer.cpp ${CFLAGS} ${ARC} @@ -181,5 +208,5 @@ WrapperCinnamon.o: WrapperCinnamon.cpp $(COMP) -c WrapperCinnamon.cpp ${CFLAGS} ${ARC} clean: - $(RM) *.o $(EXE) cinnamon.js + $(RM) *.o $(EXE) cinnamon.js libCinnamon.a diff --git a/src/Search.cpp b/src/Search.cpp index ea0a08c1..1738fce0 100644 --- a/src/Search.cpp +++ b/src/Search.cpp @@ -16,14 +16,12 @@ along with this program. If not, see . */ - #include "Search.h" -#include "SearchManager.h" -#include "db/bitbase/kpk.h" bool volatile Search::runningThread; high_resolution_clock::time_point Search::startTime; -using namespace _bitbase; + +DEBUG(unsigned Search::cumulativeMovesCount) void Search::run() { if (getRunning()) { @@ -40,26 +38,26 @@ void Search::aspirationWindow(const int depth, const int valWin) { init(); if (depth == 1) { - valWindow = search(depth, -_INFINITE - 1, _INFINITE + 1); + valWindow = searchRoot(depth, -_INFINITE - 1, _INFINITE + 1); } else { - int tmp = search(mainDepth, valWindow - VAL_WINDOW, valWindow + VAL_WINDOW); + int tmp = searchRoot(mainDepth, valWindow - VAL_WINDOW, valWindow + VAL_WINDOW); if (tmp <= valWindow - VAL_WINDOW || tmp >= valWindow + VAL_WINDOW) { if (tmp <= valWindow - VAL_WINDOW) { - tmp = search(mainDepth, valWindow - VAL_WINDOW * 2, valWindow + VAL_WINDOW); + tmp = searchRoot(mainDepth, valWindow - VAL_WINDOW * 2, valWindow + VAL_WINDOW); } else { - tmp = search(mainDepth, valWindow - VAL_WINDOW, valWindow + VAL_WINDOW * 2); + tmp = searchRoot(mainDepth, valWindow - VAL_WINDOW, valWindow + VAL_WINDOW * 2); } if (tmp <= valWindow - VAL_WINDOW || tmp >= valWindow + VAL_WINDOW) { if (tmp <= valWindow - VAL_WINDOW) { - tmp = search(mainDepth, valWindow - VAL_WINDOW * 4, valWindow + VAL_WINDOW); + tmp = searchRoot(mainDepth, valWindow - VAL_WINDOW * 4, valWindow + VAL_WINDOW); } else { - tmp = search(mainDepth, valWindow - VAL_WINDOW, valWindow + VAL_WINDOW * 4); + tmp = searchRoot(mainDepth, valWindow - VAL_WINDOW, valWindow + VAL_WINDOW * 4); } if (tmp <= valWindow - VAL_WINDOW || tmp >= valWindow + VAL_WINDOW) { - tmp = search(mainDepth, -_INFINITE - 1, _INFINITE + 1); + tmp = searchRoot(mainDepth, -_INFINITE - 1, _INFINITE + 1); } } } @@ -71,7 +69,7 @@ void Search::aspirationWindow(const int depth, const int valWin) { Search::Search() : ponder(false), nullSearch(false) { - DEBUG(lazyEvalCuts = cumulativeMovesCount = totGen = 0) + DEBUG(eval.lazyEvalCuts = cumulativeMovesCount = totGen = 0) } @@ -83,24 +81,23 @@ void Search::clone(const Search *s) { int Search::SZtbProbeWDL() const { const auto tot = bitCount(board::getBitmap(chessboard) | board::getBitmap(chessboard)); - const int side = board::getSide(chessboard); - return syzygy->SZtbProbeWDL(chessboard, side, tot); + return syzygy->SZtbProbeWDL(chessboard, sideToMove, tot); } void Search::printWdlSyzygy() { perftMode = true; - const int side = board::getSide(chessboard); - u64 friends = side == WHITE ? board::getBitmap(chessboard) : board::getBitmap(chessboard); - u64 enemies = side == BLACK ? board::getBitmap(chessboard) : board::getBitmap(chessboard); + u64 friends = sideToMove == WHITE ? board::getBitmap(chessboard) : board::getBitmap(chessboard); + u64 enemies = sideToMove == BLACK ? board::getBitmap(chessboard) : board::getBitmap(chessboard); incListId(); - generateCaptures(side, enemies, friends); - generateMoves(side, friends | enemies); + generateCaptures(sideToMove, enemies, friends); + generateMoves(sideToMove, friends | enemies); _Tmove *move; u64 oldKey = chessboard[ZOBRISTKEY_IDX]; + uchar oldEnpassant = enPassant; display(); - unsigned res = syzygy->SZtbProbeWDL(chessboard, side); + unsigned res = syzygy->SZtbProbeWDL(chessboard, sideToMove); cout << "current: "; if (res != TB_RESULT_FAILED) { res = TB_GET_WDL(res); @@ -114,14 +111,14 @@ void Search::printWdlSyzygy() { cout << " none" << endl; for (int i = 0; i < getListSize(); i++) { - move = &gen_list[listId].moveList[i]; + move = &genList[listId].moveList[i]; if (!makemove(move, false, true)) { - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); continue; } - print(move, chessboard); + print(move); - unsigned res = syzygy->SZtbProbeWDL(chessboard, side ^ 1); + unsigned res = syzygy->SZtbProbeWDL(chessboard, X(sideToMove)); if (res != TB_RESULT_FAILED) { res = TB_GET_WDL(res); @@ -133,7 +130,7 @@ void Search::printWdlSyzygy() { } else cout << " none" << endl; - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); } cout << endl; decListId(); @@ -141,9 +138,8 @@ void Search::printWdlSyzygy() { void Search::printDtzSyzygy() { perftMode = true; - const int side = board::getSide(chessboard); - if ((side == BLACK) ? board::inCheck1(chessboard) : board::inCheck1(chessboard)) { + if ((sideToMove == BLACK) ? board::inCheck1(chessboard) : board::inCheck1(chessboard)) { cout << "invalid position" << endl; return; } @@ -153,7 +149,7 @@ void Search::printDtzSyzygy() { const u64 white = board::getBitmap(chessboard); const u64 black = board::getBitmap(chessboard); - unsigned res = syzygy->SZtbProbeWDL(chessboard, side); + unsigned res = syzygy->SZtbProbeWDL(chessboard, sideToMove); display(); cout << "current: "; if (res != TB_RESULT_FAILED) { @@ -167,7 +163,7 @@ void Search::printDtzSyzygy() { } else cout << " none" << endl; - const unsigned res1 = syzygy->SZtbProbeRoot(white, black, chessboard, side, results); + const unsigned res1 = syzygy->SZtbProbeRoot(white, black, chessboard, sideToMove, results); if (res1 != TB_RESULT_FAILED) { for (unsigned i = 0; results[i] != TB_RESULT_FAILED; i++) { @@ -199,30 +195,30 @@ void Search::printDtzSyzygy() { int Search::printDtmWdlGtb(const bool dtm) { perftMode = true; - int side = board::getSide(chessboard); - u64 friends = side == WHITE ? board::getBitmap(chessboard) : board::getBitmap(chessboard); - u64 enemies = side == BLACK ? board::getBitmap(chessboard) : board::getBitmap(chessboard); + + u64 friends = sideToMove == WHITE ? board::getBitmap(chessboard) : board::getBitmap(chessboard); + u64 enemies = sideToMove == BLACK ? board::getBitmap(chessboard) : board::getBitmap(chessboard); display(); cout << "current: "; unsigned pliestomate; - const int res = GTB::getInstance().getDtmWdl(GTB_STM(side), 2, chessboard, &pliestomate, dtm); + const int res = GTB::getInstance().getDtmWdl(GTB_STM(sideToMove), 2, chessboard, &pliestomate, dtm, rightCastle); incListId(); - generateCaptures(side, enemies, friends); - generateMoves(side, friends | enemies); + generateCaptures(sideToMove, enemies, friends); + generateMoves(sideToMove, friends | enemies); _Tmove *move; u64 oldKey = chessboard[ZOBRISTKEY_IDX]; - + uchar oldEnpassant = enPassant; for (int i = 0; i < getListSize(); i++) { - move = &gen_list[listId].moveList[i]; + move = &genList[listId].moveList[i]; if (!makemove(move, false, true)) { - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); continue; } - print(move, chessboard); + print(move); - GTB::getInstance().getDtmWdl(GTB_STM(side ^ 1), 1, chessboard, &pliestomate, dtm); + GTB::getInstance().getDtmWdl(GTB_STM(X(sideToMove)), 1, chessboard, &pliestomate, dtm, rightCastle); - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); } cout << endl; @@ -232,7 +228,7 @@ int Search::printDtmWdlGtb(const bool dtm) { #endif -void Search::setNullMove(bool b) { +void Search::setNullMove(const bool b) { nullSearch = !b; } @@ -240,8 +236,9 @@ void Search::startClock() { startTime = std::chrono::high_resolution_clock::now(); } -void Search::setMainPly(const int m) { - mainDepth = m; +void Search::setMainPly(const int ply, const int mply) { + mainDepth = mply; + this->ply = ply; } int Search::checkTime() const { @@ -259,48 +256,33 @@ Search::~Search() { join(); } -template -int Search::quiescence(int alpha, const int beta, const char promotionPiece, const int depth) { - - if (!getRunning()) return 0; - +template +int Search::qsearch(int alpha, const int beta, const uchar promotionPiece, const int depth) { const u64 zobristKeyR = chessboard[ZOBRISTKEY_IDX] ^_random::RANDSIDE[side]; - int score = getScore(zobristKeyR, side, alpha, beta, false); - if (score >= beta) { - return beta; - } - ///************* hash **************** - char hashf = Hash::hashfALPHA; - - pair hashAlwaysItem = checkHash(Hash::HASH_ALWAYS, true, alpha, beta, depth, zobristKeyR); - if (hashAlwaysItem.first != INT_MAX) { - return hashAlwaysItem.first; - } + if (!getRunning()) return 0; - pair hashGreaterItem = checkHash(Hash::HASH_GREATER, true, alpha, beta, depth, zobristKeyR); - if (hashGreaterItem.first != INT_MAX) { - return hashGreaterItem.first; + ++numMovesq; + int score = eval.getScore(chessboard, zobristKeyR, side, alpha, beta); + if (score > alpha) { + if (score >= beta) return score; + alpha = score; } -///********** end hash *************** -/**************Delta Pruning ****************/ - char fprune = 0; + /// **************Delta Pruning **************** + bool fprune = false; int fscore; if ((fscore = score + (promotionPiece == NO_PROMOTION ? VALUEQUEEN : 2 * VALUEQUEEN)) < alpha) { - fprune = 1; - } -/************ end Delta Pruning *************/ - if (score > alpha) { - alpha = score; + fprune = true; } + /// ************ end Delta Pruning ************* + if (score > alpha) alpha = score; incListId(); u64 friends = board::getBitmap(chessboard); - u64 enemies = board::getBitmap(chessboard); + u64 enemies = board::getBitmap(chessboard); if (generateCaptures(enemies, friends)) { decListId(); - return _INFINITE - (mainDepth + depth); } if (!getListSize()) { @@ -308,60 +290,49 @@ int Search::quiescence(int alpha, const int beta, const char promotionPiece, con return score; } _Tmove *move; - _Tmove *best = &gen_list[listId].moveList[0]; const u64 oldKey = chessboard[ZOBRISTKEY_IDX]; - Hash::_ThashData *c = nullptr; - if (hashAlwaysItem.second.phasheType[Hash::HASH_ALWAYS].dataS.flags & 0x3) { - c = &hashAlwaysItem.second.phasheType[Hash::HASH_ALWAYS]; - } else if (hashGreaterItem.second.phasheType[Hash::HASH_GREATER].dataS.flags & 0x3) { - c = &hashGreaterItem.second.phasheType[Hash::HASH_GREATER]; - } + uchar oldEnpassant = enPassant; int first = 0; if (!(numMoves % 2048)) setRunning(checkTime()); - while ((move = getNextMove(&gen_list[listId], depth, c, first++))) { + while ((move = getNextMoveQ(&genList[listId], first++))) { if (!makemove(move, false, true)) { - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); continue; } -/**************Delta Pruning ****************/ - if (fprune && ((move->s.type & 0x3) != PROMOTION_MOVE_MASK) && - fscore + PIECES_VALUE[move->s.capturedPiece] <= alpha) { + + if (badCapure(*move, friends | enemies)) { + INC(nCutBadCaputure); + takeback(move, oldKey, oldEnpassant, false); + continue; + } + /// **************Delta Pruning **************** + if (fprune && ((move->type & 0x3) != PROMOTION_MOVE_MASK) && + fscore + PIECES_VALUE[move->capturedPiece] <= alpha) { INC(nCutFp); - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); continue; } -/************ end Delta Pruning *************/ - int val = -quiescence(-beta, -alpha, move->s.promotionPiece, depth - 1); + /// ************ end Delta Pruning ************* + int val = -qsearch(-beta, -alpha, move->promotionPiece, depth - 1); score = max(score, val); - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); if (score > alpha) { if (score >= beta) { decListId(); - if (getRunning()) { - Hash::_ThashData data(score, depth, move->s.from, move->s.to, 0, Hash::hashfBETA); - hash.recordHash(zobristKeyR, data); - } return beta; } - best = move; alpha = score; - hashf = Hash::hashfEXACT; } } - if (getRunning()) { - Hash::_ThashData data(score, depth, best->s.from, best->s.to, 0, hashf); - hash.recordHash(zobristKeyR, data); - } decListId(); - return score; } -void Search::setPonder(bool r) { +void Search::setPonder(const bool r) { ponder = r; } -void Search::setRunning(int r) { +void Search::setRunning(const int r) { GenMoves::setRunning(r); if (!r) { maxTimeMillsec = 0; @@ -371,10 +342,9 @@ void Search::setRunning(int r) { int Search::getRunning() const { if (!runningThread)return 0; return GenMoves::getRunning(); - } -void Search::setMaxTimeMillsec(int n) { +void Search::setMaxTimeMillsec(const int n) { maxTimeMillsec = n; } @@ -382,7 +352,7 @@ int Search::getMaxTimeMillsec() const { return maxTimeMillsec; } -bool Search::checkDraw(u64 key) { +bool Search::checkDraw(const u64 key) { int o = 0; int count = 0; for (int i = repetitionMapCount - 1; i >= 0; i--) { @@ -409,94 +379,50 @@ void Search::setMainParam(const int depth) { } template -int Search::search(const int depth, const int alpha, const int beta) { +int Search::searchRoot(const int depth, const int alpha, const int beta) { ASSERT_RANGE(depth, 0, MAX_PLY) - auto ep = chessboard[ENPASSANT_IDX]; + auto ep = enPassant; incListId(); - const int side = board::getSide(chessboard); - const u64 friends = (side == WHITE) ? board::getBitmap(chessboard) : board::getBitmap(chessboard); - const u64 enemies = (side == WHITE) ? board::getBitmap(chessboard) : board::getBitmap(chessboard); - generateCaptures(side, enemies, friends); - generateMoves(side, friends | enemies); + + const u64 friends = (sideToMove == WHITE) ? board::getBitmap(chessboard) : board::getBitmap( + chessboard); + const u64 enemies = (sideToMove == WHITE) ? board::getBitmap(chessboard) : board::getBitmap( + chessboard); + generateCaptures(sideToMove, enemies, friends); + generateMoves(sideToMove, friends | enemies); int n_root_moves = getListSize(); decListId(); - chessboard[ENPASSANT_IDX] = ep; - return board::getSide(chessboard) ? search(depth, - alpha, - beta, - &pvLine, - bitCount(board::getBitmap(chessboard) | - board::getBitmap(chessboard)), - n_root_moves) - : search(depth, alpha, beta, &pvLine, - bitCount(board::getBitmap(chessboard) | - board::getBitmap(chessboard)), - n_root_moves); + enPassant = ep; + return sideToMove ? search(depth, + alpha, + beta, + &pvLine, + bitCount(board::getBitmap(chessboard) | + board::getBitmap(chessboard)), + n_root_moves) + : search(depth, alpha, beta, &pvLine, + bitCount(board::getBitmap(chessboard) | + board::getBitmap(chessboard)), + n_root_moves); } bool Search::probeRootTB(_Tmove *res) { const u64 white = board::getBitmap(chessboard); const u64 black = board::getBitmap(chessboard); const auto tot = bitCount(white | black); - const int side = board::getSide(chessboard); const u64 oldKey = chessboard[ZOBRISTKEY_IDX]; + uchar oldEnpassant = enPassant; - if (tot == 3 && (chessboard[WHITE] || chessboard[BLACK])) { - _Tmove *bestMove = nullptr; - u64 friends = side == WHITE ? white : black; - u64 enemies = side == BLACK ? white : black; - - incListId(); - generateCaptures(side, enemies, friends); - generateMoves(side, friends | enemies); - - for (int i = 0; i < getListSize(); i++) { - if (bestMove)break; - _Tmove *move = &gen_list[listId].moveList[i]; - if (!makemove(move, false, true)) { - takeback(move, oldKey, false); - continue; - } - - const int kw = BITScanForward(chessboard[KING_WHITE]); - const int kb = BITScanForward(chessboard[KING_BLACK]); - const int pawnQueenPos = BITScanForward(chessboard[PAWN_BLACK]) | BITScanForward(chessboard[PAWN_WHITE]) | - BITScanForward(chessboard[QUEEN_BLACK]) | BITScanForward(chessboard[QUEEN_WHITE]); - const int winSide = chessboard[PAWN_BLACK] | chessboard[QUEEN_BLACK] ? BLACK : WHITE; - - bool p; - - if (winSide != side) { // looking for draw - p = isDraw(winSide, side ^ 1, kw, kb, pawnQueenPos); - } else { //looking for win - p = !isDraw(winSide, side ^ 1, kw, kb, pawnQueenPos); - } - if (p && - (bestMove == nullptr || move->s.capturedPiece != SQUARE_EMPTY || - move->s.promotionPiece != NO_PROMOTION)) { - bestMove = move; - } - takeback(move, oldKey, false); - } - - decListId(); - if (bestMove) { - memcpy(res, bestMove, sizeof(_Tmove)); - if (res->s.pieceFrom == PAWN_WHITE && res->s.to > 55)res->s.promotionPiece = 'q'; - else if (res->s.pieceFrom == PAWN_BLACK && res->s.to < 8)res->s.promotionPiece = 'q'; - return true; - } - } #ifndef JS_MODE //gaviota if (GTB::getInstance().isInstalledPieces(tot)) { - u64 friends = side == WHITE ? white : black; - u64 enemies = side == BLACK ? white : black; + u64 friends = sideToMove == WHITE ? white : black; + u64 enemies = sideToMove == BLACK ? white : black; _Tmove *bestMove = nullptr; incListId(); - generateCaptures(side, enemies, friends); - generateMoves(side, friends | enemies); + generateCaptures(sideToMove, enemies, friends); + generateMoves(sideToMove, friends | enemies); _Tmove *drawMove = nullptr; _Tmove *worstMove = nullptr; @@ -509,41 +435,42 @@ bool Search::probeRootTB(_Tmove *res) { unsigned dtz; for (int i = 0; i < getListSize(); i++) { - _Tmove *move = &gen_list[listId].moveList[i]; + _Tmove *move = &genList[listId].moveList[i]; if (!makemove(move, false, true)) { - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); continue; } - BENCH(times->start("gtbTime")) - const auto res = GTB::getInstance().getDtmWdl(GTB_STM(side ^ 1), 0, chessboard, &dtz, true); - BENCH(times->stop("gtbTime")) + BENCH_START("gtbTime") + const auto res = GTB::getInstance().getDtmWdl(GTB_STM(X(sideToMove)), 0, chessboard, &dtz, true, + rightCastle); + BENCH_STOP("gtbTime") if (res == TB_WIN && !worstMove && !drawMove) { if ((int) dtz > minDtz) { bestMove = move; minDtz = dtz; - if (move->s.promotionPiece != NO_PROMOTION || board::isOccupied(move->s.to, allPieces)) + if (move->promotionPiece != NO_PROMOTION || board::isOccupied(move->to, allPieces)) minDtz++; } } else if (res == TB_DRAW) { - if (!drawMove || (move->s.promotionPiece != NO_PROMOTION || board::isOccupied(move->s.to, allPieces))) { + if (!drawMove || (move->promotionPiece != NO_PROMOTION || board::isOccupied(move->to, allPieces))) { drawMove = move; } } else if (res == TB_LOSS) { if ((int) dtz < (int) maxDtzWorst) { worstMove = move; maxDtzWorst = dtz; - if (move->s.promotionPiece != NO_PROMOTION || board::isOccupied(move->s.to, allPieces)) + if (move->promotionPiece != NO_PROMOTION || board::isOccupied(move->to, allPieces)) maxDtzWorst--; } } - takeback(move, oldKey, false); + takeback(move, oldKey, oldEnpassant, false); } if (worstMove) { debug("worstMove ***********\n") memcpy(res, worstMove, sizeof(_Tmove)); - if (res->s.promotionPiece != NO_PROMOTION) - res->s.promotionPiece = FEN_PIECE[res->s.promotionPiece]; + if (res->promotionPiece != NO_PROMOTION) + res->promotionPiece = FEN_PIECE[res->promotionPiece]; decListId(); return true; } @@ -551,15 +478,15 @@ bool Search::probeRootTB(_Tmove *res) { if (drawMove) { debug("drawMove ***********\n") memcpy(res, drawMove, sizeof(_Tmove)); - if (res->s.promotionPiece != NO_PROMOTION)res->s.promotionPiece = FEN_PIECE[res->s.promotionPiece]; + if (res->promotionPiece != NO_PROMOTION)res->promotionPiece = FEN_PIECE[res->promotionPiece]; decListId(); return true; } if (bestMove) { debug("best ***********\n") memcpy(res, bestMove, sizeof(_Tmove)); - if (res->s.promotionPiece != NO_PROMOTION) - res->s.promotionPiece = FEN_PIECE[res->s.promotionPiece]; + if (res->promotionPiece != NO_PROMOTION) + res->promotionPiece = FEN_PIECE[res->promotionPiece]; decListId(); return true; } @@ -582,9 +509,9 @@ bool Search::probeRootTB(_Tmove *res) { unsigned results[TB_MAX_MOVES]; const u64 allPieces = white | black; - BENCH(times->start("syzygyTime")) - const auto sz = syzygy->SZtbProbeRoot(white, black, chessboard, side, results); - BENCH(times->stop("syzygyTime")) + BENCH_START("syzygyTime") + const auto sz = syzygy->SZtbProbeRoot(white, black, chessboard, sideToMove, results); + BENCH_STOP("syzygyTime") if (sz == TB_RESULT_FAILED) return false; for (unsigned i = 0; results[i] != TB_RESULT_FAILED; i++) { @@ -631,41 +558,41 @@ bool Search::probeRootTB(_Tmove *res) { } } - res->s.type = STANDARD_MOVE_MASK; + res->type = STANDARD_MOVE_MASK; if (bestMove) { debug("best ***********\n") - res->s.from = _decodeSquare[TB_GET_FROM(bestMove)]; - res->s.to = _decodeSquare[TB_GET_TO(bestMove)]; - res->s.promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(bestMove)); + res->from = _decodeSquare[TB_GET_FROM(bestMove)]; + res->to = _decodeSquare[TB_GET_TO(bestMove)]; + res->promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(bestMove)); return true; } if (bestMove50) { debug("bestMove50 ***********\n") - res->s.from = _decodeSquare[TB_GET_FROM(bestMove50)]; - res->s.to = _decodeSquare[TB_GET_TO(bestMove50)]; - res->s.promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(bestMove50)); + res->from = _decodeSquare[TB_GET_FROM(bestMove50)]; + res->to = _decodeSquare[TB_GET_TO(bestMove50)]; + res->promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(bestMove50)); return true; } if (drawMove) { debug("drawMove ***********\n") - res->s.from = _decodeSquare[TB_GET_FROM(drawMove)]; - res->s.to = _decodeSquare[TB_GET_TO(drawMove)]; - res->s.promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(drawMove)); + res->from = _decodeSquare[TB_GET_FROM(drawMove)]; + res->to = _decodeSquare[TB_GET_TO(drawMove)]; + res->promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(drawMove)); return true; } if (worstMove50) { debug("worstMove50 ***********\n") - res->s.from = _decodeSquare[TB_GET_FROM(worstMove50)]; - res->s.to = _decodeSquare[TB_GET_TO(worstMove50)]; - res->s.promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(worstMove50)); + res->from = _decodeSquare[TB_GET_FROM(worstMove50)]; + res->to = _decodeSquare[TB_GET_TO(worstMove50)]; + res->promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(worstMove50)); return true; } if (worstMove) { debug("worstMove ***********\n") - res->s.from = _decodeSquare[TB_GET_FROM(worstMove)]; - res->s.to = _decodeSquare[TB_GET_TO(worstMove)]; - res->s.promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(worstMove)); + res->from = _decodeSquare[TB_GET_FROM(worstMove)]; + res->to = _decodeSquare[TB_GET_TO(worstMove)]; + res->promotionPiece = SYZYGY::getPromotion(TB_GET_PROMOTES(worstMove)); return true; } return false; @@ -675,9 +602,9 @@ bool Search::probeRootTB(_Tmove *res) { } template -bool Search::checkSearchMoves(_Tmove *move) const { +bool Search::checkSearchMoves(const _Tmove *move) const { if (!checkMoves)return true; - int m = move->s.to | (move->s.from << 8); + int m = move->to | (move->from << 8); if (std::find(searchMovesVector.begin(), searchMovesVector.end(), m) != searchMovesVector.end()) { return true; } @@ -686,7 +613,7 @@ bool Search::checkSearchMoves(_Tmove *move) const { #ifndef JS_MODE -int Search::probeWdl(const int depth, const int side, const int N_PIECE) { +int Search::probeWdl(const int depth, const uchar side, const int N_PIECE) { // if (N_PIECE == 3 && depth > 2 && depth != mainDepth && (board[WHITE] || board[BLACK])) { // const int kw = BITScanForward(board[KING_WHITE]); @@ -713,9 +640,9 @@ int Search::probeWdl(const int depth, const int side, const int N_PIECE) { unsigned pliestomate; //gaviota if (GTB::getInstance().isInstalledPieces(N_PIECE)) { - BENCH(times->start("gtbTime")) - tbResult = GTB::getInstance().getDtmWdl(GTB_STM(side), 0, chessboard, &pliestomate, false); - BENCH(times->stop("gtbTime")) + BENCH_START("gtbTime") + tbResult = GTB::getInstance().getDtmWdl(GTB_STM(side), 0, chessboard, &pliestomate, false, rightCastle); + BENCH_STOP("gtbTime") } switch (tbResult) { case TB_LOSS : @@ -733,83 +660,85 @@ int Search::probeWdl(const int depth, const int side, const int N_PIECE) { #endif -template -int Search::search(int depth, int alpha, const int beta, _TpvLine *pline, const int N_PIECE, - const int n_root_moves) { - ASSERT_RANGE(depth, 0, MAX_PLY); - ASSERT_RANGE(side, 0, 1); - if (!getRunning()) return 0; +template +int Search::search(const int depth, int alpha, const int beta, _TpvLine *pline, const int N_PIECE, + const int nRootMoves) { + ASSERT_RANGE(side, 0, 1) + if (!getRunning()) return 0; + u64 oldKey = chessboard[ZOBRISTKEY_IDX]; + uchar oldEnpassant = enPassant; + if (depth >= MAX_PLY - 1) { + return eval.getScore(chessboard, oldKey, side, alpha, beta); + } INC(cumulativeMovesCount); #ifndef JS_MODE int wdl = probeWdl(depth, side, N_PIECE); if (wdl != INT_MAX) return wdl; #endif - u64 oldKey = chessboard[ZOBRISTKEY_IDX]; int score = -_INFINITE; - const int pvNode = alpha != beta - 1; - + const bool pvNode = alpha != beta - 1; - DEBUG(double betaEfficiencyCount = 0.0) + assert(chessboard[KING_BLACK]); + assert(chessboard[KING_WHITE]); - ASSERT(chessboard[KING_BLACK]) - ASSERT(chessboard[KING_WHITE]) - - int extension = 0; - const int is_incheck_side = board::inCheck1(chessboard); - if (!is_incheck_side && depth != mainDepth) { + const bool isIncheckSide = board::inCheck1(chessboard); + if (!isIncheckSide && depth != mainDepth) { if (board::checkInsufficientMaterial(N_PIECE, chessboard) || checkDraw(chessboard[ZOBRISTKEY_IDX])) { - if (board::inCheck1(chessboard)) { + if (board::inCheck1(chessboard)) { return _INFINITE - (mainDepth - depth + 1); } - return -lazyEval() * 2; + return -eval.lazyEval(chessboard) * 2; } } - if (is_incheck_side) { - extension++; - } - depth += extension; - if (depth == 0) { - return quiescence(alpha, beta, -1, 0); + int extension = isIncheckSide; + if (depth + extension == 0) { + return qsearch(alpha, beta, NO_PROMOTION, 0); } - //************* hash **************** - u64 zobristKeyR = chessboard[ZOBRISTKEY_IDX] ^_random::RANDSIDE[side]; - - pair hashGreaterItem = checkHash(Hash::HASH_GREATER, false, alpha, beta, depth, zobristKeyR); - if (hashGreaterItem.first != INT_MAX) { - return hashGreaterItem.first; + /// ************* hash **************** + const u64 zobristKeyR = chessboard[ZOBRISTKEY_IDX] ^_random::RANDSIDE[side]; + u64 hashItem; + const int hashValue = hash.readHash(alpha, beta, depth, zobristKeyR, hashItem, currentPly); + if (hashValue != INT_MAX) { + return hashValue; } - pair hashAlwaysItem = checkHash(Hash::HASH_ALWAYS, false, alpha, beta, depth, zobristKeyR); - if (hashAlwaysItem.first != INT_MAX) { - return hashAlwaysItem.first; - } - ///********** end hash *************** + /// ********** end hash *************** if (!(numMoves % 2048)) setRunning(checkTime()); - ++numMoves; _TpvLine line; line.cmove = 0; - // ********* null move *********** - if (!nullSearch && !pvNode && !is_incheck_side) { - int n_depth = (n_root_moves > 17 || depth > 3) ? 1 : 3; - if (n_depth == 3) { + /// ********* null move *********** + if (!nullSearch && !pvNode && !isIncheckSide) { + int nDepth = (nRootMoves > 17 || depth > 3) ? 1 : 3; + if (nDepth == 3) { const u64 pieces = board::getPiecesNoKing(chessboard); if (pieces != chessboard[PAWN_BLACK + side] || bitCount(pieces) > 9) - n_depth = 1; + nDepth = 1; } - if (depth > n_depth) { + if (depth > nDepth) { nullSearch = true; const int R = NULL_DEPTH + depth / NULL_DIVISOR; - const int nullScore = - (depth - R - 1 > 0) ? - -search(depth - R - 1, -beta, -beta + 1, &line, N_PIECE, n_root_moves) - : - -quiescence(-beta, -beta + 1, -1, 0); + int nullScore; + if (depth - R - 1 > 0) { + nullScore = -search(depth + extension - R - 1, -beta, -beta + 1, &line, N_PIECE, + nRootMoves); + if (!forceCheck && abs(nullScore) > _INFINITE - MAX_PLY) { + currentPly++; + forceCheck = true; + nullScore = -search(depth + extension - R - 1, -beta, -beta + 1, &line, + N_PIECE, + nRootMoves); + forceCheck = false; + currentPly--; + } + } else { + nullScore = -qsearch(-beta, -beta + 1, -1, 0); + } nullSearch = false; if (nullScore >= beta) { INC(nNullMoveCut); @@ -818,138 +747,163 @@ int Search::search(int depth, int alpha, const int beta, _TpvLine *pline, const } } - ///******* null move end ******** + /// ******* null move end ******** - /**************Futility Pruning****************/ - /**************Futility Pruning razor at pre-pre-frontier*****/ + /// ********************** Futility Pruning ********************* + /// ************* Futility Pruning razor at pre-pre-frontier **** bool futilPrune = false; int futilScore = 0; - if (depth <= 3 && !is_incheck_side) { - int matBalance = lazyEval(); - if ((futilScore = matBalance + FUTIL_MARGIN) <= alpha) { - if (depth == 3 && (matBalance + RAZOR_MARGIN) <= alpha && - board::getNpiecesNoPawnNoKing(chessboard) > 3) { + if (depth <= 3 && !isIncheckSide) { + const int matBalance = eval.lazyEval(chessboard); + /// ******** reverse futility pruning *********** + if (depth < 3 && !pvNode && abs(beta - 1) > -_INFINITE + MAX_PLY) { + const int evalMargin = matBalance - eval.REVERSE_FUTIL_MARGIN * depth; + if (evalMargin >= beta) return evalMargin; + } + /// ********************************************* + if ((futilScore = matBalance + eval.FUTIL_MARGIN) <= alpha) { + if (depth == 3 && (matBalance + eval.RAZOR_MARGIN) <= alpha && + bitCount(board::getBitmapNoPawnsNoKing(chessboard)) > 3) { INC(nCutRazor); - depth--; + extension--; } else - ///**************Futility Pruning at pre-frontier***** - if (depth == 2 && (futilScore = matBalance + EXT_FUTILY_MARGIN) <= alpha) { + /// **************Futility Pruning at pre-frontier***** + if (depth == 2 && (futilScore = matBalance + eval.EXT_FUTIL_MARGIN) <= alpha) { futilPrune = true; score = futilScore; } else - ///**************Futility Pruning at frontier***** + /// **************Futility Pruning at frontier***** if (depth == 1) { futilPrune = true; score = futilScore; } } } - /************ end Futility Pruning*************/ + /// ************ end Futility Pruning************* incListId(); - ASSERT_RANGE(KING_BLACK + side, 0, 11); - ASSERT_RANGE(KING_BLACK + (side ^ 1), 0, 11); + ASSERT_RANGE(KING_BLACK + side, 0, 11) + ASSERT_RANGE(KING_BLACK + (X(side)), 0, 11) const u64 friends = board::getBitmap(chessboard); - const u64 enemies = board::getBitmap(chessboard); + const u64 enemies = board::getBitmap(chessboard); if (generateCaptures(enemies, friends)) { decListId(); - score = _INFINITE - (mainDepth - depth + 1); - return score; + return _INFINITE - (mainDepth - depth + 1); } generateMoves(friends | enemies); const int listcount = getListSize(); if (!listcount) { --listId; - if (is_incheck_side) { + if (isIncheckSide) { return -_INFINITE + (mainDepth - depth + 1); } else { - return -lazyEval() * 2; + return -eval.lazyEval(chessboard) * 2; } } - ASSERT(gen_list[listId].size > 0) - Hash::_ThashData *c = nullptr; - _Tmove *best = &gen_list[listId].moveList[0]; - if (hashGreaterItem.second.phasheType[Hash::HASH_GREATER].dataS.flags & 0x3) { - c = &hashGreaterItem.second.phasheType[Hash::HASH_GREATER]; - } else if (hashAlwaysItem.second.phasheType[Hash::HASH_ALWAYS].dataS.flags & 0x3) { - c = &hashAlwaysItem.second.phasheType[Hash::HASH_ALWAYS]; - } + assert(genList[listId].size > 0); + + _Tmove *best = &genList[listId].moveList[0]; + INC(totGen); _Tmove *move; bool checkInCheck = false; int countMove = 0; char hashf = Hash::hashfALPHA; int first = 0; - while ((move = getNextMove(&gen_list[listId], depth, c, first++))) { + while ((move = getNextMove(&genList[listId], depth, hashItem, first++))) { if (!checkSearchMoves(move) && depth == mainDepth) continue; countMove++; - INC(betaEfficiencyCount); + if (!makemove(move, true, checkInCheck)) { - takeback(move, oldKey, true); + takeback(move, oldKey, oldEnpassant, true); continue; } checkInCheck = true; - if (futilPrune && ((move->s.type & 0x3) != PROMOTION_MOVE_MASK) && - futilScore + PIECES_VALUE[move->s.capturedPiece] <= alpha && !board::inCheck1(chessboard)) { - INC(nCutFp); - takeback(move, oldKey, true); - continue; - } - //Late Move Reduction int val = INT_MAX; - if (countMove > 4 && !is_incheck_side && depth >= 3 && move->s.capturedPiece == SQUARE_EMPTY && - move->s.promotionPiece == NO_PROMOTION) { - currentPly++; - val = -search(depth - 2, -(alpha + 1), -alpha, &line, N_PIECE, n_root_moves); - ASSERT(val != INT_MAX); - currentPly--; + if (move->promotionPiece == NO_PROMOTION) { + if (futilPrune && futilScore + PIECES_VALUE[move->capturedPiece] <= alpha && + !board::inCheck1(chessboard)) { + INC(nCutFp); + takeback(move, oldKey, oldEnpassant, true); + continue; + } + //Late Move Reduction + if (countMove > 3 && !isIncheckSide && depth >= 3 && move->capturedPiece == SQUARE_EMPTY) { + currentPly++; + const int R = countMove > 6 ? 3 : 2; + val = -search(depth + extension - R, -(alpha + 1), -alpha, &line, N_PIECE, + nRootMoves); + currentPly--; + if (!forceCheck && abs(val) > _INFINITE - MAX_PLY) { + currentPly++; + forceCheck = true; + val = -search(depth + extension - R, -(alpha + 1), -alpha, &line, N_PIECE, + nRootMoves); + forceCheck = false; + currentPly--; + } + } } if (val > alpha) { const int doMws = (score > -_INFINITE + MAX_PLY); const int lwb = max(alpha, score); const int upb = (doMws ? (lwb + 1) : beta); currentPly++; - val = -search(depth - 1, -upb, -lwb, &line, - move->s.capturedPiece == SQUARE_EMPTY ? N_PIECE : N_PIECE - 1, - n_root_moves); + val = -search(depth + extension - 1, -upb, -lwb, &line, + move->capturedPiece == SQUARE_EMPTY ? N_PIECE : N_PIECE - 1, + nRootMoves); currentPly--; + if (!forceCheck && abs(val) > _INFINITE - MAX_PLY) { + currentPly++; + forceCheck = true; + val = -search(depth + extension - 1, -upb, -lwb, &line, + move->capturedPiece == SQUARE_EMPTY ? N_PIECE : N_PIECE - 1, + nRootMoves); + forceCheck = false; + currentPly--; + } if (doMws && (lwb < val) && (val < beta)) { currentPly++; - val = -search(depth - 1, -beta, -val + 1, - &line, - move->s.capturedPiece == SQUARE_EMPTY ? N_PIECE : N_PIECE - 1, - n_root_moves); - if (move->s.capturedPiece == SQUARE_EMPTY && move->s.promotionPiece == NO_PROMOTION && - val < -(_INFINITE - 100)) { - setKiller(move->s.from, move->s.to, depth, true); - } + val = -search(depth + extension - 1, -beta, -val + 1, + &line, + move->capturedPiece == SQUARE_EMPTY ? N_PIECE : N_PIECE - 1, + nRootMoves); currentPly--; - } else { - if (move->s.capturedPiece == SQUARE_EMPTY && move->s.promotionPiece == NO_PROMOTION && - val < -(_INFINITE - 100)) { - setKiller(move->s.from, move->s.to, depth, true); + if (!forceCheck && abs(val) > _INFINITE - MAX_PLY) { + currentPly++; + forceCheck = true; + val = -search(depth + extension - 1, -beta, -val + 1, + &line, + move->capturedPiece == SQUARE_EMPTY ? N_PIECE : N_PIECE - 1, + nRootMoves); + forceCheck = false; + currentPly--; } } } score = max(score, val); - takeback(move, oldKey, true); - ASSERT(chessboard[KING_BLACK]) - ASSERT(chessboard[KING_WHITE]) + takeback(move, oldKey, oldEnpassant, true); + assert(chessboard[KING_BLACK]); + assert(chessboard[KING_WHITE]); if (score > alpha) { + if (move->capturedPiece == SQUARE_EMPTY && move->promotionPiece == NO_PROMOTION) { + setKiller(move->from, move->to, depth); + } if (score >= beta) { decListId(); INC(nCutAB); - ADD(betaEfficiency, betaEfficiencyCount / (double) listcount * 100.0); + INC(betaEfficiencyCount); + DEBUG(betaEfficiency += + (100.0 - ((double) countMove * 100.0 / (double) listcount)) + + (((double) countMove * 100.0 / (double) listcount) / (double) countMove)) if (getRunning()) { - Hash::_ThashData data(score, depth - extension, move->s.from, move->s.to, 0, Hash::hashfBETA); - hash.recordHash(zobristKeyR, data); + Hash::_Thash data(zobristKeyR, score, depth, move->from, move->to, Hash::hashfBETA); + hash.recordHash(data, ply); + } + + if (move->capturedPiece == SQUARE_EMPTY && move->promotionPiece == NO_PROMOTION) { + setHistoryHeuristic(move->from, move->to, depth); } - if (depth < 31) - setHistoryHeuristic(move->s.from, move->s.to, 1 << depth); - else - setHistoryHeuristic(move->s.from, move->s.to, 0x40000000); - if (move->s.capturedPiece == SQUARE_EMPTY && move->s.promotionPiece == NO_PROMOTION) - setKiller(move->s.from, move->s.to, depth, false); return score; } alpha = score; @@ -959,8 +913,12 @@ int Search::search(int depth, int alpha, const int beta, _TpvLine *pline, const } } if (getRunning()) { - Hash::_ThashData data(score, depth - extension, best->s.from, best->s.to, 0, hashf); - hash.recordHash(zobristKeyR, data); + if (best->capturedPiece == SQUARE_EMPTY && best->promotionPiece == NO_PROMOTION) { + setHistoryHeuristic(best->from, best->to, depth - extension); + setKiller(best->from, best->to, depth - extension); + } + Hash::_Thash data(zobristKeyR, score, depth, best->from, best->to, hashf); + hash.recordHash(data, ply); } decListId(); return score; @@ -968,14 +926,14 @@ int Search::search(int depth, int alpha, const int beta, _TpvLine *pline, const } void Search::updatePv(_TpvLine *pline, const _TpvLine *line, const _Tmove *move) { - ASSERT(line->cmove < MAX_PLY - 1) + assert(line->cmove < MAX_PLY - 1); memcpy(&(pline->argmove[0]), move, sizeof(_Tmove)); memcpy(pline->argmove + 1, line->argmove, line->cmove * sizeof(_Tmove)); - ASSERT(line->cmove >= 0) + assert(line->cmove >= 0); pline->cmove = line->cmove + 1; } -u64 Search::getZobristKey() { +u64 Search::getZobristKey() const { return chessboard[ZOBRISTKEY_IDX]; } @@ -983,81 +941,107 @@ void Search::unsetSearchMoves() { searchMovesVector.clear(); } -void Search::setSearchMoves(vector &s) { +void Search::setSearchMoves(const vector &s) { searchMovesVector = s; } -bool Search::setParameter(String param, int value) { -#if defined(CLOP) || defined(DEBUG_MODE) - param.toUpper(); - bool res = true; - if (param == "FUTIL_MARGIN") { - FUTIL_MARGIN = value; - } else if (param == "EXT_FUTILY_MARGIN") { - EXT_FUTILY_MARGIN = value; - } else if (param == "RAZOR_MARGIN") { - RAZOR_MARGIN = value; - } else if (param == "ATTACK_KING") { - ATTACK_KING = value; - } else if (param == "BACKWARD_PAWN") { - BACKWARD_PAWN = value; - } else if (param == "BISHOP_ON_QUEEN") { - BISHOP_ON_QUEEN = value; - } else if (param == "BONUS2BISHOP") { - BONUS2BISHOP = value; - } else if (param == "CONNECTED_ROOKS") { - CONNECTED_ROOKS = value; - } else if (param == "DOUBLED_ISOLATED_PAWNS") { - DOUBLED_ISOLATED_PAWNS = value; - } else if (param == "DOUBLED_PAWNS") { - DOUBLED_PAWNS = value; - } else if (param == "ENEMY_NEAR_KING") { - ENEMY_NEAR_KING = value; - } else if (param == "FRIEND_NEAR_KING") { - FRIEND_NEAR_KING = value; - } else if (param == "HALF_OPEN_FILE_Q") { - HALF_OPEN_FILE_Q = value; - } else if (param == "OPEN_FILE") { - OPEN_FILE = value; - } else if (param == "OPEN_FILE_Q") { - OPEN_FILE_Q = value; - } else if (param == "PAWN_IN_7TH") { - PAWN_IN_7TH = value; - } else if (param == "PAWN_CENTER") { - PAWN_CENTER = value; - } else if (param == "PAWN_IN_8TH") { - PAWN_IN_8TH = value; - } else if (param == "PAWN_ISOLATED") { - PAWN_ISOLATED = value; - } else if (param == "PAWN_NEAR_KING") { - PAWN_NEAR_KING = value; - } else if (param == "PAWN_BLOCKED") { - PAWN_BLOCKED = value; - } else if (param == "ROOK_7TH_RANK") { - ROOK_7TH_RANK = value; - } else if (param == "ROOK_BLOCKED") { - ROOK_BLOCKED = value; - } else if (param == "ROOK_TRAPPED") { - ROOK_TRAPPED = value; - } else if (param == "UNDEVELOPED_KNIGHT") { - UNDEVELOPED_KNIGHT = value; - } else if (param == "UNDEVELOPED_BISHOP") { - UNDEVELOPED_BISHOP = value; - } else if (param == "VAL_WINDOW") { - VAL_WINDOW = value; - } else if (param == "UNPROTECTED_PAWNS") { - UNPROTECTED_PAWNS = value; - } else { - res = false; +#ifdef TUNING + +int Search::getParameter(const string &p) { + if (p == "ATTACK_KING")return eval.ATTACK_KING; + if (p == "BISHOP_ON_QUEEN")return eval.BISHOP_ON_QUEEN; + if (p == "BACKWARD_PAWN")return eval.BACKWARD_PAWN; + if (p == "DOUBLED_ISOLATED_PAWNS")return eval.DOUBLED_ISOLATED_PAWNS; +// if (p == "DOUBLED_PAWNS")return eval.DOUBLED_PAWNS; + if (p == "PAWN_IN_7TH")return eval.PAWN_IN_7TH; +// if (p == "PAWN_CENTER")return eval.PAWN_CENTER; + if (p == "PAWN_IN_PROMOTION")return eval.PAWN_IN_PROMOTION; +// if (p == "PAWN_ISOLATED")return eval.PAWN_ISOLATED; + if (p == "PAWN_NEAR_KING")return eval.PAWN_NEAR_KING; + if (p == "PAWN_BLOCKED")return eval.PAWN_BLOCKED; + if (p == "UNPROTECTED_PAWNS")return eval.UNPROTECTED_PAWNS; +// if (p == "ENEMY_NEAR_KING")return eval.ENEMY_NEAR_KING; + if (p == "FRIEND_NEAR_KING")return eval.FRIEND_NEAR_KING; +// if (p == "HALF_OPEN_FILE_Q")return eval.HALF_OPEN_FILE_Q; + if (p == "BONUS2BISHOP")return eval.BONUS2BISHOP; + if (p == "BISHOP_PAWN_ON_SAME_COLOR")return eval.BISHOP_PAWN_ON_SAME_COLOR; +// if (p == "CONNECTED_ROOKS")return eval.CONNECTED_ROOKS; +// if (p == "OPEN_FILE")return eval.OPEN_FILE; + if (p == "OPEN_FILE_Q")return eval.OPEN_FILE_Q; + if (p == "ROOK_7TH_RANK")return eval.ROOK_7TH_RANK; +// if (p == "ROOK_BLOCKED")return eval.ROOK_BLOCKED; +// if (p == "ROOK_TRAPPED")return eval.ROOK_TRAPPED; +// if (p == "UNDEVELOPED_KNIGHT")return eval.UNDEVELOPED_KNIGHT; +// if (p == "UNDEVELOPED_BISHOP")return eval.UNDEVELOPED_BISHOP; + if (p == "KNIGHT_PINNED")return eval.KNIGHT_PINNED; + if (p == "ROOK_PINNED")return eval.ROOK_PINNED; + if (p == "BISHOP_PINNED")return eval.BISHOP_PINNED; + if (p == "QUEEN_PINNED")return eval.QUEEN_PINNED; + if (p == "QUEEN_IN_7")return eval.QUEEN_IN_7; + if (p == "ROOK_IN_7")return eval.ROOK_IN_7; +// if (p == "PAWN_PINNED")return eval.PAWN_PINNED; + fatal("Not found ", p) + exit(1); +} + +void Search::setParameter(const string &p, const int value) { + //cout << "setParameter " << param << " " << value << endl; + if (p == "ATTACK_KING")eval.ATTACK_KING = value; + else if (p == "BISHOP_ON_QUEEN")eval.BISHOP_ON_QUEEN = value; + else if (p == "BACKWARD_PAWN")eval.BACKWARD_PAWN = value; + else if (p == "DOUBLED_ISOLATED_PAWNS")eval.DOUBLED_ISOLATED_PAWNS = value; +// else if (p == "DOUBLED_PAWNS")eval.DOUBLED_PAWNS = value; + else if (p == "PAWN_IN_7TH")eval.PAWN_IN_7TH = value; +// else if (p == "PAWN_CENTER")eval.PAWN_CENTER = value; + else if (p == "PAWN_IN_PROMOTION")eval.PAWN_IN_PROMOTION = value; +// else if (p == "PAWN_ISOLATED")eval.PAWN_ISOLATED = value; + else if (p == "PAWN_NEAR_KING")eval.PAWN_NEAR_KING = value; + else if (p == "PAWN_BLOCKED")eval.PAWN_BLOCKED = value; + else if (p == "UNPROTECTED_PAWNS")eval.UNPROTECTED_PAWNS = value; +// else if (p == "ENEMY_NEAR_KING")eval.ENEMY_NEAR_KING = value; + else if (p == "FRIEND_NEAR_KING")eval.FRIEND_NEAR_KING = value; +// else if (p == "HALF_OPEN_FILE_Q")eval.HALF_OPEN_FILE_Q = value; + else if (p == "BONUS2BISHOP")eval.BONUS2BISHOP = value; + else if (p == "BISHOP_PAWN_ON_SAME_COLOR")eval.BISHOP_PAWN_ON_SAME_COLOR = value; +// else if (p == "CONNECTED_ROOKS")eval.CONNECTED_ROOKS = value; +// else if (p == "OPEN_FILE")eval.OPEN_FILE = value; + else if (p == "OPEN_FILE_Q")eval.OPEN_FILE_Q = value; + else if (p == "ROOK_7TH_RANK")eval.ROOK_7TH_RANK = value; +// else if (p == "ROOK_BLOCKED")eval.ROOK_BLOCKED = value; +// else if (p == "ROOK_TRAPPED")eval.ROOK_TRAPPED = value; +// else if (p == "UNDEVELOPED_KNIGHT")eval.UNDEVELOPED_KNIGHT = value; +// else if (p == "UNDEVELOPED_BISHOP")eval.UNDEVELOPED_BISHOP = value; + else if (p == "KNIGHT_PINNED")eval.KNIGHT_PINNED = value; + else if (p == "ROOK_PINNED")eval.ROOK_PINNED = value; + else if (p == "BISHOP_PINNED")eval.BISHOP_PINNED = value; + else if (p == "QUEEN_PINNED")eval.QUEEN_PINNED = value; + else if (p == "QUEEN_IN_7")eval.QUEEN_IN_7 = value; + else if (p == "ROOK_IN_7")eval.ROOK_IN_7 = value; +// else if (p == "PAWN_PINNED")eval.PAWN_PINNED = value; + else { + fatal("Not found ", p) + exit(1); } - return res; -#else - cout << param << " " << value << endl; - return false; -#endif } +#endif + +template +bool Search::badCapure(const _Tmove &move, const u64 allpieces) { + + if (move.pieceFrom == (PAWN_BLACK + side)) return false; + if (PIECES_VALUE[move.capturedPiece] - 5 >= PIECES_VALUE[move.pieceFrom]) return false; + if (PIECES_VALUE[move.capturedPiece] + 200 < PIECES_VALUE[move.pieceFrom] && + (PAWN_FORK_MASK[side][move.to] & chessboard[PAWN_BLACK + (X(side))])) + return true; + + if (PIECES_VALUE[move.capturedPiece] + 500 < PIECES_VALUE[move.pieceFrom] && + board::isAttacked(side, move.to, allpieces, chessboard)) + return true; + + return false; +} diff --git a/src/Search.h b/src/Search.h index fafae67d..598072eb 100644 --- a/src/Search.h +++ b/src/Search.h @@ -18,7 +18,7 @@ #pragma once -#include +#include "unistd.h" #include "Hash.h" #include "Eval.h" #include "namespaces/bits.h" @@ -33,28 +33,55 @@ #endif +typedef struct { + int cmove; + _Tmove argmove[MAX_PLY]; +} _TpvLine; -class Search : public Eval, public Thread { +class Search : public GenMoves, public Thread { public: + static constexpr int NULL_DIVISOR = 7; + static constexpr int NULL_DEPTH = 3; + static constexpr int VAL_WINDOW = 50; + Search(); + short getScore(const uchar side) { + return eval.getScore(chessboard, 0xffffffffffffffffULL, side, -_INFINITE, _INFINITE DEBUG2(, true)); + } + Search(const Search *s) { clone(s); } void clone(const Search *); virtual ~Search(); - void setRunning(int); + void setRunning(const int); + + void setPonder(const bool); + + void setNullMove(const bool); + + void setMaxTimeMillsec(const int); - void setPonder(bool); +#ifdef TUNING - void setNullMove(bool); + int getParameter(const string ¶m); - void setMaxTimeMillsec(int); + void setParameter(const string ¶m, const int value); - bool setParameter(String param, int value); + int qSearch(const int depth, const int alpha, const int beta) { + ASSERT_RANGE(depth, 0, MAX_PLY) + auto ep = enPassant; + + const auto result= sideToMove ? qsearch(alpha, beta, ep, depth) + : qsearch(alpha, beta, ep, depth); + return sideToMove ? result : -result; + } + +#endif int getMaxTimeMillsec() const; @@ -69,14 +96,15 @@ class Search : public Eval, public Thread { void setMainParam(const int depth); template - int search(const int depth, const int alpha, const int beta); + int searchRoot(const int depth, const int alpha, const int beta); void run(); - void endRun() {}; + void endRun() {} + #ifndef JS_MODE - int probeWdl(const int depth, const int side, const int N_PIECE); + int probeWdl(const int depth, const uchar side, const int N_PIECE); int printDtmWdlGtb(const bool dtm); @@ -86,13 +114,9 @@ class Search : public Eval, public Thread { #endif - void setMainPly(const int); + void setMainPly(const int, const int); - STATIC_CONST int NULL_DIVISOR = 7; - STATIC_CONST int NULL_DEPTH = 3; - STATIC_CONST int VAL_WINDOW = 50; - - void setRunningThread(bool t) { + static void setRunningThread(const bool t) { runningThread = t; } @@ -104,24 +128,28 @@ class Search : public Eval, public Thread { return valWindow; } - u64 getZobristKey(); + u64 getZobristKey() const; + + uchar getEnpassant() const { + return enPassant; + } #ifdef DEBUG_MODE - unsigned cumulativeMovesCount; + static unsigned cumulativeMovesCount; unsigned totGen; + unsigned getLazyEvalCuts() { + return eval.lazyEvalCuts; + } + #endif void unsetSearchMoves(); - void setSearchMoves(vector &v); + void setSearchMoves(const vector &v); private: - - typedef struct { - Hash::_ThashData phasheType[2]; - } _TcheckHash; - + Eval eval; Hash &hash = Hash::getInstance(); #ifndef JS_MODE SYZYGY *syzygy = &SYZYGY::getInstance(); @@ -132,6 +160,7 @@ class Search : public Eval, public Thread { _TpvLine pvLine; bool ponder; + #ifdef BENCH_MODE Times *times = &Times::getInstance(); #endif @@ -147,65 +176,20 @@ class Search : public Eval, public Thread { bool checkDraw(u64); - template - int search(int depth, int alpha, const int beta, _TpvLine *pline, const int N_PIECE, const int n_root_moves); + template + int search(const int depth, int alpha, const int beta, _TpvLine *pline, const int N_PIECE, const int nRootMoves); template - bool checkSearchMoves(_Tmove *move) const; + bool checkSearchMoves(const _Tmove *move) const; - template - int quiescence(int alpha, const int beta, const char promotionPiece, const int depth); + template + int qsearch(int alpha, const int beta, const uchar promotionPiece, const int depth); void updatePv(_TpvLine *pline, const _TpvLine *line, const _Tmove *move); int mainDepth; + int ply; - inline pair checkHash(const int type, - const bool quies, - const int alpha, - const int beta, - const int depth, - const u64 zobristKeyR) { - - _TcheckHash checkHashStruct; - Hash::_ThashData *phashe = &checkHashStruct.phasheType[type]; - if ((phashe->dataU = hash.readHash(type, zobristKeyR))) { - if (phashe->dataS.depth >= depth) { - INC(hash.probeHash); - if (!currentPly) { - if (phashe->dataS.flags == Hash::hashfBETA) { - incHistoryHeuristic(phashe->dataS.from, phashe->dataS.to, 1); - } - } else { - switch (phashe->dataS.flags) { - case Hash::hashfEXACT: - if (phashe->dataS.score >= beta) { - INC(hash.n_cut_hashB); - return pair(beta, checkHashStruct); - } - break; - case Hash::hashfBETA: - if (!quies)incHistoryHeuristic(phashe->dataS.from, phashe->dataS.to, 1); - if (phashe->dataS.score >= beta) { - INC(hash.n_cut_hashB); - return pair(beta, checkHashStruct); - } - break; - case Hash::hashfALPHA: - if (phashe->dataS.score <= alpha) { - INC(hash.n_cut_hashA); - return pair(alpha, checkHashStruct); - } - break; - default: - fatal("error checkHash"); - break; - } - } - } - } - INC(hash.cutFailed); - return pair(INT_MAX, checkHashStruct); - - } + template + bool badCapure(const _Tmove &move, const u64 allpieces); }; diff --git a/src/SearchManager.cpp b/src/SearchManager.cpp index 5af0bd79..2f664cf2 100644 --- a/src/SearchManager.cpp +++ b/src/SearchManager.cpp @@ -20,30 +20,11 @@ using namespace _logger; -SearchManager::SearchManager() { +ThreadPool *SearchManager::threadPool; +_TpvLine SearchManager::lineWin; +SearchManager::SearchManager() { threadPool = new ThreadPool(1); - - IniFile iniFile("cinnamon.ini"); - - while (true) { - pair *parameters = iniFile.get(); - if (!parameters) { - break; - } - string param = parameters->first; - int value = stoi(parameters->second); - cout << param << endl; - cout << value << endl; - - if (param == "threads") { - setNthread(value); - } else { - if (!setParameter(param, value)) { - cout << "error parameter " << param << " not defined\n"; - } - } - } } #if defined(FULL_TEST) @@ -52,33 +33,31 @@ unsigned SearchManager::SZtbProbeWDL() const { } #endif -string SearchManager::probeRootTB() const { +string SearchManager::probeRootTB() { _Tmove bestMove; Search &search = threadPool->getThread(0); if (search.probeRootTB(&bestMove)) { - string best = string(search.decodeBoardinv(bestMove.s.type, bestMove.s.from, getSide())) + - string(search.decodeBoardinv(bestMove.s.type, bestMove.s.to, getSide())); + string best = string(search.decodeBoardinv(bestMove.type, bestMove.from, getSide())) + + string(search.decodeBoardinv(bestMove.type, bestMove.to, getSide())); - if (bestMove.s.promotionPiece != GenMoves::NO_PROMOTION) - best += tolower(bestMove.s.promotionPiece); + if (bestMove.promotionPiece != NO_PROMOTION) + best += tolower(bestMove.promotionPiece); return best; } else return ""; } -int SearchManager::search(const int mply) { +int SearchManager::search(const int ply, const int mply) { constexpr int SkipStep[64] = {0, 1, 2, 3, 1, 1, 2, 3, 0, 1, 1, 2, 1, 1, 2, 3, 0, 1, 1, 2, 1, 1, 2, 3, 0, 1, 1, 2, 1, 1, 2, 3, 0, 1, 1, 2, 1, 1, 2, 3, 0, 1, 1, 2, 1, 1, 2, 3, 0, 1, 1, 2, 1, 1, 2, 3, 0, 1, 1, 2, 1, 1, 2, 3}; - debug("start singleSearch -------------------------------") lineWin.cmove = -1; - setMainPly(mply); - ASSERT(bitCount(threadPool->getBitCount()) < 2) - debug("start lazySMP --------------------------") + setMainPly(ply, mply); + assert(bitCount(threadPool->getBitCount()) < 2); for (int ii = 1; ii < threadPool->getNthread(); ii++) { Search &helperThread = threadPool->getNextThread(); @@ -88,7 +67,6 @@ int SearchManager::search(const int mply) { startThread(helperThread, mply + SkipStep[ii]); } - debug("end lazySMP ---------------------------") Search &mainThread = threadPool->getThread(0); mainThread.setMainParam(mply); mainThread.run(); @@ -96,11 +74,10 @@ int SearchManager::search(const int mply) { auto res = mainThread.getValWindow(); if (mainThread.getRunning()) { - memcpy(&lineWin, &mainThread.getPvLine(), sizeof(_TpvLine)); + memcpy(&lineWin, &mainThread.getPvLine(), sizeof(lineWin)); } stopAllThread(); threadPool->joinAll(); - debug("end singleSearch -------------------------------") return res; } @@ -112,17 +89,15 @@ bool SearchManager::getRes(_Tmove &resultMove, string &ponderMove, string &pvv) pvv.clear(); string pvvTmp; - ASSERT(lineWin.cmove) + assert(lineWin.cmove); for (int t = 0; t < lineWin.cmove; t++) { pvvTmp.clear(); pvvTmp += - decodeBoardinv(lineWin.argmove[t].s.type, - lineWin.argmove[t].s.from, - board::getSide(threadPool->getThread(0).getChessboard())); + decodeBoardinv(lineWin.argmove[t].type, lineWin.argmove[t].from, + threadPool->getThread(0).sideToMove); if (pvvTmp.length() != 4 && pvvTmp[0] != 'O') { - pvvTmp += decodeBoardinv(lineWin.argmove[t].s.type, - lineWin.argmove[t].s.to, - board::getSide(threadPool->getThread(0).getChessboard())); + pvvTmp += decodeBoardinv(lineWin.argmove[t].type, lineWin.argmove[t].to, + threadPool->getThread(0).sideToMove); } pvv.append(pvvTmp); if (t == 1) { @@ -138,7 +113,7 @@ bool SearchManager::getRes(_Tmove &resultMove, string &ponderMove, string &pvv) SearchManager::~SearchManager() { } -int SearchManager::loadFen(string fen) { +int SearchManager::loadFen(const string &fen) { int res = -1; for (uchar i = 0; i < threadPool->getPool().size(); i++) { @@ -157,13 +132,13 @@ void SearchManager::startThread(Search &thread, const int depth) { thread.start(); } -void SearchManager::setMainPly(int r) { +void SearchManager::setMainPly(const int ply, const int mply) { for (Search *s:threadPool->getPool()) { - s->setMainPly(r); + s->setMainPly(ply, mply); } } -int SearchManager::getPieceAt(int side, u64 i) { +int SearchManager::getPieceAt(const uchar side, const u64 i) { return side == WHITE ? board::getPieceAt(i, threadPool->getThread(0).getChessboard()) : board::getPieceAt(i, threadPool->getThread(0).getChessboard()); } @@ -176,7 +151,7 @@ u64 SearchManager::getTotMoves() { return i; } -void SearchManager::incHistoryHeuristic(int from, int to, int value) { +void SearchManager::incHistoryHeuristic(const int from, const int to, const int value) { for (Search *s:threadPool->getPool()) { s->incHistoryHeuristic(from, to, value); } @@ -186,10 +161,6 @@ void SearchManager::startClock() { threadPool->getThread(0).startClock();// static variable } -string SearchManager::boardToFen() { - return threadPool->getThread(0).boardToFen(); -} - void SearchManager::clearHeuristic() { for (Search *s:threadPool->getPool()) { s->clearHeuristic(); @@ -200,25 +171,27 @@ int SearchManager::getForceCheck() { return threadPool->getThread(0).getForceCheck(); } -u64 SearchManager::getZobristKey(int id) { +u64 SearchManager::getZobristKey(const int id) { return threadPool->getThread(id).getZobristKey(); } -void SearchManager::setForceCheck(bool a) { - threadPool->getThread(0).setForceCheck(a); +void SearchManager::setForceCheck(const bool a) { + for (Search *s:threadPool->getPool()) { + s->setForceCheck(a); + } } -void SearchManager::setRunningThread(bool r) { - threadPool->getThread(0).setRunningThread(r); +void SearchManager::setRunningThread(const bool r) { + Search::setRunningThread(r); } -void SearchManager::setRunning(int i) { +void SearchManager::setRunning(const int i) { for (Search *s:threadPool->getPool()) { s->setRunning(i); } } -int SearchManager::getRunning(int i) { +int SearchManager::getRunning(const int i) { return threadPool->getThread(i).getRunning(); } @@ -226,11 +199,7 @@ void SearchManager::display() { threadPool->getThread(0).display(); } -string SearchManager::getFen() { - return threadPool->getThread(0).getFen(); -} - -void SearchManager::setMaxTimeMillsec(int i) { +void SearchManager::setMaxTimeMillsec(const int i) { for (Search *s:threadPool->getPool()) { s->setMaxTimeMillsec(i); } @@ -242,12 +211,12 @@ void SearchManager::unsetSearchMoves() { } } -void SearchManager::setSearchMoves(vector &searchMov) { +void SearchManager::setSearchMoves(const vector &searchMov) { _Tmove move; vector searchMoves; - for (std::vector::iterator it = searchMov.begin(); it != searchMov.end(); ++it) { + for (auto it = searchMov.begin(); it != searchMov.end(); ++it) { getMoveFromSan(*it, &move); - const int x = move.s.to | (int) (move.s.from << 8); + const int x = move.to | (int) (move.from << 8); searchMoves.push_back(x); } for (Search *s:threadPool->getPool()) { @@ -255,43 +224,43 @@ void SearchManager::setSearchMoves(vector &searchMov) { } } -void SearchManager::setPonder(bool i) { +void SearchManager::setPonder(const bool i) { for (Search *s:threadPool->getPool()) { s->setPonder(i); } } -int SearchManager::getSide() const { +int SearchManager::getSide() { #ifdef DEBUG_MODE - int t = board::getSide(threadPool->getThread(0).getChessboard()); + int t = threadPool->getThread(0).sideToMove; for (Search *s:threadPool->getPool()) { - ASSERT(board::getSide(s->getChessboard()) == t) + assert(s->sideToMove == t); } #endif - return board::getSide(threadPool->getThread(0).getChessboard()); + return threadPool->getThread(0).sideToMove; } -int SearchManager::getScore(int side, const bool trace) { - return threadPool->getThread(0).getScore(0xffffffffffffffffULL, side, -_INFINITE, _INFINITE, trace); +int SearchManager::getScore(const uchar side) { + return threadPool->getThread(0).getScore(side); } int SearchManager::getMaxTimeMillsec() { return threadPool->getThread(0).getMaxTimeMillsec(); } -void SearchManager::setNullMove(bool i) { +void SearchManager::setNullMove(const bool i) { for (Search *s:threadPool->getPool()) { s->setNullMove(i); } } -void SearchManager::setChess960(bool i) { +void SearchManager::setChess960(const bool i) { for (Search *s:threadPool->getPool()) { s->setChess960(i); } } -bool SearchManager::makemove(_Tmove *i) { +bool SearchManager::makemove(const _Tmove *i) { bool b = false; for (Search *s:threadPool->getPool()) { b = s->makemove(i, true, false); @@ -299,17 +268,17 @@ bool SearchManager::makemove(_Tmove *i) { return b; } -string SearchManager::decodeBoardinv(const uchar type, const int a, const int side) { +string SearchManager::decodeBoardinv(const uchar type, const int a, const uchar side) { return threadPool->getThread(0).decodeBoardinv(type, a, side); } -void SearchManager::takeback(_Tmove *move, const u64 oldkey, bool rep) { +void SearchManager::takeback(const _Tmove *move, const u64 oldkey, const uchar oldEnpassant, const bool rep) { for (Search *s:threadPool->getPool()) { - s->takeback(move, oldkey, rep); + s->takeback(move, oldkey, oldEnpassant, rep); } } -void SearchManager::setSide(bool i) { +void SearchManager::setSide(const bool i) { for (Search *s:threadPool->getPool()) { s->setSide(i); } @@ -331,11 +300,11 @@ void SearchManager::printWdlSyzygy() { #endif -int SearchManager::getMoveFromSan(String string, _Tmove *ptr) const { +int SearchManager::getMoveFromSan(const string &string, _Tmove *ptr) { #ifdef DEBUG_MODE int t = threadPool->getThread(0).getMoveFromSan(string, ptr); for (Search *s:threadPool->getPool()) { - ASSERT(s->getMoveFromSan(string, ptr) == t) + assert(s->getMoveFromSan(string, ptr) == t); } #endif return threadPool->getThread(0).getMoveFromSan(string, ptr); @@ -353,30 +322,19 @@ void SearchManager::init() { } } -void SearchManager::setRepetitionMapCount(int i) { +void SearchManager::setRepetitionMapCount(const int i) { for (Search *s:threadPool->getPool()) { s->setRepetitionMapCount(i); } } - -bool SearchManager::setNthread(int nthread) { - if (!threadPool->setNthread(nthread))return false; - return true; +bool SearchManager::setNthread(const int nthread) { + return threadPool->setNthread(nthread); } void SearchManager::stopAllThread() { - threadPool->getThread(0).setRunningThread(false); + Search::setRunningThread(false); } -bool SearchManager::setParameter(String param, int value) { - bool b = false; - for (Search *s:threadPool->getPool()) { - b = s->setParameter(param, value); - } - return b; -} - - diff --git a/src/SearchManager.h b/src/SearchManager.h index 27be251e..944ff177 100644 --- a/src/SearchManager.h +++ b/src/SearchManager.h @@ -18,119 +18,134 @@ #pragma once -#include #include "Search.h" #include "threadPool/ThreadPool.h" -#include -#include "util/String.h" +#include "namespaces/String.h" #include "util/IniFile.h" -#include -#include -#include "namespaces/bits.h" -class SearchManager : public Singleton { +class SearchManager : private Singleton { friend class Singleton; public: - bool getRes(_Tmove &resultMove, string &ponderMove, string &pvv); - ~SearchManager(); - int loadFen(string fen = ""); + static bool getRes(_Tmove &resultMove, string &ponderMove, string &pvv); - int getPieceAt(int side, u64 i); + static int loadFen(const string &fen = ""); - u64 getTotMoves(); + static int getPieceAt(const uchar side, const u64 i); - void incHistoryHeuristic(int from, int to, int value); + static u64 getTotMoves(); - void startClock(); + static void incHistoryHeuristic(const int from, const int to, const int value); - string boardToFen(); + static void startClock(); - string decodeBoardinv(const uchar type, const int a, const int side); + static string decodeBoardinv(const uchar type, const int a, const uchar side); - bool setParameter(String param, int value); +#ifdef TUNING - void clearHeuristic(); + const _Tchessboard &getChessboard() { + return threadPool->getThread(0).getChessboard(); + } - int getForceCheck(); + static void setParameter(const string ¶m, const int value) { + for (Search *s:threadPool->getPool()) { + s->setParameter(param, value); + } + } - u64 getZobristKey(int id); + static int getParameter(const string ¶m) { + return threadPool->getThread(0).getParameter(param); + } - void setForceCheck(bool a); + int getQscore() const { + return threadPool->getThread(0).qSearch(15, -_INFINITE, _INFINITE); + } - void setRunningThread(bool r); +#endif + + static void clearHeuristic(); + + static int getForceCheck(); + + static u64 getZobristKey(const int id); + + static u64 getEnpassant(const int id) { + return threadPool->getThread(id).getEnpassant(); + } - string probeRootTB() const; + static void setForceCheck(const bool a); - void setRunning(int i); + static void setRunningThread(const bool r); - int getRunning(int i); + static string probeRootTB(); - void display(); + static void setRunning(const int i); - string getFen(); + static int getRunning(const int i); - void setMaxTimeMillsec(int i); + static void display(); - void unsetSearchMoves(); + static void setMaxTimeMillsec(const int i); - void setSearchMoves(vector &searchmoves); + static void unsetSearchMoves(); - void setPonder(bool i); + static void setSearchMoves(const vector &searchmoves); - int getSide() const; + static void setPonder(bool i); - int getScore(int side, const bool trace); + static int getSide(); - int getMaxTimeMillsec(); + static int getScore(const uchar side); - void setNullMove(bool i); + static int getMaxTimeMillsec(); - void setChess960(bool i); + static void setNullMove(const bool i); - bool makemove(_Tmove *i); + static void setChess960(const bool i); - void takeback(_Tmove *move, const u64 oldkey, bool rep); + static bool makemove(const _Tmove *i); - void setSide(bool i); + static void takeback(const _Tmove *move, const u64 oldkey, const uchar oldEnpassant, const bool rep); - int getMoveFromSan(String string, _Tmove *ptr) const; + static void setSide(const bool i); + + static int getMoveFromSan(const string &string, _Tmove *ptr); #ifndef JS_MODE - int printDtmGtb(const bool dtm); + static int printDtmGtb(const bool dtm); - void printDtmSyzygy(); + static void printDtmSyzygy(); - void printWdlSyzygy(); + static void printWdlSyzygy(); #endif - void pushStackMove(); + static void pushStackMove(); - void init(); + static void init(); - void setRepetitionMapCount(int i); + static void setRepetitionMapCount(const int i); - bool setNthread(int); + static bool setNthread(const int); #if defined(FULL_TEST) unsigned SZtbProbeWDL() const; - u64 getBitmap(const int n, const int side) const { + u64 getBitmap(const int n, const uchar side) const { return side ? board::getBitmap(threadPool->getPool()[n]->getChessboard()) : board::getBitmap(threadPool->getPool()[n]->getChessboard()); } - const _Tchessboard &getChessboard(const int n) const { + const _Tchessboard &getChessboard(const int n = 0) const { return threadPool->getPool()[n]->getChessboard(); } - template + template u64 getPinned(const u64 allpieces, const u64 friends, const int kingPosition) const { return board::getPinned(allpieces, friends, kingPosition, threadPool->getPool()[0]->getChessboard()); } @@ -139,15 +154,11 @@ class SearchManager : public Singleton { #ifdef DEBUG_MODE - unsigned getCumulativeMovesCount() { - unsigned i = 0; - for (Search *s:threadPool->getPool()) { - i += s->cumulativeMovesCount; - } - return i; + static unsigned getCumulativeMovesCount() { + return Search::cumulativeMovesCount; } - unsigned getNCutAB() { + static unsigned getNCutAB() { unsigned i = 0; for (Search *s:threadPool->getPool()) { i += s->nCutAB; @@ -155,23 +166,25 @@ class SearchManager : public Singleton { return i; } - double getBetaEfficiency() { - double i = 0; + static double getBetaEfficiency() { + double b = 0; + unsigned count = 0; for (Search *s:threadPool->getPool()) { - i += s->betaEfficiency; + b += s->betaEfficiency; + count += s->betaEfficiencyCount; } - return i; + return b / count; } - unsigned getLazyEvalCuts() { + static unsigned getLazyEvalCuts() { unsigned i = 0; for (Search *s:threadPool->getPool()) { - i += s->lazyEvalCuts; + i += s->getLazyEvalCuts(); } return i; } - unsigned getNCutFp() { + static unsigned getNCutFp() { unsigned i = 0; for (Search *s:threadPool->getPool()) { i += s->nCutFp; @@ -179,7 +192,7 @@ class SearchManager : public Singleton { return i; } - unsigned getNCutRazor() { + static unsigned getNCutRazor() { unsigned i = 0; for (Search *s:threadPool->getPool()) { i += s->nCutRazor; @@ -187,31 +200,39 @@ class SearchManager : public Singleton { return i; } - unsigned getTotGen() { + static unsigned getTotBadCaputure() { + unsigned i = 0; + for (Search *s:threadPool->getPool()) { + i += s->nCutBadCaputure; + } + return i; + } + + static unsigned getNullMoveCut() { unsigned i = 0; for (Search *s:threadPool->getPool()) { - i += s->totGen; + i += s->nNullMoveCut; } return i; } #endif - int search(int mply); + static int search(const int ply, const int mply); private: SearchManager(); - ThreadPool *threadPool = nullptr; + static ThreadPool *threadPool; - _TpvLine lineWin; + static _TpvLine lineWin; - void setMainPly(const int r); + static void setMainPly(const int ply, const int r); - void startThread(Search &thread, const int depth); + static void startThread(Search &thread, const int depth); - void stopAllThread(); + static void stopAllThread(); }; diff --git a/src/Uci.cpp b/src/Uci.cpp index bad128e8..d9e34668 100644 --- a/src/Uci.cpp +++ b/src/Uci.cpp @@ -27,7 +27,7 @@ Uci::Uci() { startListner(); } -void Uci::getToken(istringstream &uip, String &token) { +void Uci::getToken(istringstream &uip, string &token) const { token.clear(); uip >> token; } @@ -35,7 +35,7 @@ void Uci::getToken(istringstream &uip, String &token) { void Uci::listner(IterativeDeeping *it) { string command; bool knowCommand; - String token; + string token; bool stop = false; int lastTime = 0; uciMode = false; @@ -51,23 +51,23 @@ void Uci::listner(IterativeDeeping *it) { istringstream uip(command, ios::in); getToken(uip, token); knowCommand = false; - if (token.toLower() == "quit") { + if (String::toLower(token) == "quit") { knowCommand = true; searchManager.setRunning(false); stop = true; while (it->getRunning()); - } else if (token.toLower() == "ponderhit") { + } else if (String::toLower(token) == "ponderhit") { knowCommand = true; searchManager.startClock(); searchManager.setMaxTimeMillsec(lastTime - lastTime / 3); searchManager.setPonder(false); - } else if (token.toLower() == "display") { + } else if (String::toLower(token) == "display") { knowCommand = true; searchManager.display(); - } else if (token.toLower() == "isready") { + } else if (String::toLower(token) == "isready") { knowCommand = true; cout << "readyok\n"; - } else if (token.toLower() == "uci") { + } else if (String::toLower(token) == "uci") { knowCommand = true; uciMode = true; cout << "id name " << NAME << endl; @@ -76,8 +76,6 @@ void Uci::listner(IterativeDeeping *it) { << (0xffffffff / (1024 * 1024 / (sizeof(Hash::_Thash) * 2))) << endl; cout << "option name Clear Hash type button" << endl; cout << "option name Nullmove type check default true" << endl; - cout << "option name Book File type string default cinnamon.bin" << endl; - cout << "option name OwnBook type check default " << _BOOLEAN[it->getUseBook()] << "" << endl; cout << "option name Ponder type check default " << _BOOLEAN[it->getPonderEnabled()] << "" << endl; cout << "option name Threads type spin default 1 min 1 max 64" << endl; cout << "option name UCI_Chess960 type check default false" << endl; @@ -90,36 +88,31 @@ void Uci::listner(IterativeDeeping *it) { cout << "option name TB Restart type button" << endl; cout << "option name SyzygyPath type string default " << endl; cout << "uciok" << endl; - } else if (token.toLower() == "score") { - int side = searchManager.getSide(); - int t = searchManager.getScore(side, true); - - if (!searchManager.getSide()) { - t = -t; - } + } else if (String::toLower(token) == "score" || String::toLower(token) == "eval") { + uchar side = searchManager.getSide(); + int t = searchManager.getScore(side); + if (!searchManager.getSide()) t = -t; cout << "Score: " << t << endl; knowCommand = true; - } else if (token.toLower() == "stop") { + } else if (String::toLower(token) == "perft") { + cout << "Can't run perft here, view \"cinnamon.exe -help\"" << endl; + } else if (String::toLower(token) == "stop") { knowCommand = true; searchManager.setPonder(false); searchManager.setRunning(0); searchManager.setRunningThread(false); - } else if (token.toLower() == "ucinewgame") { + } else if (String::toLower(token) == "ucinewgame") { while (it->getRunning()); + it->ply = 0; searchManager.loadFen(); knowCommand = true; - } else if (token.toLower() == "setvalue") { + } else if (String::toLower(token) == "setoption") { getToken(uip, token); - String value; - getToken(uip, value); - knowCommand = searchManager.setParameter(token, stoi(value)); - } else if (token.toLower() == "setoption") { - getToken(uip, token); - if (token.toLower() == "name") { + if (String::toLower(token) == "name") { getToken(uip, token); - if (token.toLower() == "gaviotatbpath") { + if (String::toLower(token) == "gaviotatbpath") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); knowCommand = true; auto gtb = >B::getInstance(); @@ -131,16 +124,16 @@ void Uci::listner(IterativeDeeping *it) { if (tb_pieces != -1) gtb->setInstalledPieces(tb_pieces); } - } else if (token.toLower() == "syzygypath") { + } else if (String::toLower(token) == "syzygypath") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); knowCommand = true; SYZYGY::getInstance().createSYZYGY(token); } - } else if (token.toLower() == "gaviotatbcache") { + } else if (String::toLower(token) == "gaviotatbcache") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); gaviotatbcache = stoi(token); GTB *gtb = >B::getInstance(); @@ -150,15 +143,15 @@ void Uci::listner(IterativeDeeping *it) { knowCommand = true; } } - } else if (token.toLower() == "threads") { + } else if (String::toLower(token) == "threads") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); knowCommand = searchManager.setNthread(stoi(token)); } - } else if (token.toLower() == "gaviotatbscheme") { + } else if (String::toLower(token) == "gaviotatbscheme") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); gaviotatbscheme = token; GTB *gtb = >B::getInstance(); @@ -167,13 +160,13 @@ void Uci::listner(IterativeDeeping *it) { knowCommand = true; } } - } else if (token.toLower() == "tb") { + } else if (String::toLower(token) == "tb") { getToken(uip, token); - if (token.toLower() == "pieces") { + if (String::toLower(token) == "pieces") { getToken(uip, token); - if (token.toLower() == "installed") { + if (String::toLower(token) == "installed") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); tb_pieces = stoi(token); GTB *gtb = >B::getInstance(); @@ -183,78 +176,60 @@ void Uci::listner(IterativeDeeping *it) { } } } - } else if (token.toLower() == "restart") { + } else if (String::toLower(token) == "restart") { knowCommand = true; GTB *gtb = >B::getInstance(); if (gtb != nullptr)gtb->restart(); } - } else if (token.toLower() == "hash") { + } else if (String::toLower(token) == "hash") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); hash.setHashSize(stoi(token)); knowCommand = true; } - } else if (token.toLower() == "nullmove") { - getToken(uip, token); - if (token.toLower() == "value") { - getToken(uip, token); - knowCommand = true; - searchManager.setNullMove(token.toLower() == "true"); - } - } else if (token.toLower() == "uci_chess960") { + } else if (String::toLower(token) == "nullmove") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); knowCommand = true; - searchManager.setChess960(token.toLower() == "true"); + searchManager.setNullMove(String::toLower(token) == "true"); } - } else if (token.toLower() == "ownbook") { + } else if (String::toLower(token) == "uci_chess960") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); - it->setUseBook(token.toLower() == "true"); knowCommand = true; + searchManager.setChess960(String::toLower(token) == "true"); } - } else if (token.toLower() == "book") { - getToken(uip, token); - if (token.toLower() == "file") { - getToken(uip, token); - if (token.toLower() == "value") { - getToken(uip, token); - it->loadBook(token); - knowCommand = true; - } - } - } else if (token.toLower() == "ponder") { + } else if (String::toLower(token) == "ponder") { getToken(uip, token); - if (token.toLower() == "value") { + if (String::toLower(token) == "value") { getToken(uip, token); it->enablePonder(token == "true"); knowCommand = true; } - } else if (token.toLower() == "clear") { + } else if (String::toLower(token) == "clear") { getToken(uip, token); - if (token.toLower() == "hash") { + if (String::toLower(token) == "hash") { knowCommand = true; hash.clearHash(); } } } - } else if (token.toLower() == "position") { + } else if (String::toLower(token) == "position") { while (it->getRunning()); knowCommand = true; searchManager.setRepetitionMapCount(0); getToken(uip, token); _Tmove move; - if (token.toLower() == "startpos") { - it->setUseBook(it->getUseBook()); - searchManager.loadFen(); + if (String::toLower(token) == "startpos") { + searchManager.loadFen(STARTPOS); getToken(uip, token); } - if (token.toLower() == "fen") { + if (String::toLower(token) == "fen") { string fen; - while (token.toLower() != "moves" && !uip.eof()) { + while (String::toLower(token) != "moves" && !uip.eof()) { getToken(uip, token); fen.append(token); fen.append(" "); @@ -264,7 +239,7 @@ void Uci::listner(IterativeDeeping *it) { searchManager.setSide(x); searchManager.pushStackMove(); } - if (token.toLower() == "moves") { + if (String::toLower(token) == "moves") { while (!uip.eof()) { getToken(uip, token); if (!token.empty()) { @@ -275,7 +250,7 @@ void Uci::listner(IterativeDeeping *it) { } } - } else if (token.toLower() == "go") { + } else if (String::toLower(token) == "go") { it->setMaxDepth(MAX_PLY); searchManager.unsetSearchMoves(); int wtime = 200000; //5 min @@ -286,15 +261,15 @@ void Uci::listner(IterativeDeeping *it) { bool setMovetime = false; while (!uip.eof()) { getToken(uip, token); - if (token.toLower() == "wtime") { + if (String::toLower(token) == "wtime") { uip >> wtime; - } else if (token.toLower() == "btime") { + } else if (String::toLower(token) == "btime") { uip >> btime; - } else if (token.toLower() == "winc") { + } else if (String::toLower(token) == "winc") { uip >> winc; - } else if (token.toLower() == "binc") { + } else if (String::toLower(token) == "binc") { uip >> binc; - } else if (token.toLower() == "depth") { + } else if (String::toLower(token) == "depth") { int depth; uip >> depth; if (depth > MAX_PLY) { @@ -305,23 +280,23 @@ void Uci::listner(IterativeDeeping *it) { } it->setMaxDepth(depth); forceTime = true; - } else if (token.toLower() == "movetime") { + } else if (String::toLower(token) == "movetime") { int tim; uip >> tim; setMovetime = true; searchManager.setMaxTimeMillsec(tim); forceTime = true; - } else if (token.toLower() == "infinite") { + } else if (String::toLower(token) == "infinite") { searchManager.setMaxTimeMillsec(0x7FFFFFFF); forceTime = true; - } else if (token.toLower() == "searchmoves") { + } else if (String::toLower(token) == "searchmoves") { vector searchmoves; while (!uip.eof()) { uip >> token; searchmoves.push_back(token); } searchManager.setSearchMoves(searchmoves); - } else if (token.toLower() == "ponder") { + } else if (String::toLower(token) == "ponder") { searchManager.setPonder(true); } } diff --git a/src/Uci.h b/src/Uci.h index b26e2746..56fb2968 100644 --- a/src/Uci.h +++ b/src/Uci.h @@ -20,15 +20,15 @@ #include "IterativeDeeping.h" #include -#include "util/String.h" +#include "namespaces/String.h" -class Uci: public Singleton { +class Uci : public Singleton { friend class Singleton; private: Uci(); - Hash& hash = Hash::getInstance(); + Hash &hash = Hash::getInstance(); SearchManager &searchManager = Singleton::getInstance(); @@ -36,7 +36,7 @@ class Uci: public Singleton { void listner(IterativeDeeping *it); - void getToken(istringstream &uip, String &token); + void getToken(istringstream &uip, string &token) const; void startListner(); diff --git a/src/WrapperCinnamon.cpp b/src/WrapperCinnamon.cpp index 0d1c6c53..bb7f88a9 100644 --- a/src/WrapperCinnamon.cpp +++ b/src/WrapperCinnamon.cpp @@ -15,7 +15,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifdef JS_MODE + +// Auriga, JS etc. #include "WrapperCinnamon.h" vector WrapperCinnamon::getSuccessorsFen(const string &fen, const int depth) { @@ -30,7 +31,6 @@ unsigned WrapperCinnamon::perft(const string &fen, const int depth) { bool WrapperCinnamon::isValid(const string &fen) const { ChessBoard a; - if (a.loadFen(fen) == -1)return false; - return true; + return a.loadFen(fen) != -1; } -#endif + diff --git a/src/WrapperCinnamon.h b/src/WrapperCinnamon.h index c20fda74..69a31800 100644 --- a/src/WrapperCinnamon.h +++ b/src/WrapperCinnamon.h @@ -17,7 +17,7 @@ */ #pragma once -#ifdef JS_MODE +// Auriga, JS etc. #include #include #include "perft/PerftThread.h" @@ -33,4 +33,3 @@ class WrapperCinnamon { bool isValid(const string &fen) const; }; -#endif \ No newline at end of file diff --git a/src/cinnamon.vcxproj b/src/cinnamon.vcxproj new file mode 100644 index 00000000..7a53b6b7 --- /dev/null +++ b/src/cinnamon.vcxproj @@ -0,0 +1,373 @@ + + + + x64 + + + + Debug + x64 + + + Release + x64 + + + MinSizeRel + x64 + + + RelWithDebInfo + x64 + + + + {7600E37A-3D09-3C2D-B42C-0F76F2AA54C1} + 10.0.18362.0 + Win32Proj + x64 + cinnamon + NoUpgrade + + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + + + + + + + + <_ProjectFileVersion>10.0.20506.1 + .\Debug\ + cinnamon.dir\Debug\ + cinnamon + .exe + true + true + .\Release\ + cinnamon.dir\Release\ + cinnamon + .exe + false + true + .\MinSizeRel\ + cinnamon.dir\MinSizeRel\ + cinnamon + .exe + false + true + .\RelWithDebInfo\ + cinnamon.dir\RelWithDebInfo\ + cinnamon + .exe + true + true + + + + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + %(AdditionalOptions) + $(IntDir) + EnableFastChecks + ProgramDatabase + Sync + Disabled + Disabled + NotUsing + MultiThreadedDebugDLL + true + false + Level3 + WIN32;_WINDOWS;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions) + $(IntDir) + + + WIN32;_DEBUG;_WINDOWS;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions) + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + + + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + $(ProjectDir)/$(IntDir) + %(Filename).h + %(Filename).tlb + %(Filename)_i.c + %(Filename)_p.c + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib + %(AdditionalLibraryDirectories) + %(AdditionalOptions) /machine:x64 + true + %(IgnoreSpecificDefaultLibraries) + ./Debug/cinnamon.lib + ./Debug/cinnamon.pdb + Console + + + false + + + + + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + %(AdditionalOptions) + $(IntDir) + Sync + AnySuitable + MaxSpeed + NotUsing + MultiThreadedDLL + true + false + TurnOffAllWarnings + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";HAS_POPCNT;HAS_BSF;USE_BMI2xxx;%(PreprocessorDefinitions) + $(IntDir) + + + + + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions) + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + + + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + $(ProjectDir)/$(IntDir) + %(Filename).h + %(Filename).tlb + %(Filename)_i.c + %(Filename)_p.c + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib + %(AdditionalLibraryDirectories) + %(AdditionalOptions) /machine:x64 + false + %(IgnoreSpecificDefaultLibraries) + ./Release/cinnamon.lib + ./Release/cinnamon.pdb + Console + + + false + + + true + + + + + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + %(AdditionalOptions) + $(IntDir) + Sync + OnlyExplicitInline + MinSpace + NotUsing + MultiThreadedDLL + true + false + Level3 + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="MinSizeRel";%(PreprocessorDefinitions) + $(IntDir) + + + + + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"MinSizeRel\";%(PreprocessorDefinitions) + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + + + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + $(ProjectDir)/$(IntDir) + %(Filename).h + %(Filename).tlb + %(Filename)_i.c + %(Filename)_p.c + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib + %(AdditionalLibraryDirectories) + %(AdditionalOptions) /machine:x64 + false + %(IgnoreSpecificDefaultLibraries) + ./MinSizeRel/cinnamon.lib + ./MinSizeRel/cinnamon.pdb + Console + + + false + + + + + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + %(AdditionalOptions) + $(IntDir) + ProgramDatabase + Sync + OnlyExplicitInline + MaxSpeed + NotUsing + MultiThreadedDLL + true + false + Level3 + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="RelWithDebInfo";%(PreprocessorDefinitions) + $(IntDir) + + + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"RelWithDebInfo\";%(PreprocessorDefinitions) + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + + + .\db\gtb;.\db\gtb\compression;.\db\gtb\compression\lzma;.\db\gtb\sysport;%(AdditionalIncludeDirectories) + $(ProjectDir)/$(IntDir) + %(Filename).h + %(Filename).tlb + %(Filename)_i.c + %(Filename)_p.c + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib + %(AdditionalLibraryDirectories) + %(AdditionalOptions) /machine:x64 + true + %(IgnoreSpecificDefaultLibraries) + ./RelWithDebInfo/cinnamon.lib + ./RelWithDebInfo/cinnamon.pdb + Console + + + false + + + + + UTF-8 + Building Custom Rule ./CMakeLists.txt + .\CMakeFiles\generate.stamp + false + Building Custom Rule ./CMakeLists.txt + false + Building Custom Rule ./CMakeLists.txt + .\CMakeFiles\generate.stamp + false + Building Custom Rule ./CMakeLists.txt + .\CMakeFiles\generate.stamp + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {E11CC2AA-5310-364C-8380-EB0F52FF6F31} + ZERO_CHECK + false + Never + + + + + + diff --git a/src/db/OpenBook.cpp b/src/db/OpenBook.cpp deleted file mode 100644 index 0cee01ed..00000000 --- a/src/db/OpenBook.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - Cinnamon UCI chess engine - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/// Some code is released in the public domain by Michel Van den Bergh. - -#include "OpenBook.h" - -OpenBook::OpenBook() : openBookFile(nullptr), Random64(nullptr) { - srand(time(NULL)); -} - -void OpenBook::dispose() { - if (openBookFile) { - fclose(openBookFile); - openBookFile = nullptr; - } - if (Random64) { - free(Random64); - } - - Random64 = nullptr; -} - -OpenBook::~OpenBook() { - dispose(); -} - -u64 OpenBook::createKey(string fen1) { - const char *fen = fen1.c_str(); - u64 *RandomPiece = Random64; - u64 *RandomCastle = Random64 + 768; - u64 *RandomEnPassant = Random64 + 772; - u64 *RandomTurn = Random64 + 780; - static const char *piece_names = "pPnNbBrRqQkK"; - char board_s[72 + 1]; - char to_move_c; - char castle_flags_s[4 + 1]; - char ep_square_s[2 + 1]; - char board[8][8]; - char c; - int r, f, i, p_enc; - unsigned p; - u64 key = 0; - sscanf(fen, "%72s %c %4s %2s", board_s, &to_move_c, castle_flags_s, ep_square_s); - r = 7; - f = 0; - p = 0; - while (1) { - if (p >= strlen(board_s)) { - break; - } - c = board_s[p++]; - if (c == '/') { - r--; - f = 0; - continue; - } - if (('1' <= c) && ('8' >= c)) { - for (i = 0; i <= c - '1'; i++) { - board[f++][r] = '-'; - } - continue; - } - board[f++][r] = c; - } - for (f = 0; f <= 7; f++) { - for (r = 0; r <= 7; r++) { - c = board[f][r]; - if (c != '-') { - p_enc = strchr(piece_names, c) - piece_names; - key ^= RandomPiece[64 * p_enc + 8 * r + f]; - } - } - } - p = 0; - while (1) { - if (p >= strlen(castle_flags_s)) { - break; - } - c = castle_flags_s[p++]; - switch (c) { - case '-': - break; - case 'K': - key ^= RandomCastle[0]; - break; - case 'Q': - key ^= RandomCastle[1]; - break; - case 'k': - key ^= RandomCastle[2]; - break; - case 'q': - key ^= RandomCastle[3]; - break; - default: - break; - } - } - if (ep_square_s[0] != '-') { - f = ep_square_s[0] - 'a'; - if (to_move_c == 'b') { - if ((f > 0 && board[f - 1][3] == 'p') || (f < 7 && board[f + 1][3] == 'p')) { - key ^= RandomEnPassant[f]; - } - } else { - if ((f > 0 && board[f - 1][4] == 'P') || (f < 7 && board[f + 1][4] == 'P')) { - key ^= RandomEnPassant[f]; - } - } - } - if (to_move_c == 'w') { - key ^= RandomTurn[0]; - } - return key; -} - -int OpenBook::intFromFile(const int l, u64 *r) { - int c; - for (int i = 0; i < l; i++) { - c = fgetc(openBookFile); - if (c == EOF) { - return 1; - } - (*r) = ((*r) << 8) + c; - } - return 0; -} - -int OpenBook::entryFromFile(entry_t *entry) { - u64 r = 0; - if (intFromFile(8, &r)) { - return 1; - } - entry->key = r; - if (intFromFile(2, &r)) { - return 1; - } - entry->move = r; - if (intFromFile(2, &r)) { - return 1; - } - entry->weight = r; - if (intFromFile(4, &r)) { - return 1; - } - entry->learn = r; - return 0; -} - -int OpenBook::findKey(const u64 key, entry_t *entry) { - int first, last, middle; - static constexpr entry_t entry_none = {0, 0, 0, 0}; - entry_t last_entry, middle_entry; - first = -1; - if (fseek(openBookFile, -16, SEEK_END)) { - *entry = entry_none; - entry->key = key + 1; - return -1; - } - last = ftell(openBookFile) / 16; - entryFromFile(&last_entry); - while (1) { - if (last - first == 1) { - *entry = last_entry; - return last; - } - middle = (first + last) / 2; - fseek(openBookFile, 16 * middle, SEEK_SET); - entryFromFile(&middle_entry); - if (key <= middle_entry.key) { - last = middle; - last_entry = middle_entry; - } else { - first = middle; - } - } -} - -void OpenBook::moveToString(char move_s[6], const unsigned short move) { - const static char *promote_pieces = " nbrq"; - int f, fr, ff, t, tr, tf, p; - f = (move >> 6) & 077; - fr = (f >> 3) & 0x7; - ff = f & 0x7; - t = move & 077; - tr = (t >> 3) & 0x7; - tf = t & 0x7; - p = (move >> 12) & 0x7; - move_s[0] = ff + 'a'; - move_s[1] = fr + '1'; - move_s[2] = tf + 'a'; - move_s[3] = tr + '1'; - if (p) { - move_s[4] = promote_pieces[p]; - move_s[5] = '\0'; - } else { - move_s[4] = '\0'; - } - if (!strcmp(move_s, "e1h1")) { - strcpy(move_s, "e1g1"); - } else if (!strcmp(move_s, "e1a1")) { - strcpy(move_s, "e1c1"); - } else if (!strcmp(move_s, "e8h8")) { - strcpy(move_s, "e8g8"); - } else if (!strcmp(move_s, "e8a8")) { - strcpy(move_s, "e8c8"); - } -} - -string OpenBook::search(string fen) { - u64 key = createKey(fen); - entry_t entry; - char move_s[6]; - findKey(key, &entry); - if (entry.key != key) { - return string(); - } - moveToString(move_s, entry.move); - return move_s; -} diff --git a/src/db/OpenBook.h b/src/db/OpenBook.h deleted file mode 100644 index b4abb09e..00000000 --- a/src/db/OpenBook.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Cinnamon UCI chess engine - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#pragma once - -#include -#include "../Eval.h" - -class OpenBook: public Singleton { - friend class Singleton; - -public: - static OpenBook &getInstance() = delete; - - static OpenBook *getInstance(const string &fileName) { - - if (!FileUtil::fileExists(fileName)) { - cout << fileName << " not found" << endl; - return nullptr; - } - - static OpenBook openBook; - - openBook.openBookFile = fopen(fileName.c_str(), "rb"); - openBook.Random64 = (u64 *) malloc(781 * sizeof(u64)); - int k = 0; - for (int i = 0; i < 15 && k < 781; i++) { - for (int j = 0; j < 64 && k < 781; j++) { - openBook.Random64[k++] = _random::RANDOM_KEY[i][j]; - } - } - return &openBook; - } - - virtual ~OpenBook(); - - - string search(string fen); - - void dispose(); - -private: - OpenBook(); - - typedef struct { - u64 key; - unsigned short move; - unsigned short weight; - unsigned learn; - } entry_t; - - FILE *openBookFile; - - u64 createKey(string fen); - - int intFromFile(const int l, u64 *r); - - int entryFromFile(entry_t *entry); - - int findKey(const u64 key, entry_t *entry); - - void moveToString(char move_s[6], const unsigned short move); - - u64 *Random64; -}; - diff --git a/src/db/bitbase/kpk.h b/src/db/bitbase/kpk.h deleted file mode 100644 index 701719fa..00000000 --- a/src/db/bitbase/kpk.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - Cinnamon UCI chess engine - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#pragma once -#include "../../namespaces/bits.h" -using namespace _def; - -namespace _bitbase { - - static constexpr u64 KPK_BLACK_PAWN[2][64][64] = { - { - {0x0ull,0x203000000000000ull,0x101010101010100ull,0x101010101030100ull,0x303030303030100ull,0x303030303030100ull,0x707070707070100ull,0x707070707070100ull,0x203000000000000ull,0x203000000000000ull,0x101010101010100ull,0x101010101010100ull,0x101010303030100ull,0x101030303030100ull,0x303070707070100ull,0x707070707070100ull,0x101010101020100ull,0x101010101010100ull,0x101010101030100ull,0x101010101010100ull,0x101010303030100ull,0x101030303030100ull,0x303070707070100ull,0x707070707070100ull,0x101010100010100ull,0x101010101010100ull,0x101010101010100ull,0x101010101010100ull,0x101010303030100ull,0x101030303030100ull,0x303070707070100ull,0x707070707070100ull,0x101011e07030100ull,0x101010107030100ull,0x101010103030100ull,0x101010103030100ull,0x101010303030100ull,0x101030303030100ull,0x303070707070100ull,0x707070707070100ull,0x101001f0f070100ull,0x10101070f070100ull,0x101010307070100ull,0x101010307070100ull,0x101010307070100ull,0x101030307070100ull,0x303070707070100ull,0x707070707070100ull,0x7003f1f0f070100ull,0x101070f0f070100ull,0x10103070f070100ull,0x10103070f070100ull,0x10103070f070100ull,0x10103070f070100ull,0x30307070f070100ull,0x70707070f070100ull,0x13f1f0f070100ull,0x1010f1f0f070100ull,0x101070f0f070100ull,0x101070f0f070100ull,0x101070f0f070100ull,0x101070f0f070100ull,0x103070f0f070100ull,0x307070f0f070100ull}, - {0x203000000000000ull,0x0ull,0x203000000000000ull,0x303030303030200ull,0x303030303030200ull,0x707070707070200ull,0x707070707070200ull,0xf0f0f0f0f0f0200ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x101010101030000ull,0x101010303030200ull,0x101030707070200ull,0x303070707070200ull,0x7070f0f0f0f0200ull,0x101010101000200ull,0x101010101050000ull,0x101010101010200ull,0x101010101030000ull,0x101010303030200ull,0x101030707070200ull,0x303070707070200ull,0x7070f0f0f0f0200ull,0x101010100030000ull,0x101010101030000ull,0x101010101030000ull,0x101010101030000ull,0x101010303030200ull,0x101030707070200ull,0x303070707070200ull,0x7070f0f0f0f0200ull,0x101013e1f070200ull,0x101013d0f070200ull,0x10101030f070200ull,0x101010307070200ull,0x101010307070200ull,0x101030707070200ull,0x303070707070200ull,0x7070f0f0f0f0200ull,0x101003f1f0f0200ull,0x101013f1f0f0200ull,0x101010f1f0f0200ull,0x10101070f0f0200ull,0x10101070f0f0200ull,0x10103070f0f0200ull,0x30307070f0f0200ull,0x7070f0f0f0f0200ull,0x7007f3f1f0f0200ull,0x1017f3f1f0f0200ull,0x1010f1f1f0f0200ull,0x101070f1f0f0200ull,0x101070f1f0f0200ull,0x101070f1f0f0200ull,0x303070f1f0f0200ull,0x7070f0f1f0f0200ull,0x17f3f1f0f0200ull,0x1017f3f1f0f0200ull,0x1011f3f1f0f0200ull,0x1010f1f1f0f0200ull,0x1010f1f1f0f0200ull,0x1010f1f1f0f0200ull,0x1030f1f1f0f0200ull,0x3070f1f1f0f0200ull}, - {0xfdfdfd7d3d1d0500ull,0x203000000000000ull,0x0ull,0x0ull,0x707070707070400ull,0x707070707070400ull,0xf0f0f0f0f0f0400ull,0xf0f0f0f0f0f0400ull,0xe1e1f179391d0000ull,0x1000000000000ull,0x1000000000000ull,0x1000000000000ull,0x101010303070000ull,0x101030707070400ull,0x303070f0f0f0400ull,0x7070f0f0f0f0400ull,0xe1e1f179391c0000ull,0x8181810101000400ull,0x81818101010a0000ull,0x101010101010400ull,0x101010303070000ull,0x101030707070400ull,0x303070f0f0f0400ull,0x7070f0f0f0f0400ull,0xe1e1f179381d0000ull,0x8181810101050000ull,0x8181810101050000ull,0x101010101050000ull,0x101010303070000ull,0x101030707070400ull,0x303070f0f0f0400ull,0x7070f0f0f0f0400ull,0xe1e1f17c3f1f0400ull,0x8181817d3f0f0400ull,0x8181817b1f0f0400ull,0x10101071f0f0400ull,0x10101070f0f0400ull,0x10103070f0f0400ull,0x303070f0f0f0400ull,0x7070f0f0f0f0400ull,0xe1e1f07f3f1f0400ull,0x8181817f3f1f0400ull,0x8181817f3f1f0400ull,0x8181811f3f1f0400ull,0x8181810f1f1f0400ull,0x8181830f1f1f0400ull,0x8383870f1f1f0400ull,0x87870f0f1f1f0400ull,0xe7e0ff7f3f1f0400ull,0x8181ff7f3f1f0400ull,0x8181ff7f3f1f0400ull,0x81819f3f3f1f0400ull,0x81818f1f3f1f0400ull,0x81818f1f3f1f0400ull,0x83838f1f3f1f0400ull,0xe7078f1f3f1f0400ull,0x80e1ff7f3f1f0400ull,0x8181ff7f3f1f0400ull,0x8181ff7f3f1f0400ull,0x8181bf7f3f1f0400ull,0x81819f3f3f1f0400ull,0x81819f3f3f1f0400ull,0x81839f3f3f1f0400ull,0x3879f3f3f1f0400ull}, - {0xf8f8f8f878380800ull,0xf8f8f8f878380800ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f0f0e0800ull,0xf0f0f0f0f0e0800ull,0x1f1f1f1f1f1e0800ull,0xe0e0f0f878380800ull,0xc0c0e0f070380000ull,0x0ull,0x0ull,0x0ull,0x1010307070e0000ull,0x303070f0f0e0800ull,0x7070f1f1f1e0800ull,0xe0e0f0f878380800ull,0xc0c0e0f070380000ull,0x8080808000000800ull,0x8181818101140000ull,0x101010101000800ull,0x1010307070e0000ull,0x303070f0f0e0800ull,0x7070f1f1f1e0800ull,0xe1e1f1f978380800ull,0xc1c1e1f171380000ull,0x8181818101080000ull,0x8181818101080000ull,0x101010101080000ull,0x1010307070e0000ull,0x303070f0f0e0800ull,0x7070f1f1f1e0800ull,0xe1e1f1f87d3c0800ull,0xc1c1e1f97d3c0800ull,0x818181f97f1c0800ull,0x818181f73f1c0800ull,0x8181818f3f1c0800ull,0x8181838f1f1e0800ull,0x8383878f1f1e0800ull,0x87878f1f1f1e0800ull,0xe1e1f0fd7f3e0800ull,0xc1c1e1fd7f3e0800ull,0x818181ff7f3e0800ull,0x818181ff7f3e0800ull,0x818181bf7f3e0800ull,0x8181839f3f3e0800ull,0x8383879f3f3e0800ull,0x87870f9f3f3e0800ull,0xe7e0fdff7f3e0800ull,0xc1c1fdff7f3e0800ull,0x8181ffff7f3e0800ull,0x8181ffff7f3e0800ull,0x8181bfff7f3e0800ull,0x81819fbf7f3e0800ull,0x83839fbf7f3e0800ull,0xe7079fbf7f3e0800ull,0xc0e1ffff7f3e0800ull,0x81c1ffff7f3e0800ull,0x8181ffff7f3e0800ull,0x8181ffff7f3e0800ull,0x8181ffff7f3e0800ull,0x8181bfff7f3e0800ull,0x8183bfff7f3e0800ull,0x387bfff7f3e0800ull}, - {0xf8f8f8f8f8781000ull,0xf0f0f0f0f0701000ull,0xf0f0f0f0f0701000ull,0x0ull,0x0ull,0x0ull,0x1f1f1f1f1e1c1000ull,0x1f1f1f1f1e1c1000ull,0xe0e0f0f8f8781000ull,0xc0c0e0f0f0701000ull,0x8080c0e0e0700000ull,0x0ull,0x0ull,0x0ull,0x303070f0e1c0000ull,0x7070f1f1e1c1000ull,0xe0e0f0f8f8781000ull,0xc0c0e0f0f0701000ull,0x8080c0e0e0700000ull,0x8080808080001000ull,0x8181818180280000ull,0x101010100001000ull,0x303070f0e1c0000ull,0x7070f1f1e1c1000ull,0xe0e0f0f8f8781000ull,0xc0c0e0f0f0701000ull,0x8080c0e0e0700000ull,0x8080808080100000ull,0x8181818180100000ull,0x8181818180100000ull,0x8383878f8e1c0000ull,0x87878f9f1e1c1000ull,0xe1e1f1f8f8781000ull,0xc1c1e1f1f8781000ull,0x8181c1f1f8781000ull,0x818181f1fc381000ull,0x818181effc381000ull,0x8181819ffe381000ull,0x8383879fbe3c1000ull,0x87878f1fbe3c1000ull,0xe1e1f0f9fc7c1000ull,0xc1c1e1f9fc7c1000ull,0x8181c1f9fc7c1000ull,0x818181fdfe7c1000ull,0x818181fffe7c1000ull,0x818181fffe7c1000ull,0x838387bffe7c1000ull,0x87870fbffe7c1000ull,0xe7e0f9fdfe7c1000ull,0xc1c1f9fdfe7c1000ull,0x8181f9fdfe7c1000ull,0x8181fdfffe7c1000ull,0x8181fffffe7c1000ull,0x8181fffffe7c1000ull,0x8383bffffe7c1000ull,0xe707bffffe7c1000ull,0xc0e1fdfffe7c1000ull,0x81c1fdfffe7c1000ull,0x8181fdfffe7c1000ull,0x8181fffffe7c1000ull,0x8181fffffe7c1000ull,0x8181fffffe7c1000ull,0x8183fffffe7c1000ull,0x387fffffe7c1000ull}, - {0xf0f0f0f0f0f02000ull,0xf0f0f0f0f0f02000ull,0xe0e0e0e0e0e02000ull,0xe0e0e0e0e0e02000ull,0x0ull,0x0ull,0x0ull,0xbfbfbfbebcb8a000ull,0xe0e0f0f0f0f02000ull,0xc0c0e0f0f0f02000ull,0x8080c0e0e0e02000ull,0x808080c0c0e00000ull,0x0ull,0x0ull,0x0ull,0x87878f9e9cb80000ull,0xe0e0f0f0f0f02000ull,0xc0c0e0f0f0f02000ull,0x8080c0e0e0e02000ull,0x808080c0c0e00000ull,0x8080808080802000ull,0x8181818080500000ull,0x8181818080002000ull,0x87878f9e9c380000ull,0xe0e0f0f0f0f02000ull,0xc0c0e0f0f0f02000ull,0x8080c0e0e0e02000ull,0x808080c0c0e00000ull,0x8080808080a00000ull,0x8181818080a00000ull,0x8181818080a00000ull,0x87878f9e1cb80000ull,0xe0e0f0f0f0f02000ull,0xc0c0e0f0f0f02000ull,0x8080c0e0f0f02000ull,0x808080e0f0f02000ull,0x808080e0f8f02000ull,0x818181def8f02000ull,0x818181befcf02000ull,0x87878f3efcf82000ull,0xe1e1f0f0f8f82000ull,0xc1c1e1f0f8f82000ull,0x8181c1f0f8f82000ull,0x818181f0f8f82000ull,0x818181f8fcf82000ull,0x818181fefcf82000ull,0x818181fefcf82000ull,0x87870ffefcf82000ull,0xe7e0f1f8fcf82000ull,0xc1c1f1f8fcf82000ull,0x8181f1f8fcf82000ull,0x8181f1f8fcf82000ull,0x8181f9fcfcf82000ull,0x8181fffefcf82000ull,0x8181fffefcf82000ull,0xe707fffefcf82000ull,0xc0e1f9fcfcf82000ull,0x81c1f9fcfcf82000ull,0x8181f9fcfcf82000ull,0x8181f9fcfcf82000ull,0x8181fdfefcf82000ull,0x8181fffefcf82000ull,0x8181fffefcf82000ull,0x187fffefcf82000ull}, - {0xf0f0f0f0f0f04000ull,0xe0e0e0e0e0e04000ull,0xe0e0e0e0e0e04000ull,0xc0c0c0c0c0c04000ull,0xc0c0c0c0c0c04000ull,0x0ull,0x0ull,0x0ull,0xe0e0f0f0f0f04000ull,0xc0c0e0e0e0e04000ull,0x8080c0e0e0e04000ull,0x808080c0c0c04000ull,0x8080808080c00000ull,0x0ull,0x0ull,0x0ull,0xe0e0f0f0f0f04000ull,0xc0c0e0e0e0e04000ull,0x8080c0e0e0e04000ull,0x808080c0c0c04000ull,0x8080808080c00000ull,0x8080808080804000ull,0x8080808080a00000ull,0x8080808080004000ull,0xe0e0f0f0f0f04000ull,0xc0c0e0e0e0e04000ull,0x8080c0e0e0e04000ull,0x808080c0c0c04000ull,0x8080808080c00000ull,0x8080808080c00000ull,0x8080808080c00000ull,0x8080808000c00000ull,0xe0e0f0f0f0f04000ull,0xc0c0e0e0e0e04000ull,0x8080c0e0e0e04000ull,0x808080c0e0e04000ull,0x808080c0e0e04000ull,0x808080c0f0e04000ull,0x808080bcf0e04000ull,0x8080807cf8e04000ull,0xe0e0f0f0f0f04000ull,0xc0c0e0e0f0f04000ull,0x8080c0e0f0f04000ull,0x808080e0f0f04000ull,0x808080e0f0f04000ull,0x808080f0f8f04000ull,0x808080fcf8f04000ull,0x808000fcf8f04000ull,0xe0e0f0f0f8f04000ull,0xc0c0e0f0f8f04000ull,0x8080e0f0f8f04000ull,0x8080e0f0f8f04000ull,0x8080e0f0f8f04000ull,0x8080f0f8f8f04000ull,0x8080fefcf8f04000ull,0xe000fefcf8f04000ull,0xc0e0f0f8f8f04000ull,0x80c0f0f8f8f04000ull,0x8080f0f8f8f04000ull,0x8080f0f8f8f04000ull,0x8080f0f8f8f04000ull,0x8080f8fcf8f04000ull,0x8080fefcf8f04000ull,0x80fefcf8f04000ull}, - {0xe0e0e0e0e0e08000ull,0xe0e0e0e0e0e08000ull,0xc0c0c0c0c0c08000ull,0xc0c0c0c0c0c08000ull,0x8080808080c08000ull,0x8080808080808000ull,0x0ull,0x0ull,0xe0e0e0e0e0e08000ull,0xc0c0e0e0e0e08000ull,0x8080c0c0c0c08000ull,0x808080c0c0c08000ull,0x8080808080808000ull,0x8080808080808000ull,0x0ull,0x0ull,0xe0e0e0e0e0e08000ull,0xc0c0e0e0e0e08000ull,0x8080c0c0c0c08000ull,0x808080c0c0c08000ull,0x8080808080808000ull,0x8080808080c08000ull,0x8080808080808000ull,0x8080808080408000ull,0xe0e0e0e0e0e08000ull,0xc0c0e0e0e0e08000ull,0x8080c0c0c0c08000ull,0x808080c0c0c08000ull,0x8080808080808000ull,0x8080808080808000ull,0x8080808080808000ull,0x8080808000808000ull,0xe0e0e0e0e0e08000ull,0xc0c0e0e0e0e08000ull,0x8080c0c0c0c08000ull,0x808080c0c0c08000ull,0x80808080c0c08000ull,0x80808080c0c08000ull,0x80808080e0c08000ull,0x80808078e0c08000ull,0xe0e0e0e0e0e08000ull,0xc0c0e0e0e0e08000ull,0x8080c0c0e0e08000ull,0x808080c0e0e08000ull,0x808080c0e0e08000ull,0x808080c0e0e08000ull,0x808080e0f0e08000ull,0x808000f8f0e08000ull,0xe0e0e0e0f0e08000ull,0xc0c0e0e0f0e08000ull,0x8080c0e0f0e08000ull,0x8080c0e0f0e08000ull,0x8080c0e0f0e08000ull,0x8080c0e0f0e08000ull,0x8080e0f0f0e08000ull,0xe000fcf8f0e08000ull,0xc0e0e0f0f0e08000ull,0x80c0e0f0f0e08000ull,0x8080e0f0f0e08000ull,0x8080e0f0f0e08000ull,0x8080e0f0f0e08000ull,0x8080e0f0f0e08000ull,0x8080f0f8f0e08000ull,0x80fcf8f0e08000ull}, - {0x203000000000000ull,0x203000000000000ull,0x101010101010000ull,0x101010101010000ull,0x303030303010200ull,0x303030303010200ull,0x707070707050200ull,0x707070707050200ull,0x0ull,0x203000000000000ull,0x101010101010000ull,0x101010101010000ull,0x303030303010200ull,0x303030303010200ull,0x707070707050200ull,0x707070707050200ull,0x203000000000000ull,0x203000000000000ull,0x101010101010000ull,0x101010101010000ull,0x101030303010200ull,0x303030303010200ull,0x707070707050200ull,0x707070707050200ull,0x101011f02010200ull,0x101010101010200ull,0x101010101010200ull,0x101010101010200ull,0x101030303010200ull,0x303030303010200ull,0x707070707050200ull,0x707070707050200ull,0x101010007010200ull,0x101010107010200ull,0x101010103010200ull,0x101010103010200ull,0x101030303010200ull,0x303030303010200ull,0x707070707050200ull,0x707070707050200ull,0x1013e1f0f050200ull,0x10101070f050200ull,0x101010307050200ull,0x101010307050200ull,0x101030307050200ull,0x303030307050200ull,0x707070707050200ull,0x707070707050200ull,0x7003f1f0f050200ull,0x101070f0f050200ull,0x10103070f050200ull,0x10103070f050200ull,0x10103070f050200ull,0x30303070f050200ull,0x70707070f050200ull,0x370707070f050200ull,0xe3f3f1f0f050200ull,0x5070f1f0f050200ull,0x303070f0f050200ull,0x303070f0f050200ull,0x303070f0f050200ull,0x303070f0f050200ull,0x307070f0f050200ull,0x707070f0f050200ull}, - {0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x303030303020100ull,0x303030303020100ull,0x707070707020500ull,0x707070707020500ull,0xf0f0f0f0f0a0500ull,0x203000000000000ull,0x0ull,0x203000000000000ull,0x303030303020100ull,0x303030303020100ull,0x707070707020500ull,0x707070707020500ull,0xf0f0f0f0f0a0500ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x101010303020100ull,0x101030303020100ull,0x303070707020500ull,0x707070707020500ull,0xf0f0f0f0f0a0500ull,0x10101011e020500ull,0x101013f05020500ull,0x101010103020500ull,0x101010303020500ull,0x101030303020500ull,0x303070707020500ull,0x707070707020500ull,0xf0f0f0f0f0a0500ull,0x10101001f020500ull,0x10101010f020500ull,0x10101010f020500ull,0x101010307020500ull,0x101030307020500ull,0x303070707020500ull,0x707070707020500ull,0xf0f0f0f0f0a0500ull,0x1017e3f1f0a0500ull,0x1017d3f1f0a0500ull,0x101030f1f0a0500ull,0x10103070f0a0500ull,0x10103070f0a0500ull,0x30307070f0a0500ull,0x70707070f0a0500ull,0xf0f0f0f0f0a0500ull,0xf007f3f1f0a0500ull,0x1017f3f1f0a0500ull,0x1010f1f1f0a0500ull,0x101070f1f0a0500ull,0x101070f1f0a0500ull,0x303070f1f0a0500ull,0x707070f1f0a0500ull,0x7f0f0f0f1f0a0500ull,0x7e7f7f3f1f0a0500ull,0xd7f7f3f1f0a0500ull,0xb0f1f3f1f0a0500ull,0x7070f1f1f0a0500ull,0x7070f1f1f0a0500ull,0x7070f1f1f0a0500ull,0x7070f1f1f0a0500ull,0x70f0f1f1f0a0500ull}, - {0xfdfdfd7d3d150900ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x707070707050200ull,0x707070707050200ull,0xf0f0f0f0f050a00ull,0xf0f0f0f0f050a00ull,0xfdfdfd7d3d150800ull,0x203000000000000ull,0x0ull,0x0ull,0x707070707050200ull,0x707070707050200ull,0xf0f0f0f0f050a00ull,0xf0f0f0f0f050a00ull,0xf1f1f97d3d140800ull,0x1000000000000ull,0x1000000000000ull,0x1000000000000ull,0x101030707050200ull,0x303070707050200ull,0x7070f0f0f050a00ull,0xf0f0f0f0f050a00ull,0xf1f1f97d3c150a00ull,0x818181013d050a00ull,0x8181817f0b050a00ull,0x101010107050a00ull,0x101030707050a00ull,0x303070707050a00ull,0x7070f0f0f050a00ull,0xf0f0f0f0f050a00ull,0xf1f1f97c3f150a00ull,0x818181013f050a00ull,0x818181011f050a00ull,0x10101011f050a00ull,0x10103070f050a00ull,0x30307070f050a00ull,0x7070f0f0f050a00ull,0xf0f0f0f0f050a00ull,0xf1f1fc7f3f150a00ull,0x8181fd7f3f150a00ull,0x8181fb7f3f150a00ull,0x8181871f3f150a00ull,0x8181870f1f150a00ull,0x8383870f1f150a00ull,0x87878f0f1f150a00ull,0x8f8f0f0f1f150a00ull,0xfff0ff7f3f150a00ull,0x8181ff7f3f150a00ull,0x8181ff7f3f150a00ull,0x81819f3f3f150a00ull,0x81818f1f3f150a00ull,0x83838f1f3f150a00ull,0x87878f1f3f150a00ull,0xff0f8f1f3f150a00ull,0xfeffff7f3f150a00ull,0xfdffff7f3f150a00ull,0x9bffff7f3f150a00ull,0x879fbf7f3f150a00ull,0x8f8f9f3f3f150a00ull,0x8f8f9f3f3f150a00ull,0x8f8f9f3f3f150a00ull,0xf8f9f3f3f150a00ull}, - {0xf8f8f8f878281000ull,0xf8f8f8f878281000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f0f0a0400ull,0xf0f0f0f0f0a0400ull,0x1f1f1f1f1f0a1400ull,0xf8f8f8f878281000ull,0xf8f8f8f878281000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f0f0a0400ull,0xf0f0f0f0f0a0400ull,0x1f1f1f1f1f0a1400ull,0xf0f0f8f878281000ull,0xe0e0f0f878281000ull,0x0ull,0x0ull,0x0ull,0x303070f0f0a0400ull,0x7070f0f0f0a0400ull,0xf0f1f1f1f0a1400ull,0xf1f1f9f978281400ull,0xe1e1f1f979281400ull,0x8181818179081400ull,0x818181ff15081400ull,0x10101010f081400ull,0x303070f0f0a1400ull,0x7070f0f0f0a1400ull,0xf0f1f1f1f0a1400ull,0xf1f1f9f87d281400ull,0xe1e1f1f97d281400ull,0x818181817f081400ull,0x818181813f081400ull,0x818181813f081400ull,0x8383878f1f0a1400ull,0x87878f8f1f0a1400ull,0x8f8f9f1f1f0a1400ull,0xf1f1f8fd7f2a1400ull,0xe1e1f9fd7f2a1400ull,0x8181f9ff7f2a1400ull,0x8181f7ff7f2a1400ull,0x81818fbf7f2a1400ull,0x83838f9f3f2a1400ull,0x87878f9f3f2a1400ull,0x8f8f1f9f3f2a1400ull,0xfff0fdff7f2a1400ull,0xe1e1fdff7f2a1400ull,0x8181ffff7f2a1400ull,0x8181ffff7f2a1400ull,0x8181bfff7f2a1400ull,0x83839fbf7f2a1400ull,0x87879fbf7f2a1400ull,0xff0f9fbf7f2a1400ull,0xfcfdffff7f2a1400ull,0xfdfdffff7f2a1400ull,0xf9ffffff7f2a1400ull,0xb7ffffff7f2a1400ull,0x8fbfffff7f2a1400ull,0x9f9fbfff7f2a1400ull,0x9f9fbfff7f2a1400ull,0x1f9fbfff7f2a1400ull}, - {0xf8f8f8f8f8502800ull,0xf0f0f0f0f0502000ull,0xf0f0f0f0f0502000ull,0x0ull,0x0ull,0x0ull,0x1f1f1f1f1e140800ull,0x1f1f1f1f1e140800ull,0xf8f8f8f8f8502800ull,0xf0f0f0f0f0502000ull,0xf0f0f0f0f0502000ull,0x0ull,0x0ull,0x0ull,0x1f1f1f1f1e140800ull,0x1f1f1f1f1e140800ull,0xf0f0f8f8f8502800ull,0xe0e0f0f0f0502000ull,0xc0c0e0f0f0502000ull,0x0ull,0x0ull,0x0ull,0x7070f1f1e140800ull,0xf0f1f1f1e140800ull,0xf0f0f8f8f8502800ull,0xe0e0f0f0f0502800ull,0xc0c0e0f0f0502800ull,0x80808080f0102800ull,0x818181ffa8102800ull,0x818181819e102800ull,0x87878f9f9e142800ull,0x8f8f9f9f1e142800ull,0xf1f1f9f8f8502800ull,0xe1e1f1f1f8502800ull,0xc1c1e1f1f8502800ull,0x81818181fc102800ull,0x81818181fc102800ull,0x81818181fe102800ull,0x87878f9fbe142800ull,0x8f8f9f1fbe142800ull,0xf1f1f8f9fc542800ull,0xe1e1f1f9fc542800ull,0xc1c1f1f9fc542800ull,0x8181f1fdfe542800ull,0x8181effffe542800ull,0x81819ffffe542800ull,0x87879fbffe542800ull,0x8f8f1fbffe542800ull,0xfff0f9fdfe542800ull,0xe1e1f9fdfe542800ull,0xc1c1f9fdfe542800ull,0x8181fdfffe542800ull,0x8181fffffe542800ull,0x8181fffffe542800ull,0x8787bffffe542800ull,0xff0fbffffe542800ull,0xf8f9fdfffe542800ull,0xf9f9fdfffe542800ull,0xf9f9fdfffe542800ull,0xf1fdfffffe542800ull,0xedfffffffe542800ull,0x9ffffffffe542800ull,0xbfbffffffe542800ull,0x3fbffffffe542800ull}, - {0xf0f0f0f0f0a05000ull,0xf0f0f0f0f0a05000ull,0xe0e0e0e0e0a04000ull,0xe0e0e0e0e0a04000ull,0x0ull,0x0ull,0x0ull,0xbfbfbfbebca89000ull,0xf0f0f0f0f0a05000ull,0xf0f0f0f0f0a05000ull,0xe0e0e0e0e0a04000ull,0xe0e0e0e0e0a04000ull,0x0ull,0x0ull,0x0ull,0xbfbfbfbebca81000ull,0xf0f0f0f0f0a05000ull,0xe0e0f0f0f0a05000ull,0xc0c0e0e0e0a04000ull,0x8080c0e0e0a04000ull,0x0ull,0x0ull,0x0ull,0x8f8f9fbebc281000ull,0xf0f0f0f0f0a05000ull,0xe0e0f0f0f0a05000ull,0xc0c0e0e0e0a05000ull,0x8080c0e0e0a05000ull,0x80808080e0a05000ull,0x818181fed0a05000ull,0x81818180bca05000ull,0x8f8f9fbe3ca85000ull,0xf0f0f0f0f0a05000ull,0xe0e0f0f0f0a05000ull,0xc0c0e0e0f0a05000ull,0x8080c0e0f0a05000ull,0x80808080f8a05000ull,0x81818180f8a05000ull,0x81818180fca05000ull,0x8f8f9f3efca85000ull,0xf1f1f0f0f8a85000ull,0xe1e1f1f0f8a85000ull,0xc1c1e1f0f8a85000ull,0x8181e1f0f8a85000ull,0x8181e1f8fca85000ull,0x8181dffefca85000ull,0x8181bffefca85000ull,0x8f8f3ffefca85000ull,0xfff0f1f8fca85000ull,0xe1e1f1f8fca85000ull,0xc1c1f1f8fca85000ull,0x8181f1f8fca85000ull,0x8181f9fcfca85000ull,0x8181fffefca85000ull,0x8181fffefca85000ull,0xff0ffffefca85000ull,0xf0f1f9fcfca85000ull,0xf1f1f9fcfca85000ull,0xf1f1f9fcfca85000ull,0xf1f1f9fcfca85000ull,0xe1f9fdfefca85000ull,0xd9fffffefca85000ull,0xbffffffefca85000ull,0x7ffffffefca85000ull}, - {0xf0f0f0f0f050a000ull,0xe0e0e0e0e040a000ull,0xe0e0e0e0e040a000ull,0xc0c0c0c0c0408000ull,0xc0c0c0c0c0408000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f0f050a000ull,0xe0e0e0e0e040a000ull,0xe0e0e0e0e040a000ull,0xc0c0c0c0c0408000ull,0xc0c0c0c0c0408000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f0f050a000ull,0xe0e0e0e0e040a000ull,0xc0c0e0e0e040a000ull,0x8080c0c0c0408000ull,0x808080c0c0408000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f0f050a000ull,0xe0e0e0e0e040a000ull,0xc0c0e0e0e040a000ull,0x8080c0c0c040a000ull,0x808080c0c040a000ull,0x80808080c040a000ull,0x808080fca040a000ull,0x808080807840a000ull,0xf0f0f0f0f050a000ull,0xe0e0e0e0e040a000ull,0xc0c0e0e0e040a000ull,0x8080c0c0e040a000ull,0x808080c0e040a000ull,0x80808080f040a000ull,0x80808080f040a000ull,0x80808000f840a000ull,0xf0f0f0f0f050a000ull,0xe0e0e0e0f050a000ull,0xc0c0e0e0f050a000ull,0x8080c0e0f050a000ull,0x8080c0e0f050a000ull,0x8080c0f0f850a000ull,0x8080befcf850a000ull,0x80807efcf850a000ull,0xfef0f0f0f850a000ull,0xe0e0e0f0f850a000ull,0xc0c0e0f0f850a000ull,0x8080e0f0f850a000ull,0x8080e0f0f850a000ull,0x8080f0f8f850a000ull,0x8080fefcf850a000ull,0xf000fefcf850a000ull,0xe0f0f0f8f850a000ull,0xe0e0f0f8f850a000ull,0xe0e0f0f8f850a000ull,0xe0e0f0f8f850a000ull,0xe0e0f0f8f850a000ull,0xd0f0f8fcf850a000ull,0xb0fefefcf850a000ull,0x7efefefcf850a000ull}, - {0xe0e0e0e0e0a04000ull,0xe0e0e0e0e0a04000ull,0xc0c0c0c0c0804000ull,0xc0c0c0c0c0804000ull,0x8080808080800000ull,0x8080808080800000ull,0x0ull,0x0ull,0xe0e0e0e0e0a04000ull,0xe0e0e0e0e0a04000ull,0xc0c0c0c0c0804000ull,0xc0c0c0c0c0804000ull,0x8080808080800000ull,0x8080808080800000ull,0x0ull,0x0ull,0xe0e0e0e0e0a04000ull,0xe0e0e0e0e0a04000ull,0xc0c0c0c0c0804000ull,0x8080c0c0c0804000ull,0x8080808080800000ull,0x8080808080800000ull,0x0ull,0x0ull,0xe0e0e0e0e0a04000ull,0xe0e0e0e0e0a04000ull,0xc0c0c0c0c0804000ull,0x8080c0c0c0804000ull,0x8080808080804000ull,0x8080808080804000ull,0x8080808080804000ull,0x808080f840804000ull,0xe0e0e0e0e0a04000ull,0xe0e0e0e0e0a04000ull,0xc0c0c0c0c0804000ull,0x8080c0c0c0804000ull,0x80808080c0804000ull,0x80808080c0804000ull,0x80808080e0804000ull,0x80808000e0804000ull,0xe0e0e0e0e0a04000ull,0xe0e0e0e0e0a04000ull,0xc0c0c0c0e0a04000ull,0x8080c0c0e0a04000ull,0x808080c0e0a04000ull,0x808080c0e0a04000ull,0x808080e0f0a04000ull,0x80807cf8f0a04000ull,0xece0e0e0f0a04000ull,0xe0e0e0e0f0a04000ull,0xc0c0c0e0f0a04000ull,0x8080c0e0f0a04000ull,0x8080c0e0f0a04000ull,0x8080c0e0f0a04000ull,0x8080e0f0f0a04000ull,0xe000fcf8f0a04000ull,0xe0e0e0f0f0a04000ull,0xc0e0e0f0f0a04000ull,0xc0c0e0f0f0a04000ull,0xc0c0e0f0f0a04000ull,0xc0c0e0f0f0a04000ull,0xc0c0e0f0f0a04000ull,0xa0e0f0f8f0a04000ull,0x70fcfcf8f0a04000ull}, - {0x3f3f3f1f0d000000ull,0xf0f070301000000ull,0xf0f070301000000ull,0xf0f070301000000ull,0xf0f070301020000ull,0xf0f070301020000ull,0xf0f070705060000ull,0xf0f070705060000ull,0x203000000000000ull,0x203000000000000ull,0x101010101000000ull,0x101010101000000ull,0x303030301020000ull,0x303030301020000ull,0x707070705060000ull,0x707070705060000ull,0x0ull,0x203000000000000ull,0x101010101000000ull,0x101010101000000ull,0x303030301020000ull,0x303030301020000ull,0x707070705060000ull,0x707070705060000ull,0x203000000000000ull,0x203000000000000ull,0x101010101000000ull,0x101010101000000ull,0x303030301020000ull,0x303030301020000ull,0x707070705060000ull,0x707070705060000ull,0x1013f1e0d060000ull,0x101010105020000ull,0x101010101020000ull,0x101010101020000ull,0x303030301020000ull,0x303030301020000ull,0x707070705060000ull,0x707070705060000ull,0x101001f0d060000ull,0x10101070d060000ull,0x101010305060000ull,0x101010305060000ull,0x303030305060000ull,0x303030305060000ull,0x707070705060000ull,0x707070705060000ull,0x373e3f1f0d060000ull,0xf01070f0d060000ull,0x10103070d060000ull,0x10103070d060000ull,0x30303070d060000ull,0x30303070d060000ull,0x70707070d060000ull,0x370707070d060000ull,0xe3f3f1f0d060000ull,0x5070f1f0d060000ull,0x303070f0d060000ull,0x303070f0d060000ull,0x303070f0d060000ull,0x303070f0d060000ull,0x307070f0d060000ull,0x707070f0d060000ull}, - {0x7f7f7f3f1a0d0000ull,0x7f7f7f3f1a000000ull,0x1f1f0f0702010000ull,0x1f1f0f0702010000ull,0x1f1f0f0702010000ull,0x1f1f0f0702050000ull,0x1f1f0f0702050000ull,0x1f1f0f0f0a0d0000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x303030302010000ull,0x303030302010000ull,0x707070702050000ull,0x707070702050000ull,0xf0f0f0f0a0d0000ull,0x203000000000000ull,0x0ull,0x203000000000000ull,0x303030302010000ull,0x303030302010000ull,0x707070702050000ull,0x707070702050000ull,0xf0f0f0f0a0d0000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x101030302010000ull,0x303030302010000ull,0x707070702050000ull,0x707070702050000ull,0xf0f0f0f0a0d0000ull,0x101013e1a0d0000ull,0x1017f3d1a0d0000ull,0x10101030a050000ull,0x101030302050000ull,0x303030302050000ull,0x707070702050000ull,0x707070702050000ull,0xf0f0f0f0a0d0000ull,0x101003f1a0d0000ull,0x101013f1a0d0000ull,0x101010f1a0d0000ull,0x10103070a0d0000ull,0x30303070a0d0000ull,0x70707070a0d0000ull,0x70707070a0d0000ull,0xf0f0f0f0a0d0000ull,0x7f7e7f3f1a0d0000ull,0x7f7d7f3f1a0d0000ull,0xf030f1f1a0d0000ull,0x303070f1a0d0000ull,0x303070f1a0d0000ull,0x707070f1a0d0000ull,0x707070f1a0d0000ull,0x7f0f0f0f1a0d0000ull,0x7e7f7f3f1a0d0000ull,0xd7f7f3f1a0d0000ull,0xb0f1f3f1a0d0000ull,0x7070f1f1a0d0000ull,0x7070f1f1a0d0000ull,0x7070f1f1a0d0000ull,0x7070f1f1a0d0000ull,0x70f0f1f1a0d0000ull}, - {0xffffff7f35180000ull,0xffffff7f34180000ull,0xffffff7f35000000ull,0x3f3f1f0f05030000ull,0x3f3f1f0f05030000ull,0x3f3f1f0f05030000ull,0x3f3f1f0f050b0000ull,0x3f3f1f0f050b0000ull,0xfdfdfd7d35180000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x707070705030000ull,0x707070705030000ull,0xf0f0f0f050b0000ull,0xf0f0f0f050b0000ull,0xfdfdfd7d35180000ull,0x203000000000000ull,0x0ull,0x0ull,0x707070705030000ull,0x707070705030000ull,0xf0f0f0f050b0000ull,0xf0f0f0f050b0000ull,0xf9f9fd7d34190000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x303070705030000ull,0x707070705030000ull,0xf0f0f0f050b0000ull,0xf0f0f0f050b0000ull,0xf9f9fd7c351b0000ull,0x8181817d351b0000ull,0x8181ff7b351b0000ull,0x1010107150b0000ull,0x3030707050b0000ull,0x7070707050b0000ull,0xf0f0f0f050b0000ull,0xf0f0f0f050b0000ull,0xf9f9fc7f351b0000ull,0x8181817f351b0000ull,0x8181817f351b0000ull,0x8181811f351b0000ull,0x8383870f151b0000ull,0x8787870f151b0000ull,0x8f8f8f0f151b0000ull,0x8f8f0f0f151b0000ull,0xfffcff7f351b0000ull,0xfdfdff7f351b0000ull,0xfffbff7f351b0000ull,0x8f879f3f351b0000ull,0x87878f1f351b0000ull,0x87878f1f351b0000ull,0x8f8f8f1f351b0000ull,0xff0f8f1f351b0000ull,0xfeffff7f351b0000ull,0xfdffff7f351b0000ull,0x9bffff7f351b0000ull,0x879fbf7f351b0000ull,0x8f8f9f3f351b0000ull,0x8f8f9f3f351b0000ull,0x8f8f9f3f351b0000ull,0xf8f9f3f351b0000ull}, - {0xfffffffc68300000ull,0xfffffffc68300000ull,0xfffffffc68300000ull,0xffffffff6b000000ull,0x7f7f3f1f0b060000ull,0x7f7f3f1f0b060000ull,0x7f7f3f1f0b060000ull,0x7f7f3f1f0b160000ull,0xf8f8f8f868300000ull,0xf8f8f8f868300000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f0b060000ull,0xf0f0f0f0b060000ull,0x1f1f1f1f0b160000ull,0xf8f8f8f868300000ull,0xf8f8f8f868300000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f0b060000ull,0xf0f0f0f0b060000ull,0x1f1f1f1f0b160000ull,0xf8f8f8f868300000ull,0xf0f0f8f868300000ull,0x0ull,0x0ull,0x0ull,0x7070f0f0b060000ull,0xf0f0f0f0b060000ull,0x1f1f1f1f0b160000ull,0xf9f9f9f869340000ull,0xf1f1f9f969340000ull,0x818181f96b340000ull,0x8181fff76b360000ull,0x8181818f2b160000ull,0x87878f8f0b160000ull,0x8f8f8f8f0b160000ull,0x9f9f9f1f0b160000ull,0xf9f9f8fd6b360000ull,0xf1f1f9fd6b360000ull,0x818181ff6b360000ull,0x818181ff6b360000ull,0x818181bf6b360000ull,0x87878f9f2b360000ull,0x8f8f8f9f2b360000ull,0x9f9f1f9f2b360000ull,0xfff8fdff6b360000ull,0xf9f9fdff6b360000ull,0xf9f9ffff6b360000ull,0xfff7ffff6b360000ull,0x8f8fbfff6b360000ull,0x8f8f9fbf6b360000ull,0x9f8f9fbf6b360000ull,0xff1f9fbf6b360000ull,0xfcfdffff6b360000ull,0xfdfdffff6b360000ull,0xf9ffffff6b360000ull,0xb7ffffff6b360000ull,0x8fbfffff6b360000ull,0x9f9fbfff6b360000ull,0x9f9fbfff6b360000ull,0x1f9fbfff6b360000ull}, - {0xfefefcf8d0680000ull,0xfefefcf8d0600000ull,0xfefefcf8d0600000ull,0xfefefcf8d0600000ull,0xffffffffd6000000ull,0xffffff3f160c0000ull,0xffffff3f160c0000ull,0xffffff3f160c0000ull,0xf8f8f8f8d0680000ull,0xf0f0f0f0d0600000ull,0xf0f0f0f0d0600000ull,0x0ull,0x0ull,0x0ull,0x1f1f1f1f160c0000ull,0x1f1f1f1f160c0000ull,0xf8f8f8f8d0680000ull,0xf0f0f0f0d0600000ull,0xf0f0f0f0d0600000ull,0x0ull,0x0ull,0x0ull,0x1f1f1f1f160c0000ull,0x1f1f1f1f160c0000ull,0xf8f8f8f8d0680000ull,0xf0f0f0f0d0600000ull,0xe0e0f0f0d0600000ull,0x0ull,0x0ull,0x0ull,0xf0f1f1f160c0000ull,0x1f1f1f1f160c0000ull,0xf9f9f9f8d0680000ull,0xf1f1f1f1d0680000ull,0xe1e1f1f1d0680000ull,0x818181f1d4680000ull,0x8181ffefd66c0000ull,0x8181819fd62c0000ull,0x8f8f9f9f962c0000ull,0x9f9f9f1f962c0000ull,0xf9f9f8f9d46c0000ull,0xf1f1f1f9d46c0000ull,0xe1e1f1f9d46c0000ull,0x818181fdd66c0000ull,0x818181ffd66c0000ull,0x818181ffd66c0000ull,0x8f8f9fbfd66c0000ull,0x9f9f1fbfd66c0000ull,0xfff8f9fdd66c0000ull,0xf9f1f9fdd66c0000ull,0xf1f1f9fdd66c0000ull,0xf1f1fdffd66c0000ull,0xffefffffd66c0000ull,0x9f9fffffd66c0000ull,0x9f9fbfffd66c0000ull,0xff1fbfffd66c0000ull,0xf8f9fdffd66c0000ull,0xf9f9fdffd66c0000ull,0xf9f9fdffd66c0000ull,0xf1fdffffd66c0000ull,0xedffffffd66c0000ull,0x9fffffffd66c0000ull,0xbfbfffffd66c0000ull,0x3fbfffffd66c0000ull}, - {0xfcfcf8f0a0d00000ull,0xfcfcf8f0a0d00000ull,0xfcfcf8f0a0c00000ull,0xfcfcf8f0a0c00000ull,0xfcfcf8f0a0c00000ull,0xfffffffeac000000ull,0xfffffffe2c180000ull,0xfffffffeac180000ull,0xf0f0f0f0a0d00000ull,0xf0f0f0f0a0d00000ull,0xe0e0e0e0a0c00000ull,0xe0e0e0e0a0c00000ull,0x0ull,0x0ull,0x0ull,0xbfbfbfbeac180000ull,0xf0f0f0f0a0d00000ull,0xf0f0f0f0a0d00000ull,0xe0e0e0e0a0c00000ull,0xe0e0e0e0a0c00000ull,0x0ull,0x0ull,0x0ull,0xbfbfbfbeac180000ull,0xf0f0f0f0a0d00000ull,0xf0f0f0f0a0d00000ull,0xe0e0e0e0a0c00000ull,0xc0c0e0e0a0c00000ull,0x0ull,0x0ull,0x0ull,0x9f9fbfbe2c980000ull,0xf0f0f0f0a0d00000ull,0xf0f0f0f0a0d00000ull,0xe0e0e0e0a0d00000ull,0xc0c0e0e0a0d00000ull,0x808080e0a8d00000ull,0x8181ffdeacd80000ull,0x818181beacd80000ull,0x9f9fbf3eacd80000ull,0xf1f1f0f0a8d80000ull,0xf1f1f1f0a8d80000ull,0xe1e1e1f0a8d80000ull,0xc1c1e1f0a8d80000ull,0x818181f8acd80000ull,0x818181feacd80000ull,0x818181feacd80000ull,0x9f9f3ffeacd80000ull,0xfff0f1f8acd80000ull,0xf1f1f1f8acd80000ull,0xe1e1f1f8acd80000ull,0xe1e1f1f8acd80000ull,0xf1e1f9fcacd80000ull,0xffdffffeacd80000ull,0xbfbffffeacd80000ull,0xff3ffffeacd80000ull,0xf0f1f9fcacd80000ull,0xf1f1f9fcacd80000ull,0xf1f1f9fcacd80000ull,0xf1f1f9fcacd80000ull,0xe1f9fdfeacd80000ull,0xd9fffffeacd80000ull,0xbffffffeacd80000ull,0x7ffffffeacd80000ull}, - {0xf8f8f0f050b00000ull,0xf8f8f0e040a00000ull,0xf8f8f0e040a00000ull,0xf8f8f0e040800000ull,0xf8f8f0e040800000ull,0xf8f8f0e040800000ull,0xfefefefc58000000ull,0xfefefefc58b00000ull,0xf0f0f0f050b00000ull,0xe0e0e0e040a00000ull,0xe0e0e0e040a00000ull,0xc0c0c0c040800000ull,0xc0c0c0c040800000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f050b00000ull,0xe0e0e0e040a00000ull,0xe0e0e0e040a00000ull,0xc0c0c0c040800000ull,0xc0c0c0c040800000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f050b00000ull,0xe0e0e0e040a00000ull,0xe0e0e0e040a00000ull,0xc0c0c0c040800000ull,0x8080c0c040800000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0f050b00000ull,0xe0e0e0e040a00000ull,0xe0e0e0e040a00000ull,0xc0c0c0c040a00000ull,0x8080c0c040a00000ull,0x808080c050a00000ull,0x8080febc58b00000ull,0x8080807c58b00000ull,0xf0f0f0f050b00000ull,0xe0e0e0e050b00000ull,0xe0e0e0e050b00000ull,0xc0c0c0e050b00000ull,0x8080c0e050b00000ull,0x808080f058b00000ull,0x808080fc58b00000ull,0x808000fc58b00000ull,0xfef0f0f058b00000ull,0xe0e0e0f058b00000ull,0xe0e0e0f058b00000ull,0xc0c0e0f058b00000ull,0xc0c0e0f058b00000ull,0xf0c0f0f858b00000ull,0xfebefefc58b00000ull,0xfe7efefc58b00000ull,0xe0f0f0f858b00000ull,0xe0e0f0f858b00000ull,0xe0e0f0f858b00000ull,0xe0e0f0f858b00000ull,0xe0e0f0f858b00000ull,0xd0f0f8fc58b00000ull,0xb0fefefc58b00000ull,0x7efefefc58b00000ull}, - {0xf0f0e0e0a0600000ull,0xf0f0e0e0a0600000ull,0xf0f0e0c080400000ull,0xf0f0e0c080400000ull,0xf0f0e0c080000000ull,0xf0f0e0c080000000ull,0xf0f0e0c080000000ull,0xfcfcfcf8b0000000ull,0xe0e0e0e0a0600000ull,0xe0e0e0e0a0600000ull,0xc0c0c0c080400000ull,0xc0c0c0c080400000ull,0x8080808080000000ull,0x8080808080000000ull,0x0ull,0x0ull,0xe0e0e0e0a0600000ull,0xe0e0e0e0a0600000ull,0xc0c0c0c080400000ull,0xc0c0c0c080400000ull,0x8080808080000000ull,0x8080808080000000ull,0x0ull,0x0ull,0xe0e0e0e0a0600000ull,0xe0e0e0e0a0600000ull,0xc0c0c0c080400000ull,0xc0c0c0c080400000ull,0x8080808080000000ull,0x8080808080000000ull,0x0ull,0x0ull,0xe0e0e0e0a0600000ull,0xe0e0e0e0a0600000ull,0xc0c0c0c080400000ull,0xc0c0c0c080400000ull,0x8080808080400000ull,0x8080808080400000ull,0x80808080a0400000ull,0x8080fc78b0600000ull,0xe0e0e0e0a0600000ull,0xe0e0e0e0a0600000ull,0xc0c0c0c0a0600000ull,0xc0c0c0c0a0600000ull,0x808080c0a0600000ull,0x808080c0a0600000ull,0x808080e0b0600000ull,0x808000f8b0600000ull,0xece0e0e0b0600000ull,0xe0e0e0e0b0600000ull,0xc0c0c0e0b0600000ull,0xc0c0c0e0b0600000ull,0x8080c0e0b0600000ull,0x8080c0e0b0600000ull,0xf080e0f0b0600000ull,0xec7cfcf8b0600000ull,0xe0e0e0f0b0600000ull,0xc0e0e0f0b0600000ull,0xc0c0e0f0b0600000ull,0xc0c0e0f0b0600000ull,0xc0c0e0f0b0600000ull,0xc0c0e0f0b0600000ull,0xa0e0f0f8b0600000ull,0x70fcfcf8b0600000ull}, - {0x3f3f3f1d02000000ull,0xf0f0f0502000000ull,0xf0f0f0502000000ull,0xf0f0f0502000000ull,0xf0f0f0502000000ull,0xf0f0f0502000000ull,0xf0f0f0506000000ull,0xf0f0f0506000000ull,0x3f3f3f1d00000000ull,0x707030100000000ull,0x707030100000000ull,0x707030100000000ull,0x707030102000000ull,0x707030102000000ull,0x707070506000000ull,0x707070506000000ull,0x203000000000000ull,0x203000000000000ull,0x101010100000000ull,0x101010100000000ull,0x303030102000000ull,0x303030102000000ull,0x707070506000000ull,0x707070506000000ull,0x0ull,0x203000000000000ull,0x101010100000000ull,0x101010100000000ull,0x303030102000000ull,0x303030102000000ull,0x707070506000000ull,0x707070506000000ull,0x203000000000000ull,0x203000000000000ull,0x101010100000000ull,0x101010100000000ull,0x303030102000000ull,0x303030102000000ull,0x707070506000000ull,0x707070506000000ull,0x3f3f3e1d0e000000ull,0x10101050a000000ull,0x101010102000000ull,0x101010102000000ull,0x303030102000000ull,0x303030102000000ull,0x707070506000000ull,0x707070506000000ull,0x7003f1d0e000000ull,0x101070d0e000000ull,0x10103050e000000ull,0x10103050e000000ull,0x30303050e000000ull,0x30303050e000000ull,0x70707050e000000ull,0x370707050e000000ull,0xe3f3f1d0e000000ull,0x5070f1d0e000000ull,0x303070d0e000000ull,0x303070d0e000000ull,0x303070d0e000000ull,0x303070d0e000000ull,0x307070d0e000000ull,0x707070d0e000000ull}, - {0x7f7f7f3a1d000000ull,0x7f7f7f3a05000000ull,0x1f1f1f0a05000000ull,0x1f1f1f0a05000000ull,0x1f1f1f0a05000000ull,0x1f1f1f0a05000000ull,0x1f1f1f0a05000000ull,0x1f1f1f0a0d000000ull,0x7f7f7f3a1c000000ull,0x7f7f7f3a00000000ull,0xf0f070201000000ull,0xf0f070201000000ull,0xf0f070201000000ull,0xf0f070205000000ull,0xf0f070205000000ull,0xf0f0f0a0d000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x303030201000000ull,0x303030201000000ull,0x707070205000000ull,0x707070205000000ull,0xf0f0f0a0d000000ull,0x203000000000000ull,0x0ull,0x203000000000000ull,0x303030201000000ull,0x303030201000000ull,0x707070205000000ull,0x707070205000000ull,0xf0f0f0a0d000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x303030201000000ull,0x303030201000000ull,0x707070205000000ull,0x707070205000000ull,0xf0f0f0a0d000000ull,0x1017e3a1d000000ull,0x7f7f7d3a1d000000ull,0x101030a15000000ull,0x303030205000000ull,0x303030205000000ull,0x707070205000000ull,0x707070205000000ull,0xf0f0f0a0d000000ull,0xf007f3a1d000000ull,0x1017f3a1d000000ull,0x1010f1a1d000000ull,0x303070a1d000000ull,0x303070a1d000000ull,0x707070a1d000000ull,0x707070a1d000000ull,0x7f0f0f0a1d000000ull,0x7e7f7f3a1d000000ull,0xd7f7f3a1d000000ull,0xb0f1f3a1d000000ull,0x7070f1a1d000000ull,0x7070f1a1d000000ull,0x7070f1a1d000000ull,0x7070f1a1d000000ull,0x70f0f1a1d000000ull}, - {0xffffff753a000000ull,0xffffff753a000000ull,0xffffff750a000000ull,0x3f3f3f150b000000ull,0x3f3f3f150b000000ull,0x3f3f3f150b000000ull,0x3f3f3f150b000000ull,0x3f3f3f150b000000ull,0xffffff7538000000ull,0xffffff7438000000ull,0xffffff7500000000ull,0x1f1f0f0503000000ull,0x1f1f0f0503000000ull,0x1f1f0f0503000000ull,0x1f1f0f050b000000ull,0x1f1f0f050b000000ull,0xfdfdfd7538000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x707070503000000ull,0x707070503000000ull,0xf0f0f050b000000ull,0xf0f0f050b000000ull,0xfdfdfd7538000000ull,0x203000000000000ull,0x0ull,0x0ull,0x707070503000000ull,0x707070503000000ull,0xf0f0f050b000000ull,0xf0f0f050b000000ull,0xfdfdfd7439000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x707070503000000ull,0x707070503000000ull,0xf0f0f050b000000ull,0xf0f0f050b000000ull,0xfdfdfc753b000000ull,0x8181fd753b000000ull,0xfffffb753b000000ull,0x818187152b000000ull,0x878787050b000000ull,0x878787050b000000ull,0x8f8f8f050b000000ull,0x8f8f0f050b000000ull,0xfffcff753b000000ull,0x8d81ff753b000000ull,0x8181ff753b000000ull,0x81819f353b000000ull,0x87878f153b000000ull,0x87878f153b000000ull,0x8f8f8f153b000000ull,0xff0f8f153b000000ull,0xfeffff753b000000ull,0xfdffff753b000000ull,0x9bffff753b000000ull,0x879fbf753b000000ull,0x8f8f9f353b000000ull,0x8f8f9f353b000000ull,0x8f8f9f353b000000ull,0xf8f9f353b000000ull}, - {0xffffffea74000000ull,0xffffffea74000000ull,0xffffffea74000000ull,0xffffffeb14000000ull,0x7f7f7f2b17000000ull,0x7f7f7f2b17000000ull,0x7f7f7f2b17000000ull,0x7f7f7f2b17000000ull,0xfefefce870000000ull,0xfefefce870000000ull,0xfefefce870000000ull,0xffffffeb00000000ull,0x3f3f1f0b07000000ull,0x3f3f1f0b07000000ull,0x3f3f1f0b07000000ull,0x3f3f1f0b17000000ull,0xf8f8f8e870000000ull,0xf8f8f8e870000000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0b07000000ull,0xf0f0f0b07000000ull,0x1f1f1f0b17000000ull,0xf8f8f8e870000000ull,0xf8f8f8e870000000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0b07000000ull,0xf0f0f0b07000000ull,0x1f1f1f0b17000000ull,0xf8f8f8e870000000ull,0xf8f8f8e870000000ull,0x0ull,0x0ull,0x0ull,0xf0f0f0b07000000ull,0xf0f0f0b07000000ull,0x1f1f1f0b17000000ull,0xf9f9f8e975000000ull,0xf9f9f9e975000000ull,0x8181f9eb75000000ull,0xfffff7eb77000000ull,0x81818fab57000000ull,0x8f8f8f8b17000000ull,0x8f8f8f8b17000000ull,0x9f9f1f8b17000000ull,0xfff8fdeb77000000ull,0xf9f9fdeb77000000ull,0x8981ffeb77000000ull,0x8181ffeb77000000ull,0x8181bfeb77000000ull,0x8f8f9fab77000000ull,0x9f8f9fab77000000ull,0xff1f9fab77000000ull,0xfcfdffeb77000000ull,0xfdfdffeb77000000ull,0xf9ffffeb77000000ull,0xb7ffffeb77000000ull,0x8fbfffeb77000000ull,0x9f9fbfeb77000000ull,0x9f9fbfeb77000000ull,0x1f9fbfeb77000000ull}, - {0xfefefed4e8000000ull,0xfefefed4e8000000ull,0xfefefed4e8000000ull,0xfefefed4e8000000ull,0xffffffd728000000ull,0xffffff572e000000ull,0xffffff572e000000ull,0xffffff572e000000ull,0xfcfcf8d0e8000000ull,0xfcfcf8d0e0000000ull,0xfcfcf8d0e0000000ull,0xfcfcf8d0e0000000ull,0xffffffd700000000ull,0x7f7f3f170e000000ull,0x7f7f3f170e000000ull,0x7f7f3f170e000000ull,0xf8f8f8d0e8000000ull,0xf0f0f0d0e0000000ull,0xf0f0f0d0e0000000ull,0x0ull,0x0ull,0x0ull,0x1f1f1f170e000000ull,0x1f1f1f170e000000ull,0xf8f8f8d0e8000000ull,0xf0f0f0d0e0000000ull,0xf0f0f0d0e0000000ull,0x0ull,0x0ull,0x0ull,0x1f1f1f170e000000ull,0x1f1f1f170e000000ull,0xf8f8f8d0e8000000ull,0xf0f0f0d0e0000000ull,0xf0f0f0d0e0000000ull,0x0ull,0x0ull,0x0ull,0x1f1f1f170e000000ull,0x1f1f1f170e000000ull,0xf9f9f8d1e8000000ull,0xf1f1f1d1e8000000ull,0xf1f1f1d1e8000000ull,0x8181f1d5ea000000ull,0xffffefd7ee000000ull,0x81819fd7ae000000ull,0x9f9f9f97ae000000ull,0x9f9f1f97ae000000ull,0xfff8f9d5ee000000ull,0xf9f1f9d5ee000000ull,0xf1f1f9d5ee000000ull,0x8181fdd7ee000000ull,0x8181ffd7ee000000ull,0x9181ffd7ee000000ull,0x9f9fbfd7ee000000ull,0xff1fbfd7ee000000ull,0xf8f9fdd7ee000000ull,0xf9f9fdd7ee000000ull,0xf9f9fdd7ee000000ull,0xf1fdffd7ee000000ull,0xedffffd7ee000000ull,0x9fffffd7ee000000ull,0xbfbfffd7ee000000ull,0x3fbfffd7ee000000ull}, - {0xfcfcfca8d0000000ull,0xfcfcfca8d0000000ull,0xfcfcfca8d0000000ull,0xfcfcfca8d0000000ull,0xfcfcfca8d0000000ull,0xffffffae50000000ull,0xffffffae5c000000ull,0xffffffae5c000000ull,0xf8f8f0a0d0000000ull,0xf8f8f0a0d0000000ull,0xf8f8f0a0c0000000ull,0xf8f8f0a0c0000000ull,0xf8f8f0a0c0000000ull,0xffffffae00000000ull,0xffffff2e1c000000ull,0xffffffae1c000000ull,0xf0f0f0a0d0000000ull,0xf0f0f0a0d0000000ull,0xe0e0e0a0c0000000ull,0xe0e0e0a0c0000000ull,0x0ull,0x0ull,0x0ull,0xbfbfbfae1c000000ull,0xf0f0f0a0d0000000ull,0xf0f0f0a0d0000000ull,0xe0e0e0a0c0000000ull,0xe0e0e0a0c0000000ull,0x0ull,0x0ull,0x0ull,0xbfbfbfae1c000000ull,0xf0f0f0a0d0000000ull,0xf0f0f0a0d0000000ull,0xe0e0e0a0c0000000ull,0xe0e0e0a0c0000000ull,0x0ull,0x0ull,0x0ull,0xbfbfbf2e9c000000ull,0xf1f1f0a0d0000000ull,0xf1f1f1a0d0000000ull,0xe1e1e1a0d0000000ull,0xe1e1e1a0d0000000ull,0x8181e1a8d4000000ull,0xffffdfaedc000000ull,0x8181bfaedc000000ull,0xbfbf3faedc000000ull,0xfff0f1a8dc000000ull,0xf1f1f1a8dc000000ull,0xe1e1f1a8dc000000ull,0xe1e1f1a8dc000000ull,0x8181f9acdc000000ull,0x8181ffaedc000000ull,0xb181ffaedc000000ull,0xff3fffaedc000000ull,0xf0f1f9acdc000000ull,0xf1f1f9acdc000000ull,0xf1f1f9acdc000000ull,0xf1f1f9acdc000000ull,0xe1f9fdaedc000000ull,0xd9ffffaedc000000ull,0xbfffffaedc000000ull,0x7fffffaedc000000ull}, - {0xf8f8f850b0000000ull,0xf8f8f850a0000000ull,0xf8f8f850a0000000ull,0xf8f8f850a0000000ull,0xf8f8f850a0000000ull,0xf8f8f850a0000000ull,0xfefefe5ca0000000ull,0xfefefe5cb8000000ull,0xf0f0f050b0000000ull,0xf0f0e040a0000000ull,0xf0f0e040a0000000ull,0xf0f0e04080000000ull,0xf0f0e04080000000ull,0xf0f0e04080000000ull,0xfefefe5c00000000ull,0xfefefe5c38000000ull,0xf0f0f050b0000000ull,0xe0e0e040a0000000ull,0xe0e0e040a0000000ull,0xc0c0c04080000000ull,0xc0c0c04080000000ull,0x0ull,0x0ull,0x0ull,0xf0f0f050b0000000ull,0xe0e0e040a0000000ull,0xe0e0e040a0000000ull,0xc0c0c04080000000ull,0xc0c0c04080000000ull,0x0ull,0x0ull,0x0ull,0xf0f0f050b0000000ull,0xe0e0e040a0000000ull,0xe0e0e040a0000000ull,0xc0c0c04080000000ull,0xc0c0c04080000000ull,0x0ull,0x0ull,0x0ull,0xf0f0f050b0000000ull,0xe0e0e040a0000000ull,0xe0e0e040a0000000ull,0xc0c0c040a0000000ull,0xc0c0c040a0000000ull,0x8080c050a8000000ull,0xfefebe5cb8000000ull,0x80807e5cb8000000ull,0xfef0f050b8000000ull,0xe0e0e050b8000000ull,0xe0e0e050b8000000ull,0xc0c0e050b8000000ull,0xc0c0e050b8000000ull,0x8080f058b8000000ull,0x8080fe5cb8000000ull,0xf000fe5cb8000000ull,0xe0f0f058b8000000ull,0xe0e0f058b8000000ull,0xe0e0f058b8000000ull,0xe0e0f058b8000000ull,0xe0e0f058b8000000ull,0xd0f0f85cb8000000ull,0xb0fefe5cb8000000ull,0x7efefe5cb8000000ull}, - {0xf0f0f0a060000000ull,0xf0f0f0a060000000ull,0xf0f0f0a040000000ull,0xf0f0f0a040000000ull,0xf0f0f0a040000000ull,0xf0f0f0a040000000ull,0xf0f0f0a040000000ull,0xfcfcfcb840000000ull,0xe0e0e0a060000000ull,0xe0e0e0a060000000ull,0xe0e0c08040000000ull,0xe0e0c08040000000ull,0xe0e0c08000000000ull,0xe0e0c08000000000ull,0xe0e0c08000000000ull,0xfcfcfcb800000000ull,0xe0e0e0a060000000ull,0xe0e0e0a060000000ull,0xc0c0c08040000000ull,0xc0c0c08040000000ull,0x8080808000000000ull,0x8080808000000000ull,0x0ull,0x0ull,0xe0e0e0a060000000ull,0xe0e0e0a060000000ull,0xc0c0c08040000000ull,0xc0c0c08040000000ull,0x8080808000000000ull,0x8080808000000000ull,0x0ull,0x0ull,0xe0e0e0a060000000ull,0xe0e0e0a060000000ull,0xc0c0c08040000000ull,0xc0c0c08040000000ull,0x8080808000000000ull,0x8080808000000000ull,0x0ull,0x0ull,0xe0e0e0a060000000ull,0xe0e0e0a060000000ull,0xc0c0c08040000000ull,0xc0c0c08040000000ull,0x8080808040000000ull,0x8080808040000000ull,0x808080a050000000ull,0xfcfc7cb870000000ull,0xece0e0a070000000ull,0xe0e0e0a070000000ull,0xc0c0c0a070000000ull,0xc0c0c0a070000000ull,0x8080c0a070000000ull,0x8080c0a070000000ull,0x8080e0b070000000ull,0xe000fcb870000000ull,0xe0e0e0b070000000ull,0xc0e0e0b070000000ull,0xc0c0e0b070000000ull,0xc0c0e0b070000000ull,0xc0c0e0b070000000ull,0xc0c0e0b070000000ull,0xa0e0f0b870000000ull,0x70fcfcb870000000ull}, - {0x3f3f3d1e00000000ull,0xf0f0d0600000000ull,0xf0f0d0600000000ull,0xf0f0d0600000000ull,0xf0f0d0600000000ull,0xf0f0d0600000000ull,0xf0f0d0600000000ull,0xf0f0d0600000000ull,0x3f3f3d0200000000ull,0x707050200000000ull,0x707050200000000ull,0x707050200000000ull,0x707050200000000ull,0x707050200000000ull,0x707050600000000ull,0x707050600000000ull,0x3f3f3d0000000000ull,0x303010000000000ull,0x303010000000000ull,0x303010000000000ull,0x303010200000000ull,0x303010200000000ull,0x707050600000000ull,0x707050600000000ull,0x203000000000000ull,0x203000000000000ull,0x101010000000000ull,0x101010000000000ull,0x303010200000000ull,0x303010200000000ull,0x707050600000000ull,0x707050600000000ull,0x0ull,0x203000000000000ull,0x101010000000000ull,0x101010000000000ull,0x303010200000000ull,0x303010200000000ull,0x707050600000000ull,0x707050600000000ull,0x203000000000000ull,0x203000000000000ull,0x101010000000000ull,0x101010000000000ull,0x303010200000000ull,0x303010200000000ull,0x707050600000000ull,0x707050600000000ull,0x373e3d1e00000000ull,0xf01050a00000000ull,0x101010200000000ull,0x101010200000000ull,0x303010200000000ull,0x303010200000000ull,0x707050600000000ull,0x3707050600000000ull,0xe3f3d1e00000000ull,0x5070d1e00000000ull,0x303050e00000000ull,0x303050e00000000ull,0x303050e00000000ull,0x303050e00000000ull,0x307050e00000000ull,0x707050e00000000ull}, - {0x7f7f7a3d00000000ull,0x7f7f7a3d00000000ull,0x1f1f1a0d00000000ull,0x1f1f1a0d00000000ull,0x1f1f1a0d00000000ull,0x1f1f1a0d00000000ull,0x1f1f1a0d00000000ull,0x1f1f1a0d00000000ull,0x7f7f7a3d00000000ull,0x7f7f7a0500000000ull,0xf0f0a0500000000ull,0xf0f0a0500000000ull,0xf0f0a0500000000ull,0xf0f0a0500000000ull,0xf0f0a0500000000ull,0xf0f0a0d00000000ull,0x7f7f7a3c00000000ull,0x7f7f7a0000000000ull,0x707020100000000ull,0x707020100000000ull,0x707020100000000ull,0x707020500000000ull,0x707020500000000ull,0xf0f0a0d00000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x303020100000000ull,0x303020100000000ull,0x707020500000000ull,0x707020500000000ull,0xf0f0a0d00000000ull,0x203000000000000ull,0x0ull,0x203000000000000ull,0x303020100000000ull,0x303020100000000ull,0x707020500000000ull,0x707020500000000ull,0xf0f0a0d00000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x303020100000000ull,0x303020100000000ull,0x707020500000000ull,0x707020500000000ull,0xf0f0a0d00000000ull,0x7f7e7a3d00000000ull,0x7f7d7a3d00000000ull,0xf030a1500000000ull,0x303020500000000ull,0x303020500000000ull,0x707020500000000ull,0x707020500000000ull,0x7f0f0a0d00000000ull,0x7e7f7a3d00000000ull,0xd7f7a3d00000000ull,0xb0f1a3d00000000ull,0x7070a1d00000000ull,0x7070a1d00000000ull,0x7070a1d00000000ull,0x7070a1d00000000ull,0x70f0a1d00000000ull}, - {0xfffff57b00000000ull,0xfffff57b00000000ull,0xfffff57b00000000ull,0x3f3f351b00000000ull,0x3f3f351b00000000ull,0x3f3f351b00000000ull,0x3f3f351b00000000ull,0x3f3f351b00000000ull,0xfffff57a00000000ull,0xfffff57a00000000ull,0xfffff50a00000000ull,0x1f1f150b00000000ull,0x1f1f150b00000000ull,0x1f1f150b00000000ull,0x1f1f150b00000000ull,0x1f1f150b00000000ull,0xfffff57800000000ull,0xfefef47800000000ull,0xfffff50000000000ull,0xf0f050300000000ull,0xf0f050300000000ull,0xf0f050300000000ull,0xf0f050b00000000ull,0xf0f050b00000000ull,0xfdfdf57800000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x707050300000000ull,0x707050300000000ull,0xf0f050b00000000ull,0xf0f050b00000000ull,0xfdfdf57800000000ull,0x203000000000000ull,0x0ull,0x0ull,0x707050300000000ull,0x707050300000000ull,0xf0f050b00000000ull,0xf0f050b00000000ull,0xfdfdf47900000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x707050300000000ull,0x707050300000000ull,0xf0f050b00000000ull,0xf0f050b00000000ull,0xfffcf57b00000000ull,0xfdfdf57b00000000ull,0xfffbf57b00000000ull,0x8f87952b00000000ull,0x8787850b00000000ull,0x8787850b00000000ull,0x8f8f850b00000000ull,0xff0f850b00000000ull,0xfefff57b00000000ull,0xfdfff57b00000000ull,0x9bfff57b00000000ull,0x879fb57b00000000ull,0x8f8f953b00000000ull,0x8f8f953b00000000ull,0x8f8f953b00000000ull,0xf8f953b00000000ull}, - {0xffffebf600000000ull,0xffffebf600000000ull,0xffffebf600000000ull,0xffffebf700000000ull,0x7f7f6b3700000000ull,0x7f7f6b3700000000ull,0x7f7f6b3700000000ull,0x7f7f6b3700000000ull,0xfefeeaf400000000ull,0xfefeeaf400000000ull,0xfefeeaf400000000ull,0xffffeb1400000000ull,0x3f3f2b1700000000ull,0x3f3f2b1700000000ull,0x3f3f2b1700000000ull,0x3f3f2b1700000000ull,0xfcfce8f000000000ull,0xfcfce8f000000000ull,0xfcfce8f000000000ull,0xffffeb0000000000ull,0x1f1f0b0700000000ull,0x1f1f0b0700000000ull,0x1f1f0b0700000000ull,0x1f1f0b1700000000ull,0xf8f8e8f000000000ull,0xf8f8e8f000000000ull,0x0ull,0x0ull,0x0ull,0xf0f0b0700000000ull,0xf0f0b0700000000ull,0x1f1f0b1700000000ull,0xf8f8e8f000000000ull,0xf8f8e8f000000000ull,0x0ull,0x0ull,0x0ull,0xf0f0b0700000000ull,0xf0f0b0700000000ull,0x1f1f0b1700000000ull,0xf8f8e8f000000000ull,0xf8f8e8f000000000ull,0x0ull,0x0ull,0x0ull,0xf0f0b0700000000ull,0xf0f0b0700000000ull,0x1f1f0b1700000000ull,0xfff8e9f500000000ull,0xf9f9e9f500000000ull,0xf9f9ebf500000000ull,0xfff7ebf700000000ull,0x8f8fabd700000000ull,0x8f8f8b9700000000ull,0x9f8f8b9700000000ull,0xff1f8b9700000000ull,0xfcfdebf700000000ull,0xfdfdebf700000000ull,0xf9ffebf700000000ull,0xb7ffebf700000000ull,0x8fbfebf700000000ull,0x9f9fabf700000000ull,0x9f9fabf700000000ull,0x1f9fabf700000000ull}, - {0xfefed6ec00000000ull,0xfefed6ec00000000ull,0xfefed6ec00000000ull,0xfefed6ec00000000ull,0xffffd7ef00000000ull,0xffffd76f00000000ull,0xffffd76f00000000ull,0xffffd76f00000000ull,0xfcfcd4e800000000ull,0xfcfcd4e800000000ull,0xfcfcd4e800000000ull,0xfcfcd4e800000000ull,0xffffd72800000000ull,0x7f7f572f00000000ull,0x7f7f572f00000000ull,0x7f7f572f00000000ull,0xf8f8d0e800000000ull,0xf8f8d0e000000000ull,0xf8f8d0e000000000ull,0xf8f8d0e000000000ull,0xffffd70000000000ull,0x3f3f170f00000000ull,0x3f3f170f00000000ull,0x3f3f170f00000000ull,0xf8f8d0e800000000ull,0xf0f0d0e000000000ull,0xf0f0d0e000000000ull,0x0ull,0x0ull,0x0ull,0x1f1f170f00000000ull,0x1f1f170f00000000ull,0xf8f8d0e800000000ull,0xf0f0d0e000000000ull,0xf0f0d0e000000000ull,0x0ull,0x0ull,0x0ull,0x1f1f170f00000000ull,0x1f1f170f00000000ull,0xf8f8d0e800000000ull,0xf0f0d0e000000000ull,0xf0f0d0e000000000ull,0x0ull,0x0ull,0x0ull,0x1f1f170f00000000ull,0x1f1f170f00000000ull,0xfff8d1e900000000ull,0xf9f1d1e900000000ull,0xf1f1d1e900000000ull,0xf1f1d5eb00000000ull,0xffefd7ef00000000ull,0x9f9fd7af00000000ull,0x9f9f97af00000000ull,0xff1f97af00000000ull,0xf8f9d5ef00000000ull,0xf9f9d5ef00000000ull,0xf9f9d5ef00000000ull,0xf1fdd7ef00000000ull,0xedffd7ef00000000ull,0x9fffd7ef00000000ull,0xbfbfd7ef00000000ull,0x3fbfd7ef00000000ull}, - {0xfcfcacd800000000ull,0xfcfcacd800000000ull,0xfcfcacd800000000ull,0xfcfcacd800000000ull,0xfcfcacd800000000ull,0xffffafde00000000ull,0xffffafde00000000ull,0xffffafde00000000ull,0xf8f8a8d000000000ull,0xf8f8a8d000000000ull,0xf8f8a8d000000000ull,0xf8f8a8d000000000ull,0xf8f8a8d000000000ull,0xffffaf5000000000ull,0xffffaf5e00000000ull,0xffffaf5e00000000ull,0xf0f0a0d000000000ull,0xf0f0a0d000000000ull,0xf0f0a0c000000000ull,0xf0f0a0c000000000ull,0xf0f0a0c000000000ull,0xffffaf0000000000ull,0x7f7f2f1e00000000ull,0xffffaf1e00000000ull,0xf0f0a0d000000000ull,0xf0f0a0d000000000ull,0xe0e0a0c000000000ull,0xe0e0a0c000000000ull,0x0ull,0x0ull,0x0ull,0xbfbfaf1e00000000ull,0xf0f0a0d000000000ull,0xf0f0a0d000000000ull,0xe0e0a0c000000000ull,0xe0e0a0c000000000ull,0x0ull,0x0ull,0x0ull,0xbfbfaf1e00000000ull,0xf0f0a0d000000000ull,0xf0f0a0d000000000ull,0xe0e0a0c000000000ull,0xe0e0a0c000000000ull,0x0ull,0x0ull,0x0ull,0xbfbf2f9e00000000ull,0xfff0a1d000000000ull,0xf1f1a1d000000000ull,0xe1e1a1d000000000ull,0xe1e1a1d000000000ull,0xf1e1a9d400000000ull,0xffdfafde00000000ull,0xbfbfafde00000000ull,0xff3fafde00000000ull,0xf0f1a9dc00000000ull,0xf1f1a9dc00000000ull,0xf1f1a9dc00000000ull,0xf1f1a9dc00000000ull,0xe1f9adde00000000ull,0xd9ffafde00000000ull,0xbfffafde00000000ull,0x7fffafde00000000ull}, - {0xf8f858b000000000ull,0xf8f858b000000000ull,0xf8f858b000000000ull,0xf8f858b000000000ull,0xf8f858b000000000ull,0xf8f858b000000000ull,0xfefe5ebc00000000ull,0xfefe5ebc00000000ull,0xf0f050b000000000ull,0xf0f050a000000000ull,0xf0f050a000000000ull,0xf0f050a000000000ull,0xf0f050a000000000ull,0xf0f050a000000000ull,0xfefe5ea000000000ull,0xfefe5ebc00000000ull,0xf0f050b000000000ull,0xe0e040a000000000ull,0xe0e040a000000000ull,0xe0e0408000000000ull,0xe0e0408000000000ull,0xe0e0408000000000ull,0xfefe5e0000000000ull,0xfefe5e3c00000000ull,0xf0f050b000000000ull,0xe0e040a000000000ull,0xe0e040a000000000ull,0xc0c0408000000000ull,0xc0c0408000000000ull,0x0ull,0x0ull,0x0ull,0xf0f050b000000000ull,0xe0e040a000000000ull,0xe0e040a000000000ull,0xc0c0408000000000ull,0xc0c0408000000000ull,0x0ull,0x0ull,0x0ull,0xf0f050b000000000ull,0xe0e040a000000000ull,0xe0e040a000000000ull,0xc0c0408000000000ull,0xc0c0408000000000ull,0x0ull,0x0ull,0x0ull,0xfef050b000000000ull,0xe0e040a000000000ull,0xe0e040a000000000ull,0xc0c040a000000000ull,0xc0c040a000000000ull,0xf0c050a800000000ull,0xfebe5ebc00000000ull,0xfe7e5ebc00000000ull,0xe0f050b800000000ull,0xe0e050b800000000ull,0xe0e050b800000000ull,0xe0e050b800000000ull,0xe0e050b800000000ull,0xd0f058bc00000000ull,0xb0fe5ebc00000000ull,0x7efe5ebc00000000ull}, - {0xf0f0b06000000000ull,0xf0f0b06000000000ull,0xf0f0b06000000000ull,0xf0f0b06000000000ull,0xf0f0b06000000000ull,0xf0f0b06000000000ull,0xf0f0b06000000000ull,0xfcfcbc7800000000ull,0xe0e0a06000000000ull,0xe0e0a06000000000ull,0xe0e0a04000000000ull,0xe0e0a04000000000ull,0xe0e0a04000000000ull,0xe0e0a04000000000ull,0xe0e0a04000000000ull,0xfcfcbc4000000000ull,0xe0e0a06000000000ull,0xe0e0a06000000000ull,0xc0c0804000000000ull,0xc0c0804000000000ull,0xc0c0800000000000ull,0xc0c0800000000000ull,0xc0c0800000000000ull,0xfcfcbc0000000000ull,0xe0e0a06000000000ull,0xe0e0a06000000000ull,0xc0c0804000000000ull,0xc0c0804000000000ull,0x8080800000000000ull,0x8080800000000000ull,0x0ull,0x0ull,0xe0e0a06000000000ull,0xe0e0a06000000000ull,0xc0c0804000000000ull,0xc0c0804000000000ull,0x8080800000000000ull,0x8080800000000000ull,0x0ull,0x0ull,0xe0e0a06000000000ull,0xe0e0a06000000000ull,0xc0c0804000000000ull,0xc0c0804000000000ull,0x8080800000000000ull,0x8080800000000000ull,0x0ull,0x0ull,0xece0a06000000000ull,0xe0e0a06000000000ull,0xc0c0804000000000ull,0xc0c0804000000000ull,0x8080804000000000ull,0x8080804000000000ull,0xf080a05000000000ull,0xec7cbc7800000000ull,0xe0e0a07000000000ull,0xc0e0a07000000000ull,0xc0c0a07000000000ull,0xc0c0a07000000000ull,0xc0c0a07000000000ull,0xc0c0a07000000000ull,0xa0e0b07800000000ull,0x70fcbc7800000000ull}, - {0x3f3d3e0000000000ull,0xf0d0e0000000000ull,0xf0d0e0000000000ull,0xf0d0e0000000000ull,0xf0d0e0000000000ull,0xf0d0e0000000000ull,0xf0d0e0000000000ull,0xf0d0e0000000000ull,0x3f3d3e0000000000ull,0x705060000000000ull,0x705060000000000ull,0x705060000000000ull,0x705060000000000ull,0x705060000000000ull,0x705060000000000ull,0x705060000000000ull,0x301020000000000ull,0x301020000000000ull,0x301020000000000ull,0x301020000000000ull,0x301020000000000ull,0x301020000000000ull,0x705060000000000ull,0x705060000000000ull,0x301000000000000ull,0x301000000000000ull,0x301000000000000ull,0x301000000000000ull,0x301020000000000ull,0x301020000000000ull,0x705060000000000ull,0x705060000000000ull,0x201000000000000ull,0x201000000000000ull,0x301000000000000ull,0x301000000000000ull,0x301020000000000ull,0x301020000000000ull,0x705060000000000ull,0x705060000000000ull,0x0ull,0x200000000000000ull,0x301000000000000ull,0x301000000000000ull,0x301020000000000ull,0x301020000000000ull,0x705060000000000ull,0x705060000000000ull,0x0ull,0x1000000000000ull,0x501000000000000ull,0x101000000000000ull,0x101020000000000ull,0x101020000000000ull,0x505060000000000ull,0x3505060000000000ull,0xc3d3e0000000000ull,0x5050a0000000000ull,0x101020000000000ull,0x101020000000000ull,0x101020000000000ull,0x101020000000000ull,0x105060000000000ull,0x505060000000000ull}, - {0x7f7a7d0000000000ull,0x7f7a7d0000000000ull,0x1f1a1d0000000000ull,0x1f1a1d0000000000ull,0x1f1a1d0000000000ull,0x1f1a1d0000000000ull,0x1f1a1d0000000000ull,0x1f1a1d0000000000ull,0x7f7a7d0000000000ull,0x7f7a7d0000000000ull,0xf0a0d0000000000ull,0xf0a0d0000000000ull,0xf0a0d0000000000ull,0xf0a0d0000000000ull,0xf0a0d0000000000ull,0xf0a0d0000000000ull,0x7027d0000000000ull,0x702050000000000ull,0x702050000000000ull,0x702050000000000ull,0x702050000000000ull,0x702050000000000ull,0x702050000000000ull,0xf0a0d0000000000ull,0x7027c0000000000ull,0x702000000000000ull,0x702010000000000ull,0x702010000000000ull,0x702010000000000ull,0x702050000000000ull,0x702050000000000ull,0xf0a0d0000000000ull,0x202000000000000ull,0x202000000000000ull,0x202000000000000ull,0x702010000000000ull,0x702010000000000ull,0x702050000000000ull,0x702050000000000ull,0xf0a0d0000000000ull,0x202000000000000ull,0x0ull,0x202000000000000ull,0x702010000000000ull,0x702010000000000ull,0x702050000000000ull,0x702050000000000ull,0xf0a0d0000000000ull,0x202000000000000ull,0x200000000000000ull,0x202000000000000ull,0x202010000000000ull,0x202010000000000ull,0x202050000000000ull,0x202050000000000ull,0x7a0a0d0000000000ull,0x7a7a7d0000000000ull,0x87a7d0000000000ull,0xa0a150000000000ull,0x202050000000000ull,0x202050000000000ull,0x202050000000000ull,0x202050000000000ull,0x20a0d0000000000ull}, - {0xfdf5fb0000000000ull,0xfdf5fb0000000000ull,0xfdf5fb0000000000ull,0x3d353b0000000000ull,0x3d353b0000000000ull,0x3d353b0000000000ull,0x3d353b0000000000ull,0x3d353b0000000000ull,0xfdf5fb0000000000ull,0xfdf5fb0000000000ull,0xfdf5fb0000000000ull,0x1d151b0000000000ull,0x1d151b0000000000ull,0x1d151b0000000000ull,0x1d151b0000000000ull,0x1d151b0000000000ull,0xfcf4fa0000000000ull,0xc04fa0000000000ull,0xc040a0000000000ull,0xc040b0000000000ull,0xd050b0000000000ull,0xd050b0000000000ull,0xd050b0000000000ull,0xd050b0000000000ull,0xfcf4f80000000000ull,0xc04f80000000000ull,0xc04000000000000ull,0xc04030000000000ull,0xd05030000000000ull,0xd05030000000000ull,0xd050b0000000000ull,0xd050b0000000000ull,0xfcf4f80000000000ull,0x1000000000000ull,0x1000000000000ull,0x1000000000000ull,0xd05030000000000ull,0xd05030000000000ull,0xd050b0000000000ull,0xd050b0000000000ull,0xfff5f80000000000ull,0x201000000000000ull,0x0ull,0x0ull,0xd05030000000000ull,0xd05030000000000ull,0xd050b0000000000ull,0xd050b0000000000ull,0xfff4f90000000000ull,0x201000000000000ull,0x201000000000000ull,0x201000000000000ull,0xf05030000000000ull,0xf05030000000000ull,0xf050b0000000000ull,0xff050b0000000000ull,0xfef5fb0000000000ull,0xfdf5fb0000000000ull,0x9bf5fb0000000000ull,0x8795ab0000000000ull,0x8f858b0000000000ull,0x8f858b0000000000ull,0x8f858b0000000000ull,0xf858b0000000000ull}, - {0xebebf70000000000ull,0xebebf70000000000ull,0xebebf70000000000ull,0xebebf70000000000ull,0x6b6b770000000000ull,0x6b6b770000000000ull,0x6b6b770000000000ull,0x6b6b770000000000ull,0xeaeaf60000000000ull,0xeaeaf60000000000ull,0xeaeaf60000000000ull,0xebebf70000000000ull,0x2b2b370000000000ull,0x2b2b370000000000ull,0x2b2b370000000000ull,0x2b2b370000000000ull,0xe8e8f40000000000ull,0xe8e8f40000000000ull,0x808f40000000000ull,0x808140000000000ull,0x808170000000000ull,0xb0b170000000000ull,0xb0b170000000000ull,0xb0b170000000000ull,0xe8e8f00000000000ull,0xe8e8f00000000000ull,0x808f00000000000ull,0x808000000000000ull,0x808070000000000ull,0xb0b070000000000ull,0xb0b070000000000ull,0xb0b170000000000ull,0xe8e8f00000000000ull,0xe8e8f00000000000ull,0x0ull,0x0ull,0x0ull,0xb0b070000000000ull,0xb0b070000000000ull,0xb0b170000000000ull,0xece8f00000000000ull,0xece8f00000000000ull,0x0ull,0x0ull,0x0ull,0x1b0b070000000000ull,0x1b0b070000000000ull,0x1b0b170000000000ull,0xffe8f00000000000ull,0xfce8f00000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x1f0b070000000000ull,0x1f0b070000000000ull,0xff0b170000000000ull,0xfce9f50000000000ull,0xfde9f50000000000ull,0xf9ebf50000000000ull,0xb7ebf70000000000ull,0x8fabd70000000000ull,0x9f8b970000000000ull,0x9f8b970000000000ull,0x1f8b970000000000ull}, - {0xd6d6ee0000000000ull,0xd6d6ee0000000000ull,0xd6d6ee0000000000ull,0xd6d6ee0000000000ull,0xd7d7ef0000000000ull,0xd7d7ef0000000000ull,0xd7d7ef0000000000ull,0xd7d7ef0000000000ull,0xd4d4ec0000000000ull,0xd4d4ec0000000000ull,0xd4d4ec0000000000ull,0xd4d4ec0000000000ull,0xd7d7ef0000000000ull,0x57576f0000000000ull,0x57576f0000000000ull,0x57576f0000000000ull,0xd0d0e80000000000ull,0xd0d0e80000000000ull,0xd0d0e80000000000ull,0x1010e80000000000ull,0x1010280000000000ull,0x10102f0000000000ull,0x17172f0000000000ull,0x17172f0000000000ull,0xd0d0e80000000000ull,0xd0d0e00000000000ull,0xd0d0e00000000000ull,0x1010e00000000000ull,0x1010000000000000ull,0x10100f0000000000ull,0x17170f0000000000ull,0x17170f0000000000ull,0xd0d0e80000000000ull,0xd0d0e00000000000ull,0xd0d0e00000000000ull,0x0ull,0x0ull,0x0ull,0x17170f0000000000ull,0x17170f0000000000ull,0xd8d0e80000000000ull,0xd8d0e00000000000ull,0xd8d0e00000000000ull,0x0ull,0x0ull,0x0ull,0x37170f0000000000ull,0x37170f0000000000ull,0xffd0e80000000000ull,0xf8d0e00000000000ull,0xf8d0e00000000000ull,0x0ull,0x0ull,0x0ull,0x3f170f0000000000ull,0xff170f0000000000ull,0xf8f9e90000000000ull,0xf9d1e90000000000ull,0xf9d1e90000000000ull,0xf1d5eb0000000000ull,0xedd7ef0000000000ull,0x9fd7af0000000000ull,0xbf97af0000000000ull,0x3f97af0000000000ull}, - {0xbcacdc0000000000ull,0xbcacdc0000000000ull,0xbcacdc0000000000ull,0xbcacdc0000000000ull,0xbcacdc0000000000ull,0xbfafdf0000000000ull,0xbfafdf0000000000ull,0xbfafdf0000000000ull,0xb8a8d80000000000ull,0xb8a8d80000000000ull,0xb8a8d80000000000ull,0xb8a8d80000000000ull,0xb8a8d80000000000ull,0xbfafdf0000000000ull,0xbfafdf0000000000ull,0xbfafdf0000000000ull,0xb0a0d00000000000ull,0xb0a0d00000000000ull,0xb0a0d00000000000ull,0xb0a0d00000000000ull,0x3020d00000000000ull,0x3020500000000000ull,0x30205f0000000000ull,0x3f2f5f0000000000ull,0xb0a0d00000000000ull,0xb0a0d00000000000ull,0xb0a0c00000000000ull,0xb0a0c00000000000ull,0x3020c00000000000ull,0x3020000000000000ull,0x30201f0000000000ull,0x3f2f1f0000000000ull,0xb0a0d00000000000ull,0xb0a0d00000000000ull,0xb0a0c00000000000ull,0xb0a0c00000000000ull,0x0ull,0x0ull,0x0ull,0x3f2f1f0000000000ull,0xb0a0d00000000000ull,0xb0a0d00000000000ull,0xb0a0c00000000000ull,0xb0a0c00000000000ull,0x0ull,0x0ull,0x0ull,0xffaf1f0000000000ull,0xffa0d00000000000ull,0xf0a0d00000000000ull,0xf0a0c00000000000ull,0xf0a0c00000000000ull,0x0ull,0x0ull,0x0ull,0xff2f9f0000000000ull,0xf0f1d10000000000ull,0xf1a1d10000000000ull,0xf1a1d10000000000ull,0xf1a1d10000000000ull,0xe1a9d50000000000ull,0xd9afdf0000000000ull,0xbfafdf0000000000ull,0x7fafdf0000000000ull}, - {0xf858b80000000000ull,0xf858b80000000000ull,0xf858b80000000000ull,0xf858b80000000000ull,0xf858b80000000000ull,0xf858b80000000000ull,0xfe5ebe0000000000ull,0xfe5ebe0000000000ull,0xf050b00000000000ull,0xf050b00000000000ull,0xf050b00000000000ull,0xf050b00000000000ull,0xf050b00000000000ull,0xf050b00000000000ull,0xfe5ebe0000000000ull,0xfe5ebe0000000000ull,0xf050b00000000000ull,0xe040a00000000000ull,0xe040a00000000000ull,0xe040a00000000000ull,0xe040a00000000000ull,0xe040a00000000000ull,0xe040a00000000000ull,0xe040be0000000000ull,0xf050b00000000000ull,0xe040a00000000000ull,0xe040a00000000000ull,0xe040800000000000ull,0xe040800000000000ull,0xe040800000000000ull,0xe040000000000000ull,0xe0403e0000000000ull,0xf050b00000000000ull,0xe040a00000000000ull,0xe040a00000000000ull,0xe040800000000000ull,0xe040800000000000ull,0x0ull,0x0ull,0x0ull,0xf050b00000000000ull,0xe040a00000000000ull,0xe040a00000000000ull,0xe040800000000000ull,0xe040800000000000ull,0x0ull,0x0ull,0x0ull,0x5e50b00000000000ull,0x4040a00000000000ull,0x4040a00000000000ull,0x4040800000000000ull,0x4040800000000000ull,0x0ull,0x0ull,0x0ull,0x4050b00000000000ull,0x4040a00000000000ull,0x4040a00000000000ull,0x4040a00000000000ull,0x4040a00000000000ull,0x5050a80000000000ull,0x105ebe0000000000ull,0x5e5ebe0000000000ull}, - {0xf0b0700000000000ull,0xf0b0700000000000ull,0xf0b0700000000000ull,0xf0b0700000000000ull,0xf0b0700000000000ull,0xf0b0700000000000ull,0xf0b0700000000000ull,0xfcbc7c0000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xfcbc7c0000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xc080400000000000ull,0xc080400000000000ull,0xc080400000000000ull,0xc080400000000000ull,0xc080400000000000ull,0xc080400000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xc080400000000000ull,0xc080400000000000ull,0xc080000000000000ull,0xc080000000000000ull,0xc080000000000000ull,0xc080000000000000ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xc080400000000000ull,0xc080400000000000ull,0xc080000000000000ull,0xc080000000000000ull,0x0ull,0x0ull,0xe0a0600000000000ull,0xe0a0600000000000ull,0xc080400000000000ull,0xc080400000000000ull,0xc080000000000000ull,0xc080000000000000ull,0x0ull,0x0ull,0xaca0600000000000ull,0xa0a0600000000000ull,0x8080400000000000ull,0x8080400000000000ull,0x8080000000000000ull,0xa080000000000000ull,0x0ull,0x0ull,0xa0a0600000000000ull,0x80a0600000000000ull,0x8080400000000000ull,0x8080400000000000ull,0x8080400000000000ull,0x8080400000000000ull,0xa0a0500000000000ull,0x30bc7c0000000000ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull} - - }, - { - - {0x0ull,0xf0f7f3f1f0f0b00ull,0x101010101030100ull,0x303030303030302ull,0x303030303030302ull,0x707070707070702ull,0x707070707070702ull,0xf0f0f0f0f0f0702ull,0xf3f3f1f0f070600ull,0x7f7f7f3f1f0f0500ull,0x101010101030100ull,0x303030303030302ull,0x303030303030302ull,0x707070707070702ull,0x707070707070702ull,0xf0f0f0f0f0f0702ull,0x101010101000702ull,0x101010101050502ull,0x101010101010302ull,0x101010303030302ull,0x101030303030302ull,0x303070707070702ull,0x707070707070702ull,0xf0f0f0f0f0f0702ull,0x101011f1e030702ull,0x101013f05030702ull,0x101010103030702ull,0x101010303030702ull,0x101030303030702ull,0x303070707070702ull,0x707070707070702ull,0xf0f0f0f0f0f0702ull,0x101013e1f070702ull,0x101013d0f070702ull,0x10101030f070702ull,0x101010307070702ull,0x101030307070702ull,0x303070707070702ull,0x707070707070702ull,0xf0f0f0f0f0f0702ull,0x1017e3f1f0f0702ull,0x1017d3f1f0f0702ull,0x101030f1f0f0702ull,0x10103070f0f0702ull,0x10103070f0f0702ull,0x30307070f0f0702ull,0x70707070f0f0702ull,0xf0f0f0f0f0f0702ull,0xf007f3f1f0f0702ull,0x1017f3f1f0f0702ull,0x1010f1f1f0f0702ull,0x101070f1f0f0702ull,0x101070f1f0f0702ull,0x303070f1f0f0702ull,0x707070f1f0f0702ull,0x7f0f0f0f1f0f0702ull,0x7e7f7f3f1f0f0702ull,0xd7f7f3f1f0f0702ull,0xb0f1f3f1f0f0702ull,0x7070f1f1f0f0702ull,0x7070f1f1f0f0702ull,0x7070f1f1f0f0702ull,0x7070f1f1f0f0702ull,0x70f0f1f1f0f0702ull}, - {0xf0f3f1f0f0f0d04ull,0x0ull,0x8fefff7f3f1f0501ull,0x303030303030301ull,0x707070707070705ull,0x707070707070705ull,0xf0f0f0f0f0f0f05ull,0xf0f0f0f0f0f0f05ull,0xf3f3f1f0f0f0e04ull,0x7f7f7f3f1f0f0d00ull,0xffffff7f3f1f0b01ull,0x303030303030301ull,0x707070707070705ull,0x707070707070705ull,0xf0f0f0f0f0f0f05ull,0xf0f0f0f0f0f0f05ull,0xf1f1f97d3d1e0d05ull,0x8181810101010705ull,0x81818101010b0105ull,0x101010303030705ull,0x101030707070705ull,0x303070707070705ull,0x7070f0f0f0f0f05ull,0xf0f0f0f0f0f0f05ull,0xf1f1f97f3e1f0f05ull,0x8181813f3d070f05ull,0x8181817f0b070f05ull,0x101010307070f05ull,0x101030707070f05ull,0x303070707070f05ull,0x7070f0f0f0f0f05ull,0xf0f0f0f0f0f0f05ull,0xf1f1f97e3f1f0f05ull,0x8181817d3f0f0f05ull,0x8181817b1f0f0f05ull,0x10101071f0f0f05ull,0x10103070f0f0f05ull,0x30307070f0f0f05ull,0x7070f0f0f0f0f05ull,0xf0f0f0f0f0f0f05ull,0xf1f1fe7f3f1f0f05ull,0x8181fd7f3f1f0f05ull,0x8181fb7f3f1f0f05ull,0x8181871f3f1f0f05ull,0x8181870f1f1f0f05ull,0x8383870f1f1f0f05ull,0x87878f0f1f1f0f05ull,0x8f8f0f0f1f1f0f05ull,0xfff0ff7f3f1f0f05ull,0x8181ff7f3f1f0f05ull,0x8181ff7f3f1f0f05ull,0x81819f3f3f1f0f05ull,0x81818f1f3f1f0f05ull,0x83838f1f3f1f0f05ull,0x87878f1f3f1f0f05ull,0xff0f8f1f3f1f0f05ull,0xfeffff7f3f1f0f05ull,0xfdffff7f3f1f0f05ull,0x9bffff7f3f1f0f05ull,0x879fbf7f3f1f0f05ull,0x8f8f9f3f3f1f0f05ull,0x8f8f9f3f3f1f0f05ull,0x8f8f9f3f3f1f0f05ull,0xf8f9f3f3f1f0f05ull}, - {0xfdfdfdfd7d3d1d08ull,0xf0f7f3f1f0f0b08ull,0x0ull,0xcdedffff7f3f0b02ull,0x707070707070702ull,0xf0f0f0f0f0f0f0aull,0xf0f0f0f0f0f0f0aull,0x1f1f1f1f1f1f1f0aull,0xfdfdfdfd7d3d1c08ull,0x7f7f7f3f1f0f0d08ull,0xffffff7f3f1f0b00ull,0xffffffff7f2f1702ull,0x707070707070702ull,0xf0f0f0f0f0f0f0aull,0xf0f0f0f0f0f0f0aull,0x1f1f1f1f1f1f1f0aull,0xf1f1f9fd7d3c1e0aull,0xe1e1f1f9793d180aull,0x8181818101010e0aull,0x818181830317030aull,0x101030707070f0aull,0x303070f0f0f0f0aull,0x7070f0f0f0f0f0aull,0xf0f1f1f1f1f1f0aull,0xf1f1f9fd7e3f1f0aull,0xe1e1f1ff7d3f1f0aull,0x818181ff7b0f1f0aull,0x818181ff170f1f0aull,0x10103070f0f1f0aull,0x303070f0f0f1f0aull,0x7070f0f0f0f1f0aull,0xf0f1f1f1f1f1f0aull,0xf1f1f9fe7f3f1f0aull,0xe1e1f1fd7f3f1f0aull,0x818181fb7f1f1f0aull,0x818181f73f1f1f0aull,0x8181838f3f1f1f0aull,0x8383878f1f1f1f0aull,0x87878f8f1f1f1f0aull,0x8f8f9f1f1f1f1f0aull,0xf1f1feff7f3f1f0aull,0xe1e1fdff7f3f1f0aull,0x8181fbff7f3f1f0aull,0x8181f7ff7f3f1f0aull,0x81818fbf7f3f1f0aull,0x83838f9f3f3f1f0aull,0x87878f9f3f3f1f0aull,0x8f8f1f9f3f3f1f0aull,0xfff0ffff7f3f1f0aull,0xe1e1ffff7f3f1f0aull,0x8181ffff7f3f1f0aull,0x8181ffff7f3f1f0aull,0x8181bfff7f3f1f0aull,0x83839fbf7f3f1f0aull,0x87879fbf7f3f1f0aull,0xff0f9fbf7f3f1f0aull,0xfeffffff7f3f1f0aull,0xfdffffff7f3f1f0aull,0xfbffffff7f3f1f0aull,0xb7ffffff7f3f1f0aull,0x8fbfffff7f3f1f0aull,0x9f9fbfff7f3f1f0aull,0x9f9fbfff7f3f1f0aull,0x1f9fbfff7f3f1f0aull}, - {0xfdfdfdfdfd7d3d14ull,0xf8f8f8f8f8783810ull,0x8dedff7f3f1f1510ull,0x0ull,0xd9f9fdfffe7c1404ull,0xf0f0f0f0f0f0e04ull,0x1f1f1f1f1f1f1e14ull,0x1f1f1f1f1f1f1e14ull,0xfdfdfdfdfd7d3c14ull,0xf8f8f8f8f8783810ull,0xffffff7f3f1d1a10ull,0xfdfdffff7f3f1600ull,0xfdfdfdffff5d2e04ull,0xf0f0f0f0f0f0e04ull,0x1f1f1f1f1f1f1e14ull,0x1f1f1f1f1f1f1e14ull,0xf1f1f9fdfd7c3c14ull,0xe1e1f1f9f9783c14ull,0xc1c1e1f1f17a3014ull,0x8181818181011c14ull,0x81818387872f0614ull,0x303070f0f0f1e14ull,0x7070f1f1f1f1e14ull,0xf0f1f1f1f1f1e14ull,0xf1f1f9fdfc7d3e14ull,0xe1e1f1f9fd7d3e14ull,0xc1c1e1fffb7d3e14ull,0x818181fff71d3e14ull,0x818183ffaf1f3e14ull,0x8383878f9f1f3e14ull,0x87878f9f9f1f3e14ull,0x8f8f9f9f1f1f3e14ull,0xf1f1f9fcff7f3e14ull,0xe1e1f1fdff7f3e14ull,0xc1c1e1fbff7f3e14ull,0x818181f7ff3f3e14ull,0x818183efff3f3e14ull,0x8383879fff3f3e14ull,0x87878f9fbf3f3e14ull,0x8f8f9f1fbf3f3e14ull,0xf1f1fcffff7f3e14ull,0xe1e1fdffff7f3e14ull,0xc1c1fbffff7f3e14ull,0x8181f7ffff7f3e14ull,0x8181efffff7f3e14ull,0x83839fffff7f3e14ull,0x87879fbfff7f3e14ull,0x8f8f1fbfff7f3e14ull,0xfff0ffffff7f3e14ull,0xe1e1ffffff7f3e14ull,0xc1c1ffffff7f3e14ull,0x8181ffffff7f3e14ull,0x8181ffffff7f3e14ull,0x8383ffffff7f3e14ull,0x8787bfffff7f3e14ull,0xff0fbfffff7f3e14ull,0xfeffffffff7f3e14ull,0xfdffffffff7f3e14ull,0xfbffffffff7f3e14ull,0xf7ffffffff7f3e14ull,0xefffffffff7f3e14ull,0x9fffffffff7f3e14ull,0xbfbfffffff7f3e14ull,0x3fbfffffff7f3e14ull}, - {0xf8f8f8f8f8f87828ull,0xf8f8f8f8f8f87828ull,0xf0f0f0f0f0f07020ull,0xd9f9ffff7f3e2820ull,0x0ull,0xf1f1f9fcfcf8a808ull,0x1f1f1f1f1f1e1c08ull,0xbfbfbfbfbfbebc28ull,0xf8f8f8f8f8f87828ull,0xf8f8f8f8f8f87828ull,0xf0f0f0f0f0f07020ull,0xfdfdffffffba7420ull,0xf9f9fdfffefc6800ull,0xf9f9f9fcfcb85808ull,0x1f1f1f1f1f1e1c08ull,0xbfbfbfbfbfbe3c28ull,0xf0f0f8f8f8f87828ull,0xe0e0f0f8f8f87828ull,0xc0c0e0f0f0f07828ull,0x8181c1e1e1f46028ull,0x8181818181803828ull,0x8383878f8f5e0c28ull,0x87878f9f9f1e3c28ull,0x8f8f9fbfbf3e3c28ull,0xf1f1f9f9f8f87c28ull,0xe1e1f1f9f9f87c28ull,0xc1c1e1f1f9f87c28ull,0x8181c1fff5f87c28ull,0x818181ffefb87c28ull,0x838387ffdfbe7c28ull,0x87878f9fbfbe7c28ull,0x8f8f9fbf3fbe7c28ull,0xf1f1f9f8fdfc7c28ull,0xe1e1f1f9fdfc7c28ull,0xc1c1e1f9fffc7c28ull,0x8181c1f7fffc7c28ull,0x818181effffc7c28ull,0x838387dffffe7c28ull,0x87878fbffffe7c28ull,0x8f8f9f3ffffe7c28ull,0xf1f1f8fdfffe7c28ull,0xe1e1f9fdfffe7c28ull,0xc1c1f9fffffe7c28ull,0x8181f7fffffe7c28ull,0x8181effffffe7c28ull,0x8383dffffffe7c28ull,0x8787bffffffe7c28ull,0x8f8f3ffffffe7c28ull,0xfff0fdfffffe7c28ull,0xe1e1fdfffffe7c28ull,0xc1c1fffffffe7c28ull,0x8181fffffffe7c28ull,0x8181fffffffe7c28ull,0x8383fffffffe7c28ull,0x8787fffffffe7c28ull,0xff0ffffffffe7c28ull,0xfcfdfffffffe7c28ull,0xfdfdfffffffe7c28ull,0xf9fffffffffe7c28ull,0xf7fffffffffe7c28ull,0xeffffffffffe7c28ull,0xdffffffffffe7c28ull,0xbffffffffffe7c28ull,0x7ffffffffffe7c28ull}, - {0xf8f8f8f8f8f8f850ull,0xf0f0f0f0f0f0f050ull,0xf0f0f0f0f0f0f050ull,0xe0e0e0e0e0e0e040ull,0xf1f1fdfffefcd040ull,0x0ull,0xf0f0f0f8f8f0d010ull,0xbfbfbfbfbebcb810ull,0xf8f8f8f8f8f8f850ull,0xf0f0f0f0f0f0f050ull,0xf0f0f0f0f0f0f050ull,0xe0e0e0e0e0e0e040ull,0xf9f9fdfffef4e840ull,0xf1f1f9fcfcf8d000ull,0xf0f0f0f8f8f0b010ull,0xbfbfbfbfbebc3810ull,0xf0f0f8f8f8f8f850ull,0xe0e0f0f0f0f0f050ull,0xc0c0e0f0f0f0f050ull,0x8080c0e0e0e0f050ull,0x818181c1c0e8c050ull,0x8181818180807050ull,0x87878f9f9ebc1850ull,0x8f8f9fbfbe3c7850ull,0xf0f0f8f8f8f8f850ull,0xe0e0f0f0f0f0f850ull,0xc0c0e0f0f0f0f850ull,0x8080c0e0f0f0f850ull,0x818181ffe8f0f850ull,0x818181ffdef0f850ull,0x87878fffbefcf850ull,0x8f8f9fbf7efcf850ull,0xf1f1f9f8f8f8f850ull,0xe1e1f1f1f8f8f850ull,0xc1c1e1f1f8f8f850ull,0x8181c1f1fcf8f850ull,0x818181effcf8f850ull,0x818181dffef8f850ull,0x87878fbffefcf850ull,0x8f8f9f7ffefcf850ull,0xf1f1f8f9fcfcf850ull,0xe1e1f1f9fcfcf850ull,0xc1c1f1f9fcfcf850ull,0x8181f1fdfefcf850ull,0x8181effffefcf850ull,0x8181dffffefcf850ull,0x8787bffffefcf850ull,0x8f8f7ffffefcf850ull,0xfff0f9fdfefcf850ull,0xe1e1f9fdfefcf850ull,0xc1c1f9fdfefcf850ull,0x8181fdfffefcf850ull,0x8181fffffefcf850ull,0x8181fffffefcf850ull,0x8787fffffefcf850ull,0xff0ffffffefcf850ull,0xf8f9fdfffefcf850ull,0xf9f9fdfffefcf850ull,0xf9f9fdfffefcf850ull,0xf1fdfffffefcf850ull,0xedfffffffefcf850ull,0xdffffffffefcf850ull,0xbffffffffefcf850ull,0x7ffffffffefcf850ull}, - {0xf0f0f0f0f0f0f0a0ull,0xf0f0f0f0f0f0f0a0ull,0xe0e0e0e0e0e0e0a0ull,0xe0e0e0e0e0e0e0a0ull,0xc0c0c0c0c0c0c080ull,0xf1f1f9fcfcf8a080ull,0x0ull,0xf0f0f0f0f0f0b020ull,0xf0f0f0f0f0f0f0a0ull,0xf0f0f0f0f0f0f0a0ull,0xe0e0e0e0e0e0e0a0ull,0xe0e0e0e0e0e0e0a0ull,0xc0c0c0c0c0c0c080ull,0xf1f1f9fcfcf8d080ull,0xe0f0f0f8f8f0b000ull,0xe0e0f0f0f0f07020ull,0xf0f0f0f0f0f0f0a0ull,0xe0e0f0f0f0f0f0a0ull,0xc0c0e0e0e0e0e0a0ull,0x8080c0e0e0e0e0a0ull,0x808080c0c0c0e0a0ull,0x8181818080d080a0ull,0x818181808080e0a0ull,0x8f8f9fbebc78b0a0ull,0xf0f0f0f0f0f0f0a0ull,0xe0e0f0f0f0f0f0a0ull,0xc0c0e0e0e0e0f0a0ull,0x8080c0e0e0e0f0a0ull,0x808080c0e0e0f0a0ull,0x818181fed0e0f0a0ull,0x818181fcbce0f0a0ull,0x8f8f9ffe7cf8f0a0ull,0xf0f0f0f0f0f0f0a0ull,0xe0e0f0f0f0f0f0a0ull,0xc0c0e0e0f0f0f0a0ull,0x8080c0e0f0f0f0a0ull,0x808080e0f8f0f0a0ull,0x818181def8f0f0a0ull,0x818181befcf0f0a0ull,0x8f8f9f7efcf8f0a0ull,0xf1f1f0f0f8f8f0a0ull,0xe1e1f1f0f8f8f0a0ull,0xc1c1e1f0f8f8f0a0ull,0x8181e1f0f8f8f0a0ull,0x8181e1f8fcf8f0a0ull,0x8181dffefcf8f0a0ull,0x8181bffefcf8f0a0ull,0x8f8f7ffefcf8f0a0ull,0xfff0f1f8fcf8f0a0ull,0xe1e1f1f8fcf8f0a0ull,0xc1c1f1f8fcf8f0a0ull,0x8181f1f8fcf8f0a0ull,0x8181f9fcfcf8f0a0ull,0x8181fffefcf8f0a0ull,0x8181fffefcf8f0a0ull,0xff0ffffefcf8f0a0ull,0xf0f1f9fcfcf8f0a0ull,0xf1f1f9fcfcf8f0a0ull,0xf1f1f9fcfcf8f0a0ull,0xf1f1f9fcfcf8f0a0ull,0xe1f9fdfefcf8f0a0ull,0xd9fffffefcf8f0a0ull,0xbffffffefcf8f0a0ull,0x7ffffffefcf8f0a0ull}, - {0xf0f0f0f0f0f0e040ull,0xe0e0e0e0e0e0e040ull,0xe0e0e0e0e0e0e040ull,0xc0c0c0c0c0c0c040ull,0xc0c0c0c0c0c0c040ull,0x8080808080c08000ull,0xf0f0f0f8f8f0d000ull,0x0ull,0xf0f0f0f0f0f0e040ull,0xe0e0e0e0e0e0e040ull,0xe0e0e0e0e0e0e040ull,0xc0c0c0c0c0c0c040ull,0xc0c0c0c0c0c0c040ull,0x8080808080c08000ull,0xe0f0f0f8f8f0a000ull,0xe0e0e0f0f0e06000ull,0xf0f0f0f0f0f0e040ull,0xe0e0e0e0e0e0e040ull,0xc0c0e0e0e0e0e040ull,0x8080c0c0c0c0c040ull,0x808080c0c0c0c040ull,0x808080808080c040ull,0x8080808080a0a040ull,0x808080808000e040ull,0xf0f0f0f0f0f0e040ull,0xe0e0e0e0e0e0e040ull,0xc0c0e0e0e0e0e040ull,0x8080c0c0c0c0e040ull,0x808080c0c0c0e040ull,0x80808080c0c0e040ull,0x808080fca0c0e040ull,0x808080f878c0e040ull,0xf0f0f0f0f0f0e040ull,0xe0e0e0e0e0e0e040ull,0xc0c0e0e0e0e0e040ull,0x8080c0c0e0e0e040ull,0x808080c0e0e0e040ull,0x808080c0f0e0e040ull,0x808080bcf0e0e040ull,0x8080807cf8e0e040ull,0xf0f0f0f0f0f0e040ull,0xe0e0e0e0f0f0e040ull,0xc0c0e0e0f0f0e040ull,0x8080c0e0f0f0e040ull,0x8080c0e0f0f0e040ull,0x8080c0f0f8f0e040ull,0x8080befcf8f0e040ull,0x80807efcf8f0e040ull,0xfef0f0f0f8f0e040ull,0xe0e0e0f0f8f0e040ull,0xc0c0e0f0f8f0e040ull,0x8080e0f0f8f0e040ull,0x8080e0f0f8f0e040ull,0x8080f0f8f8f0e040ull,0x8080fefcf8f0e040ull,0xf000fefcf8f0e040ull,0xe0f0f0f8f8f0e040ull,0xe0e0f0f8f8f0e040ull,0xe0e0f0f8f8f0e040ull,0xe0e0f0f8f8f0e040ull,0xe0e0f0f8f8f0e040ull,0xd0f0f8fcf8f0e040ull,0xb0fefefcf8f0e040ull,0x7efefefcf8f0e040ull}, - {0x1f1f3f1f0f070400ull,0x1f1f7f3f1f0f0600ull,0x1f1f0f0703030001ull,0x1f1f0f0703030203ull,0x1f1f0f0703030203ull,0x1f1f0f0707070603ull,0x1f1f0f0707070603ull,0x1f1f0f0f0f0f0603ull,0x0ull,0x7f7f7f3f1f0b0c00ull,0x101010101010005ull,0x303030303030203ull,0x303030303030203ull,0x707070707070603ull,0x707070707070603ull,0xf0f0f0f0f0f0603ull,0xf3f3f1f0f060403ull,0x7f7f7f3f1f0d0403ull,0x101010101030207ull,0x303030303030203ull,0x303030303030203ull,0x707070707070603ull,0x707070707070603ull,0xf0f0f0f0f0f0603ull,0x10101011e030607ull,0x101013f05030607ull,0x101010103030607ull,0x101030303030603ull,0x303030303030603ull,0x707070707070603ull,0x707070707070603ull,0xf0f0f0f0f0f0603ull,0x1013f3e1f0f0603ull,0x1017f3d1f0f0603ull,0x10101030f070603ull,0x101030307070603ull,0x303030307070603ull,0x707070707070603ull,0x707070707070603ull,0xf0f0f0f0f0f0603ull,0x1017e3f1f0f0603ull,0x1017d3f1f0f0603ull,0x101030f1f0f0603ull,0x10103070f0f0603ull,0x30303070f0f0603ull,0x70707070f0f0603ull,0x70707070f0f0603ull,0xf0f0f0f0f0f0603ull,0x7f7e7f3f1f0f0603ull,0x7f7d7f3f1f0f0603ull,0xf030f1f1f0f0603ull,0x303070f1f0f0603ull,0x303070f1f0f0603ull,0x707070f1f0f0603ull,0x707070f1f0f0603ull,0x7f0f0f0f1f0f0603ull,0x7e7f7f3f1f0f0603ull,0xd7f7f3f1f0f0603ull,0xb0f1f3f1f0f0603ull,0x7070f1f1f0f0603ull,0x7070f1f1f0f0603ull,0x7070f1f1f0f0603ull,0x7070f1f1f0f0603ull,0x70f0f1f1f0f0603ull}, - {0x3f3f3f1f0f0f0d04ull,0x3f3f7f3f1f0f0900ull,0xbfffff7f3f1f0d01ull,0x3f3f1f0f07070103ull,0x3f3f1f0f07070507ull,0x3f3f1f0f07070507ull,0x3f3f1f0f0f0f0d07ull,0x3f3f1f0f0f0f0d07ull,0xf3f3f1f0f0f0c04ull,0x0ull,0xffffff7f3f150901ull,0x303030303030103ull,0x707070707070507ull,0x707070707070507ull,0xf0f0f0f0f0f0d07ull,0xf0f0f0f0f0f0d07ull,0xf3f3f1f0f0e0c07ull,0x7f7f7f3f1f0d0807ull,0xffffff7f3f1b0907ull,0x303030303030507ull,0x707070707070507ull,0x707070707070507ull,0xf0f0f0f0f0f0d07ull,0xf0f0f0f0f0f0d07ull,0xf9f9fd7f3e1f0d07ull,0x818181013d070d07ull,0x8181817f0b070d07ull,0x101030307070d07ull,0x303070707070d07ull,0x707070707070d07ull,0xf0f0f0f0f0f0d07ull,0xf0f0f0f0f0f0d07ull,0xf9f9ff7e3f1f0d07ull,0x8181ff7d3f1f0d07ull,0x8181ff7b3f1f0d07ull,0x10103071f0f0d07ull,0x30307070f0f0d07ull,0x70707070f0f0d07ull,0xf0f0f0f0f0f0d07ull,0xf0f0f0f0f0f0d07ull,0xf9f9fe7f3f1f0d07ull,0x8181fd7f3f1f0d07ull,0x8181fb7f3f1f0d07ull,0x8181871f3f1f0d07ull,0x8383870f1f1f0d07ull,0x8787870f1f1f0d07ull,0x8f8f8f0f1f1f0d07ull,0x8f8f0f0f1f1f0d07ull,0xfffeff7f3f1f0d07ull,0xfffdff7f3f1f0d07ull,0xfffbff7f3f1f0d07ull,0x8f879f3f3f1f0d07ull,0x87878f1f3f1f0d07ull,0x87878f1f3f1f0d07ull,0x8f8f8f1f3f1f0d07ull,0xff0f8f1f3f1f0d07ull,0xfeffff7f3f1f0d07ull,0xfdffff7f3f1f0d07ull,0x9bffff7f3f1f0d07ull,0x879fbf7f3f1f0d07ull,0x8f8f9f3f3f1f0d07ull,0x8f8f9f3f3f1f0d07ull,0x8f8f9f3f3f1f0d07ull,0xf8f9f3f3f1f0d07ull}, - {0xffffffff7f3f190cull,0x7f7f7f3f1f0f0b08ull,0xffffff7f3f1f0100ull,0xffffffff7f3f0b02ull,0x7f7f3f1f0f0f0306ull,0x7f7f3f1f0f0f0b0eull,0x7f7f3f1f0f0f0b0eull,0x7f7f3f1f1f1f1b0eull,0xfdfdfdfd7d3d180cull,0x7f7f7f3f1f0f0908ull,0x0ull,0xfdfdffff7f2b1202ull,0x707070707070306ull,0xf0f0f0f0f0f0b0eull,0xf0f0f0f0f0f0b0eull,0x1f1f1f1f1f1f1b0eull,0xfdfdfdfd7d3c1a0eull,0x7f7f7f3f1f0d090eull,0xffffff7f3f1b010eull,0xffffffff6f37030eull,0x707070707070b0eull,0xf0f0f0f0f0f0b0eull,0xf0f0f0f0f0f0b0eull,0x1f1f1f1f1f1f1b0eull,0xf9f9fdfd7e3f1b0eull,0xf1f1f9ff7d3f1b0eull,0x818181817b0f1b0eull,0x818183ff170f1b0eull,0x30307070f0f1b0eull,0x7070f0f0f0f1b0eull,0xf0f0f0f0f0f1b0eull,0x1f1f1f1f1f1f1b0eull,0xf9f9fdfe7f3f1b0eull,0xf1f1fffd7f3f1b0eull,0x8181fffb7f3f1b0eull,0x8181fff77f3f1b0eull,0x8383878f3f1f1b0eull,0x87878f8f1f1f1b0eull,0x8f8f8f8f1f1f1b0eull,0x9f9f9f1f1f1f1b0eull,0xf9f9feff7f3f1b0eull,0xf1f1fdff7f3f1b0eull,0x8181fbff7f3f1b0eull,0x8181f7ff7f3f1b0eull,0x83838fbf7f3f1b0eull,0x87878f9f3f3f1b0eull,0x8f8f8f9f3f3f1b0eull,0x9f9f1f9f3f3f1b0eull,0xfffeffff7f3f1b0eull,0xfffdffff7f3f1b0eull,0xfffbffff7f3f1b0eull,0xfff7ffff7f3f1b0eull,0x8f8fbfff7f3f1b0eull,0x8f8f9fbf7f3f1b0eull,0x9f8f9fbf7f3f1b0eull,0xff1f9fbf7f3f1b0eull,0xfeffffff7f3f1b0eull,0xfdffffff7f3f1b0eull,0xfbffffff7f3f1b0eull,0xb7ffffff7f3f1b0eull,0x8fbfffff7f3f1b0eull,0x9f9fbfff7f3f1b0eull,0x9f9fbfff7f3f1b0eull,0x1f9fbfff7f3f1b0eull}, - {0xfffffffffd7d351cull,0xfffffffffc7c3018ull,0xffffff7f3f1f1410ull,0xffffffff7f3f0000ull,0xffffffffff7d1404ull,0xffffff3f1f1f060cull,0xffffff3f1f1f161cull,0xffffff3f1f1f161cull,0xfdfdfdfdfd7d341cull,0xf8f8f8f8f8783018ull,0xffffff7f3f1d1210ull,0x0ull,0xf9f9fdfffe542404ull,0xf0f0f0f0f0f060cull,0x1f1f1f1f1f1f161cull,0x1f1f1f1f1f1f161cull,0xfdfdfdfdfd7c341cull,0xf9f9f9f9f978341cull,0xffffff7f3d1b141cull,0xfdfdffff7f37141cull,0xfdfdfdffdf6f141cull,0xf0f0f0f0f0f161cull,0x1f1f1f1f1f1f161cull,0x1f1f1f1f1f1f161cull,0xf9f9fdfdfc7d361cull,0xf1f1f9f9fd7d361cull,0xe1e1f1fffb7d361cull,0x81818181f71d361cull,0x838387ffaf1f361cull,0x87878f8f9f1f361cull,0x8f8f9f9f9f1f361cull,0x9f9f9f9f1f1f361cull,0xf9f9fdfcff7f361cull,0xf1f1f9fdff7f361cull,0xe1e1fffbff7f361cull,0x8181fff7ff7f361cull,0x8383ffefff7f361cull,0x87878f9fff3f361cull,0x8f8f9f9fbf3f361cull,0x9f9f9f1fbf3f361cull,0xf9f9fcffff7f361cull,0xf1f1fdffff7f361cull,0xe1e1fbffff7f361cull,0x8181f7ffff7f361cull,0x8383efffff7f361cull,0x87879fffff7f361cull,0x8f8f9fbfff7f361cull,0x9f9f1fbfff7f361cull,0xfffcffffff7f361cull,0xfdfdffffff7f361cull,0xfffbffffff7f361cull,0xfff7ffffff7f361cull,0xffefffffff7f361cull,0x9f9fffffff7f361cull,0x9f9fbfffff7f361cull,0xff1fbfffff7f361cull,0xfeffffffff7f361cull,0xfdffffffff7f361cull,0xfbffffffff7f361cull,0xf7ffffffff7f361cull,0xefffffffff7f361cull,0x9fffffffff7f361cull,0xbfbfffffff7f361cull,0x3fbfffffff7f361cull}, - {0xfffffffcf8f86838ull,0xfffffffcf8f86838ull,0xfffffffcf8f86030ull,0xffffffffffbe2820ull,0xfffffffffefc0000ull,0xfffffffcfcf82808ull,0xffffffff3f3e0c18ull,0xffffffffbfbeac38ull,0xf8f8f8f8f8f86838ull,0xf8f8f8f8f8f86838ull,0xf0f0f0f0f0f06030ull,0xfdfdffff7f2a2420ull,0x0ull,0xf1f1f9fcfcb84808ull,0x1f1f1f1f1f1e0c18ull,0xbfbfbfbfbfbe2c38ull,0xf8f8f8f8f8f86838ull,0xf8f8f8f8f8f86838ull,0xf0f0f0f0f0f06838ull,0xfdfdfffffbf62838ull,0xf9f9fdfffeec2838ull,0xf9f9f9fcbcd82838ull,0x9f9f9f9f9f1e2c38ull,0xbfbfbfbfbf3e2c38ull,0xf9f9f9f9f8f86c38ull,0xf1f1f9f9f9f86c38ull,0xe1e1f1f1f9f86c38ull,0xc1c1e1fff5f86c38ull,0x81818181efb86c38ull,0x87878fffdfbe6c38ull,0x8f8f9f9fbfbe6c38ull,0x9f9fbfbf3fbe6c38ull,0xf9f9f9f8fdfc6c38ull,0xf1f1f9f9fdfc6c38ull,0xe1e1f1f9fffc6c38ull,0xc1c1fff7fffe6c38ull,0x8181ffeffffe6c38ull,0x8787ffdffffe6c38ull,0x8f8f9fbffffe6c38ull,0x9f9fbf3ffffe6c38ull,0xf9f9f8fdfffe6c38ull,0xf1f1f9fdfffe6c38ull,0xe1e1f9fffffe6c38ull,0xc1c1f7fffffe6c38ull,0x8181effffffe6c38ull,0x8787dffffffe6c38ull,0x8f8fbffffffe6c38ull,0x9f9f3ffffffe6c38ull,0xfff8fdfffffe6c38ull,0xf9f9fdfffffe6c38ull,0xf9f9fffffffe6c38ull,0xfff7fffffffe6c38ull,0xffeffffffffe6c38ull,0xffdffffffffe6c38ull,0xbfbffffffffe6c38ull,0xff3ffffffffe6c38ull,0xfcfdfffffffe6c38ull,0xfdfdfffffffe6c38ull,0xf9fffffffffe6c38ull,0xf7fffffffffe6c38ull,0xeffffffffffe6c38ull,0xdffffffffffe6c38ull,0xbffffffffffe6c38ull,0x7ffffffffffe6c38ull}, - {0xfefefcf8f8f8d870ull,0xfefefcf8f0f0d070ull,0xfefefcf8f0f0d070ull,0xfefefcf8f0f0c060ull,0xfffffdfffefcd040ull,0xfffffdfcfcf88000ull,0xfefefcf8f8f0d010ull,0xfffffffffefc9830ull,0xf8f8f8f8f8f8d870ull,0xf0f0f0f0f0f0d070ull,0xf0f0f0f0f0f0d070ull,0xe0e0e0e0e0e0c060ull,0xf9f9fdfffed44840ull,0x0ull,0xf0f0f0f8f8f09010ull,0xbfbfbfbfbebc1830ull,0xf8f8f8f8f8f8d870ull,0xf0f0f0f0f0f0d070ull,0xf0f0f0f0f0f0d070ull,0xe0e0e0e0e0e0d070ull,0xf9f9fdfff6ecc070ull,0xf1f1f9fcfcd88070ull,0xf0f0f0f8f8b09070ull,0xbfbfbfbfbe3c5870ull,0xf8f8f8f8f8f8d870ull,0xf0f0f0f0f0f0d870ull,0xe0e0f0f0f0f0d870ull,0xc0c0e0e0f0f0d870ull,0x8181c1ffe8f0d870ull,0x81818181def0d870ull,0x8f8f9fffbefcd870ull,0x9f9fbfbf7efcd870ull,0xf9f9f9f8f8f8d870ull,0xf1f1f1f1f8f8d870ull,0xe1e1f1f1f8f8d870ull,0xc1c1e1f1fcf8d870ull,0x8181ffeffefcd870ull,0x8181ffdffefcd870ull,0x8f8fffbffefcd870ull,0x9f9fbf7ffefcd870ull,0xf9f9f8f9fcfcd870ull,0xf1f1f1f9fcfcd870ull,0xe1e1f1f9fcfcd870ull,0xc1c1f1fdfefcd870ull,0x8181effffefcd870ull,0x8181dffffefcd870ull,0x8f8fbffffefcd870ull,0x9f9f7ffffefcd870ull,0xfff8f9fdfefcd870ull,0xf9f1f9fdfefcd870ull,0xf1f1f9fdfefcd870ull,0xf1f1fdfffefcd870ull,0xffeffffffefcd870ull,0xffdffffffefcd870ull,0xffbffffffefcd870ull,0xff7ffffffefcd870ull,0xf8f9fdfffefcd870ull,0xf9f9fdfffefcd870ull,0xf9f9fdfffefcd870ull,0xf1fdfffffefcd870ull,0xedfffffffefcd870ull,0xdffffffffefcd870ull,0xbffffffffefcd870ull,0x7ffffffffefcd870ull}, - {0xfcfcf8f0f0f0b0e0ull,0xfcfcf8f0f0f0b0e0ull,0xfcfcf8f0e0e0a0e0ull,0xfcfcf8f0e0e0a0e0ull,0xfcfcf8f0e0e080c0ull,0xfdfdf9fcfcf8b080ull,0xfcfcf8f8f8f09000ull,0xfcfcf8f0f0f0b020ull,0xf0f0f0f0f0f0b0e0ull,0xf0f0f0f0f0f0b0e0ull,0xe0e0e0e0e0e0a0e0ull,0xe0e0e0e0e0e0a0e0ull,0xc0c0c0c0c0c080c0ull,0xf1f1f9fcfca89080ull,0x0ull,0xf0f0f0f0f0f03020ull,0xf0f0f0f0f0f0b0e0ull,0xf0f0f0f0f0f0b0e0ull,0xe0e0e0e0e0e0a0e0ull,0xe0e0e0e0e0e0a0e0ull,0xc0c0c0c0c0c0a0e0ull,0xf1f1f9fcfcd890e0ull,0xf0f0f0f8f8b010e0ull,0xf0f0f0f0f07030e0ull,0xf0f0f0f0f0f0b0e0ull,0xf0f0f0f0f0f0b0e0ull,0xe0e0e0e0e0e0b0e0ull,0xc0c0e0e0e0e0b0e0ull,0x8080c0c0e0e0b0e0ull,0x818181fed0e0b0e0ull,0x81818180bce0b0e0ull,0x9f9fbffe7cf8b0e0ull,0xf0f0f0f0f0f0b0e0ull,0xf0f0f0f0f0f0b0e0ull,0xe0e0e0e0f0f0b0e0ull,0xc0c0e0e0f0f0b0e0ull,0x8080c0e0f8f0b0e0ull,0x8181ffdefcf8b0e0ull,0x8181ffbefcf8b0e0ull,0x9f9fff7efcf8b0e0ull,0xf1f1f0f0f8f8b0e0ull,0xf1f1f1f0f8f8b0e0ull,0xe1e1e1f0f8f8b0e0ull,0xc1c1e1f0f8f8b0e0ull,0x8181e1f8fcf8b0e0ull,0x8181dffefcf8b0e0ull,0x8181bffefcf8b0e0ull,0x9f9f7ffefcf8b0e0ull,0xfff0f1f8fcf8b0e0ull,0xf1f1f1f8fcf8b0e0ull,0xe1e1f1f8fcf8b0e0ull,0xe1e1f1f8fcf8b0e0ull,0xf1e1f9fcfcf8b0e0ull,0xffdffffefcf8b0e0ull,0xffbffffefcf8b0e0ull,0xff7ffffefcf8b0e0ull,0xf0f1f9fcfcf8b0e0ull,0xf1f1f9fcfcf8b0e0ull,0xf1f1f9fcfcf8b0e0ull,0xf1f1f9fcfcf8b0e0ull,0xe1f9fdfefcf8b0e0ull,0xd9fffffefcf8b0e0ull,0xbffffffefcf8b0e0ull,0x7ffffffefcf8b0e0ull}, - {0xf8f8f0f0f0f060c0ull,0xf8f8f0e0e0e060c0ull,0xf8f8f0e0e0e060c0ull,0xf8f8f0e0c0c040c0ull,0xf8f8f0e0c0c040c0ull,0xf8f8f0e0c0c00080ull,0xf8f8f0f8f8f06000ull,0xf8f8f0f0f0e02000ull,0xf0f0f0f0f0f060c0ull,0xe0e0e0e0e0e060c0ull,0xe0e0e0e0e0e060c0ull,0xc0c0c0c0c0c040c0ull,0xc0c0c0c0c0c040c0ull,0x80808080808000a0ull,0xf0f0f0f8f8d03000ull,0x0ull,0xf0f0f0f0f0f060c0ull,0xe0e0e0e0e0e060c0ull,0xe0e0e0e0e0e060c0ull,0xc0c0c0c0c0c040c0ull,0xc0c0c0c0c0c040c0ull,0x8080808080c040e0ull,0xe0f0f0f8f8b020c0ull,0xe0e0e0f0f06020c0ull,0xf0f0f0f0f0f060c0ull,0xe0e0e0e0e0e060c0ull,0xe0e0e0e0e0e060c0ull,0xc0c0c0c0c0c060c0ull,0x8080c0c0c0c060c0ull,0x80808080c0c060e0ull,0x808080fca0c060e0ull,0x8080808078c060e0ull,0xf0f0f0f0f0f060c0ull,0xe0e0e0e0e0e060c0ull,0xe0e0e0e0e0e060c0ull,0xc0c0c0c0e0e060c0ull,0x8080c0c0e0e060c0ull,0x808080c0f0e060c0ull,0x8080febcf8f060c0ull,0x8080fc7cf8f060c0ull,0xf0f0f0f0f0f060c0ull,0xe0e0e0e0f0f060c0ull,0xe0e0e0e0f0f060c0ull,0xc0c0c0e0f0f060c0ull,0x8080c0e0f0f060c0ull,0x8080c0f0f8f060c0ull,0x8080befcf8f060c0ull,0x80807efcf8f060c0ull,0xfef0f0f0f8f060c0ull,0xe0e0e0f0f8f060c0ull,0xe0e0e0f0f8f060c0ull,0xc0c0e0f0f8f060c0ull,0xc0c0e0f0f8f060c0ull,0xf0c0f0f8f8f060c0ull,0xfebefefcf8f060c0ull,0xfe7efefcf8f060c0ull,0xe0f0f0f8f8f060c0ull,0xe0e0f0f8f8f060c0ull,0xe0e0f0f8f8f060c0ull,0xe0e0f0f8f8f060c0ull,0xe0e0f0f8f8f060c0ull,0xd0f0f8fcf8f060c0ull,0xb0fefefcf8f060c0ull,0x7efefefcf8f060c0ull}, - {0x7f7f7f3f1f0e0000ull,0x7f7f7f3f1f020000ull,0x1f1f1f0f07020100ull,0x1f1f1f0f07020300ull,0x1f1f1f0f07020300ull,0x1f1f1f0f07060700ull,0x1f1f1f0f07060700ull,0x1f1f1f0f0f0e0700ull,0xf3f3f1f0f040600ull,0x7f7f7f3f1f0e0500ull,0xf0f070303000100ull,0xf0f070303020300ull,0xf0f070303020300ull,0xf0f070707060700ull,0xf0f070707060700ull,0xf0f0f0f0f0e0700ull,0x0ull,0x7f7f7f3f1f0c0800ull,0x101010101000100ull,0x303030303020300ull,0x303030303020300ull,0x707070707060700ull,0x707070707060700ull,0xf0f0f0f0f0e0700ull,0xf3f3f1f0e040700ull,0x7f7f7f3f1d040700ull,0x101010103020700ull,0x303030303020700ull,0x303030303020700ull,0x707070707060700ull,0x707070707060700ull,0xf0f0f0f0f0e0700ull,0x101013e1f0e0702ull,0x1017f3d1f0e0702ull,0x10101030f060700ull,0x303030307060700ull,0x303030307060700ull,0x707070707060700ull,0x707070707060700ull,0xf0f0f0f0f0e0700ull,0x3f3f7e3f1f0e0700ull,0x7f7f7d3f1f0e0700ull,0x101030f1f0e0700ull,0x30303070f0e0700ull,0x30303070f0e0700ull,0x70707070f0e0700ull,0x70707070f0e0700ull,0xf0f0f0f0f0e0700ull,0x7f7e7f3f1f0e0700ull,0x7f7d7f3f1f0e0700ull,0xf030f1f1f0e0700ull,0x303070f1f0e0700ull,0x303070f1f0e0700ull,0x707070f1f0e0700ull,0x707070f1f0e0700ull,0x7f0f0f0f1f0e0700ull,0x7e7f7f3f1f0e0700ull,0xd7f7f3f1f0e0700ull,0xb0f1f3f1f0e0700ull,0x7070f1f1f0e0700ull,0x7070f1f1f0e0700ull,0x7070f1f1f0e0700ull,0x7070f1f1f0e0700ull,0x70f0f1f1f0e0700ull}, - {0xffffff7f3f1d0d00ull,0xffffff7f3f1d0000ull,0xffffff7f3f050100ull,0x3f3f3f1f0f050300ull,0x3f3f3f1f0f050700ull,0x3f3f3f1f0f050700ull,0x3f3f3f1f0f0d0f00ull,0x3f3f3f1f0f0d0f00ull,0x1f3f3f1f0f0d0e00ull,0x7f7f7f3f1f090d00ull,0xffffff7f3f1d0b00ull,0x1f1f0f0707010300ull,0x1f1f0f0707050700ull,0x1f1f0f0707050700ull,0x1f1f0f0f0f0d0f00ull,0x1f1f0f0f0f0d0f00ull,0xf3f3f1f0f0c0c00ull,0x0ull,0xffffff7f3f190500ull,0x303030303010300ull,0x707070707050700ull,0x707070707050700ull,0xf0f0f0f0f0d0f00ull,0xf0f0f0f0f0d0f00ull,0xf3f3f1f0e0c0f00ull,0x7f7f7f3f1d080f00ull,0xffffff7f3b090f00ull,0x303030307050f00ull,0x707070707050f00ull,0x707070707050f00ull,0xf0f0f0f0f0d0f00ull,0xf0f0f0f0f0d0f00ull,0xfdfdff7e3f1d0f00ull,0x8181817d3f1d0f00ull,0x8181ff7b3f1d0f00ull,0x30303071f0d0f00ull,0x70707070f0d0f00ull,0x70707070f0d0f00ull,0xf0f0f0f0f0d0f00ull,0xf0f0f0f0f0d0f00ull,0xfffffe7f3f1d0f00ull,0xfffffd7f3f1d0f00ull,0xfffffb7f3f1d0f00ull,0x8383871f3f1d0f00ull,0x8787870f1f1d0f00ull,0x8787870f1f1d0f00ull,0x8f8f8f0f1f1d0f00ull,0x8f8f0f0f1f1d0f00ull,0xfffeff7f3f1d0f00ull,0xfffdff7f3f1d0f00ull,0xfffbff7f3f1d0f00ull,0x8f879f3f3f1d0f00ull,0x87878f1f3f1d0f00ull,0x87878f1f3f1d0f00ull,0x8f8f8f1f3f1d0f00ull,0xff0f8f1f3f1d0f00ull,0xfeffff7f3f1d0f00ull,0xfdffff7f3f1d0f00ull,0x9bffff7f3f1d0f00ull,0x879fbf7f3f1d0f00ull,0x8f8f9f3f3f1d0f00ull,0x8f8f9f3f3f1d0f00ull,0x8f8f9f3f3f1d0f00ull,0xf8f9f3f3f1d0f00ull}, - {0xffffffff7f3b1d00ull,0xffffffff7f3a1800ull,0xffffffff7f3b0000ull,0xffffffff7f0b0300ull,0x7f7f7f3f1f0b0700ull,0x7f7f7f3f1f0b0f00ull,0x7f7f7f3f1f0b0f00ull,0x7f7f7f3f1f1b1f00ull,0xffffffff7f391c00ull,0x7f7f7f3f1f0b0d00ull,0xffffff7f3f110b00ull,0xffffffff7f2b1700ull,0x3f3f1f0f0f030700ull,0x3f3f1f0f0f0b0f00ull,0x3f3f1f0f0f0b0f00ull,0x3f3f1f1f1f1b1f00ull,0xfdfdfdfd7d381c00ull,0x7f7f7f3f1f090c00ull,0x0ull,0xfdfdffff6f330a00ull,0x707070707030700ull,0xf0f0f0f0f0b0f00ull,0xf0f0f0f0f0b0f00ull,0x1f1f1f1f1f1b1f00ull,0xfdfdfdfd7e3b1f00ull,0x7f7f7f3f1d091f00ull,0xffffff7f3b091f00ull,0xffffffef770b1f00ull,0x70707070f0b1f00ull,0xf0f0f0f0f0b1f00ull,0xf0f0f0f0f0b1f00ull,0x1f1f1f1f1f1b1f00ull,0xfdfdfdfe7f3b1f00ull,0xf9f9fffd7f3b1f00ull,0x818181fb7f3b1f00ull,0x8383fff77f3b1f00ull,0x8787878f3f1b1f00ull,0x8f8f8f8f1f1b1f00ull,0x8f8f8f8f1f1b1f00ull,0x9f9f9f1f1f1b1f00ull,0xfdfdfeff7f3b1f00ull,0xfffffdff7f3b1f00ull,0xfffffbff7f3b1f00ull,0xfffff7ff7f3b1f00ull,0x87878fbf7f3b1f00ull,0x8f8f8f9f3f3b1f00ull,0x8f8f8f9f3f3b1f00ull,0x9f9f1f9f3f3b1f00ull,0xfffeffff7f3b1f00ull,0xfffdffff7f3b1f00ull,0xfffbffff7f3b1f00ull,0xfff7ffff7f3b1f00ull,0x8f8fbfff7f3b1f00ull,0x8f8f9fbf7f3b1f00ull,0x9f8f9fbf7f3b1f00ull,0xff1f9fbf7f3b1f00ull,0xfeffffff7f3b1f00ull,0xfdffffff7f3b1f00ull,0xfbffffff7f3b1f00ull,0xb7ffffff7f3b1f00ull,0x8fbfffff7f3b1f00ull,0x9f9fbfff7f3b1f00ull,0x9f9fbfff7f3b1f00ull,0x1f9fbfff7f3b1f00ull}, - {0xffffffffff753d00ull,0xfffffffffe743800ull,0xffffffffff743000ull,0xffffffffff770000ull,0xffffffffff170600ull,0xffffff7f3f170e00ull,0xffffff7f3f171e00ull,0xffffff7f3f171e00ull,0xfffffffdfd753c00ull,0xfffffffcfc703800ull,0xffffff7f3f151a00ull,0xffffffff7f231600ull,0xffffffffff552e00ull,0x7f7f3f1f1f070e00ull,0x7f7f3f1f1f171e00ull,0x7f7f3f1f1f171e00ull,0xfdfdfdfdfd743c00ull,0xf8f8f8f8f8703800ull,0xffffff7f3d131800ull,0x0ull,0xf9f9fdffde640400ull,0xf0f0f0f0f070e00ull,0x1f1f1f1f1f171e00ull,0x1f1f1f1f1f171e00ull,0xfdfdfdfdfc753e00ull,0xf9f9f9f9fd753e00ull,0xfffffffdbb153e00ull,0xfdfdfffff7153e00ull,0xfdfdfddfef153e00ull,0x8f8f8f8f9f173e00ull,0x9f9f9f9f9f173e00ull,0x9f9f9f9f1f173e00ull,0xfdfdfdfcff773e00ull,0xf9f9f9fdff773e00ull,0xf1f1fffbff773e00ull,0x818181f7ff773e00ull,0x8787ffefff773e00ull,0x8f8f8f9fff373e00ull,0x9f9f9f9fbf373e00ull,0x9f9f9f1fbf373e00ull,0xfdfdfcffff773e00ull,0xf9f9fdffff773e00ull,0xfffffbffff773e00ull,0xfffff7ffff773e00ull,0xffffefffff773e00ull,0x8f8f9fffff773e00ull,0x9f9f9fbfff773e00ull,0x9f9f1fbfff773e00ull,0xfffcffffff773e00ull,0xfdfdffffff773e00ull,0xfffbffffff773e00ull,0xfff7ffffff773e00ull,0xffefffffff773e00ull,0x9f9fffffff773e00ull,0x9f9fbfffff773e00ull,0xff1fbfffff773e00ull,0xfeffffffff773e00ull,0xfdffffffff773e00ull,0xfbffffffff773e00ull,0xf7ffffffff773e00ull,0xefffffffff773e00ull,0x9fffffffff773e00ull,0xbfbfffffff773e00ull,0x3fbfffffff773e00ull}, - {0xfffffffefce87800ull,0xfffffffefce87800ull,0xfffffffefce87000ull,0xffffffffffe86000ull,0xffffffffffee0000ull,0xffffffffff2e0c00ull,0xffffffff7f2e1c00ull,0xffffffffffaebc00ull,0xfefefcf8f8e87800ull,0xfefefcf8f8e87800ull,0xfefefcf8f8e07000ull,0xffffffffffaa7400ull,0xfffffdfffec46800ull,0xfffffdfcfca85800ull,0xffffff3f3f0e1c00ull,0xffffffbfbfae3c00ull,0xf8f8f8f8f8e87800ull,0xf8f8f8f8f8e87800ull,0xf0f0f0f0f0e07000ull,0xfdfdffff7b262000ull,0x0ull,0xf1f1f9fcbcc81800ull,0x1f1f1f1f1f0e1c00ull,0xbfbfbfbfbf2e3c00ull,0xf9f9f9f9f8e87c00ull,0xf9f9f9f9f9e87c00ull,0xf1f1f1f1f9e87c00ull,0xfdfdfffbf7a87c00ull,0xf9f9fdffefa87c00ull,0xf9f9f9bddda87c00ull,0x9f9f9f9fbfae7c00ull,0xbfbfbfbf3fae7c00ull,0xf9f9f9f8fdec7c00ull,0xf9f9f9f9fdec7c00ull,0xf1f1f1f9ffec7c00ull,0xe1e1fff7ffee7c00ull,0x818181efffee7c00ull,0x8f8fffdfffee7c00ull,0x9f9f9fbfffee7c00ull,0xbfbfbf3fffee7c00ull,0xf9f9f8fdffee7c00ull,0xf9f9f9fdffee7c00ull,0xf1f1f9ffffee7c00ull,0xfffff7ffffee7c00ull,0xffffefffffee7c00ull,0xffffdfffffee7c00ull,0x9f9fbfffffee7c00ull,0xbfbf3fffffee7c00ull,0xfff8fdffffee7c00ull,0xf9f9fdffffee7c00ull,0xf9f9ffffffee7c00ull,0xfff7ffffffee7c00ull,0xffefffffffee7c00ull,0xffdfffffffee7c00ull,0xbfbfffffffee7c00ull,0xff3fffffffee7c00ull,0xfcfdffffffee7c00ull,0xfdfdffffffee7c00ull,0xf9ffffffffee7c00ull,0xf7ffffffffee7c00ull,0xefffffffffee7c00ull,0xdfffffffffee7c00ull,0xbfffffffffee7c00ull,0x7fffffffffee7c00ull}, - {0xfefefefcf8d8f800ull,0xfefefefcf8d0f000ull,0xfefefefcf8d0f000ull,0xfefefefcf8d0e000ull,0xfffffffffed0c000ull,0xfffffffffedc0000ull,0xfffffffffe5c1800ull,0xfffffffffedcb800ull,0xfcfcf8f8f8d8f800ull,0xfcfcf8f0f0d0f000ull,0xfcfcf8f0f0d0f000ull,0xfcfcf8f0f0c0e000ull,0xfdfdfdfffed4e800ull,0xfdfdf9fcfc88d000ull,0xfcfcf8f8f8d0b000ull,0xfffffffffe9c3800ull,0xf8f8f8f8f8d8f800ull,0xf0f0f0f0f0d0f000ull,0xf0f0f0f0f0d0f000ull,0xe0e0e0e0e0c0e000ull,0xf9f9fdfff6cc5000ull,0x0ull,0xf0f0f0f8f8903000ull,0xbfbfbfbfbe1c3800ull,0xf8f8f8f8f8d8f800ull,0xf0f0f0f0f0d0f800ull,0xf0f0f0f0f0d0f800ull,0xe0e0e0e0f0d0f800ull,0xf9f9fdf7eed0f800ull,0xf1f1f9fcdc90f800ull,0xf0f0f0f8b890f800ull,0xbfbfbfbf7edcf800ull,0xf9f9f9f8f8d8f800ull,0xf1f1f1f1f8d8f800ull,0xf1f1f1f1f8d8f800ull,0xe1e1e1f1fcd8f800ull,0xc1c1ffeffedcf800ull,0x818181dffedcf800ull,0x9f9fffbffedcf800ull,0xbfbfbf7ffedcf800ull,0xf9f9f8f9fcdcf800ull,0xf1f1f1f9fcdcf800ull,0xf1f1f1f9fcdcf800ull,0xe1e1f1fdfedcf800ull,0xffffeffffedcf800ull,0xffffdffffedcf800ull,0xffffbffffedcf800ull,0xbfbf7ffffedcf800ull,0xfff8f9fdfedcf800ull,0xf9f1f9fdfedcf800ull,0xf1f1f9fdfedcf800ull,0xf1f1fdfffedcf800ull,0xffeffffffedcf800ull,0xffdffffffedcf800ull,0xffbffffffedcf800ull,0xff7ffffffedcf800ull,0xf8f9fdfffedcf800ull,0xf9f9fdfffedcf800ull,0xf9f9fdfffedcf800ull,0xf1fdfffffedcf800ull,0xedfffffffedcf800ull,0xdffffffffedcf800ull,0xbffffffffedcf800ull,0x7ffffffffedcf800ull}, - {0xfcfcfcf8f0b0f000ull,0xfcfcfcf8f0b0f000ull,0xfcfcfcf8f0a0e000ull,0xfcfcfcf8f0a0e000ull,0xfcfcfcf8f0a0c000ull,0xfffffffefca08000ull,0xfffffffefcb80000ull,0xfffffffefcb8b000ull,0xf8f8f0f0f0b0f000ull,0xf8f8f0f0f0b0f000ull,0xf8f8f0e0e0a0e000ull,0xf8f8f0e0e0a0e000ull,0xf8f8f0e0e080c000ull,0xf9f9f9fcfcb8d000ull,0xf8f8f0f8f890b000ull,0xf8f8f0f0f0b07000ull,0xf0f0f0f0f0b0f000ull,0xf0f0f0f0f0b0f000ull,0xe0e0e0e0e0a0e000ull,0xe0e0e0e0e0a0e000ull,0xc0c0c0c0c080c000ull,0xf1f1f9fcfc98a000ull,0x0ull,0xf0f0f0f0f0303000ull,0xf0f0f0f0f0b0f000ull,0xf0f0f0f0f0b0f000ull,0xe0e0e0e0e0a0f000ull,0xe0e0e0e0e0a0f000ull,0xc0c0c0c0e0a0f000ull,0xf1f1f9fcdc90f000ull,0xf0f0f0f8b810f000ull,0xf0f0f0f07030f000ull,0xf0f0f0f0f0b0f000ull,0xf0f0f0f0f0b0f000ull,0xe0e0e0e0f0b0f000ull,0xe0e0e0e0f0b0f000ull,0xc0c0c0e0f8b0f000ull,0x8181ffdefcb8f000ull,0x818181befcb8f000ull,0xbfbfff7efcb8f000ull,0xf1f1f0f0f8b8f000ull,0xf1f1f1f0f8b8f000ull,0xe1e1e1f0f8b8f000ull,0xe1e1e1f0f8b8f000ull,0xc1c1e1f8fcb8f000ull,0xffffdffefcb8f000ull,0xffffbffefcb8f000ull,0xffff7ffefcb8f000ull,0xfff0f1f8fcb8f000ull,0xf1f1f1f8fcb8f000ull,0xe1e1f1f8fcb8f000ull,0xe1e1f1f8fcb8f000ull,0xf1e1f9fcfcb8f000ull,0xffdffffefcb8f000ull,0xffbffffefcb8f000ull,0xff7ffffefcb8f000ull,0xf0f1f9fcfcb8f000ull,0xf1f1f9fcfcb8f000ull,0xf1f1f9fcfcb8f000ull,0xf1f1f9fcfcb8f000ull,0xe1f9fdfefcb8f000ull,0xd9fffffefcb8f000ull,0xbffffffefcb8f000ull,0x7ffffffefcb8f000ull}, - {0xf8f8f8f0f070e000ull,0xf8f8f8f0e060e000ull,0xf8f8f8f0e060e000ull,0xf8f8f8f0e040c000ull,0xf8f8f8f0e040c000ull,0xf8f8f8f0e0408000ull,0xfefefefcf8400000ull,0xfefefefcf8700000ull,0xf0f0f0f0f070e000ull,0xf0f0e0e0e060e000ull,0xf0f0e0e0e060e000ull,0xf0f0e0c0c040c000ull,0xf0f0e0c0c040c000ull,0xf0f0e0c0c0008000ull,0xf0f0f0f8f870a000ull,0xf0f0e0f0f0206000ull,0xf0f0f0f0f070e000ull,0xe0e0e0e0e060e000ull,0xe0e0e0e0e060e000ull,0xc0c0c0c0c040c000ull,0xc0c0c0c0c040c000ull,0x8080808080008000ull,0xf0f0f0f8f8301000ull,0x0ull,0xf0f0f0f0f070e000ull,0xe0e0e0e0e060e000ull,0xe0e0e0e0e060e000ull,0xc0c0c0c0c040e000ull,0xc0c0c0c0c040e000ull,0x80808080c040e000ull,0xe0f0f0f8b820e000ull,0xe0e0e0f07020e000ull,0xf0f0f0f0f070e000ull,0xe0e0e0e0e060e000ull,0xe0e0e0e0e060e000ull,0xc0c0c0c0e060e000ull,0xc0c0c0c0e060e000ull,0x808080c0f060e000ull,0x8080febcf870e040ull,0x8080807cf870e040ull,0xf0f0f0f0f070e000ull,0xe0e0e0e0f070e000ull,0xe0e0e0e0f070e000ull,0xc0c0c0e0f070e000ull,0xc0c0c0e0f070e000ull,0x8080c0f0f870e000ull,0xfefebefcf870e000ull,0xfcfc7efcf870e000ull,0xfef0f0f0f870e000ull,0xe0e0e0f0f870e000ull,0xe0e0e0f0f870e000ull,0xc0c0e0f0f870e000ull,0xc0c0e0f0f870e000ull,0xf0c0f0f8f870e000ull,0xfebefefcf870e000ull,0xfe7efefcf870e000ull,0xe0f0f0f8f870e000ull,0xe0e0f0f8f870e000ull,0xe0e0f0f8f870e000ull,0xe0e0f0f8f870e000ull,0xe0e0f0f8f870e000ull,0xd0f0f8fcf870e000ull,0xb0fefefcf870e000ull,0x7efefefcf870e000ull}, - {0x7f7f7f3f1e0f0000ull,0x7f7f7f3f1e030000ull,0x1f1f1f0f06030000ull,0x1f1f1f0f06030000ull,0x1f1f1f0f06030000ull,0x1f1f1f0f06070000ull,0x1f1f1f0f06070000ull,0x1f1f1f0f0e0f0000ull,0x7f7f7f3f1e000000ull,0x7f7f7f3f02000000ull,0xf0f0f0702010000ull,0xf0f0f0702030000ull,0xf0f0f0702030000ull,0xf0f0f0706070000ull,0xf0f0f0706070000ull,0xf0f0f0f0e0f0000ull,0xf3f3f1f0c060000ull,0x7f7f7f3f1e0d0000ull,0x707030300010000ull,0x707030302030000ull,0x707030302030000ull,0x707070706070000ull,0x707070706070000ull,0xf0f0f0f0e0f0000ull,0x0ull,0x7f7f7f3f1c080000ull,0x101010100010000ull,0x303030302030000ull,0x303030302030000ull,0x707070706070000ull,0x707070706070000ull,0xf0f0f0f0e0f0000ull,0xf3f3f1e0c0f0000ull,0x7f7f7f3d0c0f0000ull,0x10101030a070000ull,0x303030302070000ull,0x303030302070000ull,0x707070706070000ull,0x707070706070000ull,0xf0f0f0f0e0f0000ull,0x1017e3f1e0f0000ull,0x7f7f7d3f1e0f0000ull,0x101030f1e0f0000ull,0x30303070e0f0000ull,0x30303070e0f0000ull,0x70707070e0f0000ull,0x70707070e0f0000ull,0xf0f0f0f0e0f0000ull,0x7f7e7f3f1e0f0000ull,0x7f7d7f3f1e0f0000ull,0xf030f1f1e0f0000ull,0x303070f1e0f0000ull,0x303070f1e0f0000ull,0x707070f1e0f0000ull,0x707070f1e0f0000ull,0x7f0f0f0f1e0f0000ull,0x7e7f7f3f1e0f0000ull,0xd7f7f3f1e0f0000ull,0xb0f1f3f1e0f0000ull,0x7070f1f1e0f0000ull,0x7070f1f1e0f0000ull,0x7070f1f1e0f0000ull,0x7070f1f1e0f0000ull,0x70f0f1f1e0f0000ull}, - {0xffffff7f3d1f0000ull,0xffffff7f3d1f0000ull,0xffffff7f3d070000ull,0x3f3f3f1f0d070000ull,0x3f3f3f1f0d070000ull,0x3f3f3f1f0d070000ull,0x3f3f3f1f0d0f0000ull,0x3f3f3f1f0d0f0000ull,0xffffff7f3d1c0000ull,0xffffff7f3d000000ull,0xffffff7f05010000ull,0x1f1f1f0f05030000ull,0x1f1f1f0f05070000ull,0x1f1f1f0f05070000ull,0x1f1f1f0f0d0f0000ull,0x1f1f1f0f0d0f0000ull,0xf3f3f1f0d0e0000ull,0x7f7f7f3f190d0000ull,0xffffff7f3d1b0000ull,0xf0f070701030000ull,0xf0f070705070000ull,0xf0f070705070000ull,0xf0f0f0f0d0f0000ull,0xf0f0f0f0d0f0000ull,0xf3f3f1f0c0c0000ull,0x0ull,0xffffff7f39050000ull,0x303030301030000ull,0x707070705070000ull,0x707070705070000ull,0xf0f0f0f0d0f0000ull,0xf0f0f0f0d0f0000ull,0xf3f3f1e0c0f0000ull,0x7f7f7f3d080f0000ull,0xffffff7b090f0000ull,0x3030307150f0000ull,0x7070707050f0000ull,0x7070707050f0000ull,0xf0f0f0f0d0f0000ull,0xf0f0f0f0d0f0000ull,0xfffffe7f3d1f0000ull,0x8181fd7f3d1f0000ull,0xfffffb7f3d1f0000ull,0x8383871f3d1f0000ull,0x8787870f1d1f0000ull,0x8787870f1d1f0000ull,0x8f8f8f0f1d1f0000ull,0x8f8f0f0f1d1f0000ull,0xfffeff7f3d1f0000ull,0xfffdff7f3d1f0000ull,0xfffbff7f3d1f0000ull,0x8f879f3f3d1f0000ull,0x87878f1f3d1f0000ull,0x87878f1f3d1f0000ull,0x8f8f8f1f3d1f0000ull,0xff0f8f1f3d1f0000ull,0xfeffff7f3d1f0000ull,0xfdffff7f3d1f0000ull,0x9bffff7f3d1f0000ull,0x879fbf7f3d1f0000ull,0x8f8f9f3f3d1f0000ull,0x8f8f9f3f3d1f0000ull,0x8f8f9f3f3d1f0000ull,0xf8f9f3f3d1f0000ull}, - {0xffffffff7b3f0000ull,0xffffffff7b3e0000ull,0xffffffff7b3f0000ull,0xffffffff7b0f0000ull,0x7f7f7f3f1b0f0000ull,0x7f7f7f3f1b0f0000ull,0x7f7f7f3f1b0f0000ull,0x7f7f7f3f1b1f0000ull,0xffffffff7b3c0000ull,0xffffffff7a380000ull,0xffffffff7b000000ull,0xffffffff0b030000ull,0x3f3f3f1f0b070000ull,0x3f3f3f1f0b0f0000ull,0x3f3f3f1f0b0f0000ull,0x3f3f3f1f1b1f0000ull,0xffffffff793c0000ull,0x7f7f7f3f1b0d0000ull,0xffffff7f311b0000ull,0xffffffff6b370000ull,0x1f1f0f0f03070000ull,0x1f1f0f0f0b0f0000ull,0x1f1f0f0f0b0f0000ull,0x1f1f1f1f1b1f0000ull,0xfdfdfdfd783d0000ull,0x7f7f7f3f190d0000ull,0x0ull,0xfdfdffef730b0000ull,0x707070703070000ull,0xf0f0f0f0b0f0000ull,0xf0f0f0f0b0f0000ull,0x1f1f1f1f1b1f0000ull,0xfdfdfdfe7b3f0000ull,0xffffffbd291f0000ull,0xfffffffb291f0000ull,0xffffeff72b1f0000ull,0x8787878f2b1f0000ull,0x8f8f8f8f0b1f0000ull,0x8f8f8f8f0b1f0000ull,0x9f9f9f1f1b1f0000ull,0xfdfdfeff7b3f0000ull,0xfffffdff7b3f0000ull,0x8181fbff7b3f0000ull,0xfffff7ff7b3f0000ull,0x87878fbf7b3f0000ull,0x8f8f8f9f3b3f0000ull,0x8f8f8f9f3b3f0000ull,0x9f9f1f9f3b3f0000ull,0xfffeffff7b3f0000ull,0xfffdffff7b3f0000ull,0xfffbffff7b3f0000ull,0xfff7ffff7b3f0000ull,0x8f8fbfff7b3f0000ull,0x8f8f9fbf7b3f0000ull,0x9f8f9fbf7b3f0000ull,0xff1f9fbf7b3f0000ull,0xfeffffff7b3f0000ull,0xfdffffff7b3f0000ull,0xfbffffff7b3f0000ull,0xb7ffffff7b3f0000ull,0x8fbfffff7b3f0000ull,0x9f9fbfff7b3f0000ull,0x9f9fbfff7b3f0000ull,0x1f9fbfff7b3f0000ull}, - {0xfffffffff77c0000ull,0xfffffffff67c0000ull,0xfffffffff77c0000ull,0xfffffffff77f0000ull,0xfffffffff71f0000ull,0xffffff7f371f0000ull,0xffffff7f371f0000ull,0xffffff7f371f0000ull,0xfffffffff57c0000ull,0xfffffffef4780000ull,0xfffffffff4700000ull,0xfffffffff7000000ull,0xffffffff17070000ull,0x7f7f7f3f170f0000ull,0x7f7f7f3f171f0000ull,0x7f7f7f3f171f0000ull,0xfffffdfdf57c0000ull,0xfefefcfcf0780000ull,0xffffff7f351b0000ull,0xffffffff63370000ull,0xfffffdffd76f0000ull,0x3f3f1f1f070f0000ull,0x3f3f1f1f171f0000ull,0x3f3f1f1f171f0000ull,0xfdfdfdfdf47d0000ull,0xf8f8f8f8f0780000ull,0xffffff7d33190000ull,0x0ull,0xf9f9fddfe6040000ull,0xf0f0f0f070f0000ull,0x1f1f1f1f171f0000ull,0x1f1f1f1f171f0000ull,0xfdfdfdfcf57f0000ull,0xf9f9f9fdf57f0000ull,0xfffffdfbd53f0000ull,0xfdfdfff7d53f0000ull,0xfdfdddefd53f0000ull,0x8f8f8f9fd73f0000ull,0x9f9f9f9f973f0000ull,0x9f9f9f1f973f0000ull,0xfdfdfcfff77f0000ull,0xf9f9fdfff77f0000ull,0xfffffbfff77f0000ull,0x8181f7fff77f0000ull,0xffffeffff77f0000ull,0x8f8f9ffff77f0000ull,0x9f9f9fbff77f0000ull,0x9f9f1fbff77f0000ull,0xfffcfffff77f0000ull,0xfdfdfffff77f0000ull,0xfffbfffff77f0000ull,0xfff7fffff77f0000ull,0xffeffffff77f0000ull,0x9f9ffffff77f0000ull,0x9f9fbffff77f0000ull,0xff1fbffff77f0000ull,0xfefffffff77f0000ull,0xfdfffffff77f0000ull,0xfbfffffff77f0000ull,0xf7fffffff77f0000ull,0xeffffffff77f0000ull,0x9ffffffff77f0000ull,0xbfbffffff77f0000ull,0x3fbffffff77f0000ull}, - {0xfffffffeecf80000ull,0xfffffffeecf80000ull,0xfffffffeecf80000ull,0xffffffffeff80000ull,0xffffffffeffe0000ull,0xffffffffef3e0000ull,0xffffffff6f3e0000ull,0xffffffffef3e0000ull,0xfefefefce8f80000ull,0xfefefefce8f80000ull,0xfefefefce8f00000ull,0xffffffffe8e00000ull,0xffffffffef000000ull,0xffffffff2f0e0000ull,0xffffff7f2f1e0000ull,0xffffffffaf3e0000ull,0xfcfcf8f8e8f80000ull,0xfcfcf8f8e8f80000ull,0xfcfcf8f8e0f00000ull,0xfdfdffffebf60000ull,0xfdfdfdffc6ec0000ull,0xfdfdf9fcacd80000ull,0x7f7f3f3f0f1e0000ull,0xffffbfbfaf3e0000ull,0xf8f8f8f8e8f80000ull,0xf8f8f8f8e8f80000ull,0xf0f0f0f0e0f00000ull,0xfdfdfffb67200000ull,0x0ull,0xf1f1f9bccc980000ull,0x1f1f1f1f0f1e0000ull,0xbfbfbfbf2fbe0000ull,0xf9f9f9f8e9fc0000ull,0xf9f9f9f9e9fc0000ull,0xf1f1f1f9ebfc0000ull,0xfdfdfbf7abfc0000ull,0xf9f9fdefabfc0000ull,0xf9f9b9ddabfc0000ull,0x9f9f9fbfaffe0000ull,0xbfbfbf3faffe0000ull,0xf9f9f8fdeffe0000ull,0xf9f9f9fdeffe0000ull,0xf1f1f9ffeffe0000ull,0xfffff7ffeffe0000ull,0x8181efffeffe0000ull,0xffffdfffeffe0000ull,0x9f9fbfffeffe0000ull,0xbfbf3fffeffe0000ull,0xfff8fdffeffe0000ull,0xf9f9fdffeffe0000ull,0xf9f9ffffeffe0000ull,0xfff7ffffeffe0000ull,0xffefffffeffe0000ull,0xffdfffffeffe0000ull,0xbfbfffffeffe0000ull,0xff3fffffeffe0000ull,0xfcfdffffeffe0000ull,0xfdfdffffeffe0000ull,0xf9ffffffeffe0000ull,0xf7ffffffeffe0000ull,0xefffffffeffe0000ull,0xdfffffffeffe0000ull,0xbfffffffeffe0000ull,0x7fffffffeffe0000ull}, - {0xfefefefcd8f80000ull,0xfefefefcd8f00000ull,0xfefefefcd8f00000ull,0xfefefefcd8f00000ull,0xffffffffdef00000ull,0xffffffffdefc0000ull,0xffffffffde7c0000ull,0xffffffffdefc0000ull,0xfcfcfcf8d8f80000ull,0xfcfcfcf8d0f00000ull,0xfcfcfcf8d0f00000ull,0xfcfcfcf8d0e00000ull,0xffffffffd0c00000ull,0xffffffffde000000ull,0xffffffff5e1c0000ull,0xffffffffde3c0000ull,0xf8f8f8f8d8f80000ull,0xf8f8f0f0d0f00000ull,0xf8f8f0f0d0f00000ull,0xf8f8f0f0c0e00000ull,0xf9f9fdffd6ec0000ull,0xf9f9f9fc8cd80000ull,0xf8f8f0f8d8b00000ull,0xffffffff9e3c0000ull,0xf8f8f8f8d8f80000ull,0xf0f0f0f0d0f00000ull,0xf0f0f0f0d0f00000ull,0xe0e0e0e0c0e00000ull,0xf9f9fdf7ced00000ull,0x0ull,0xf0f0f0f898b00000ull,0xbfbfbfbf1ebc0000ull,0xf9f9f9f8d8f80000ull,0xf1f1f1f1d0f80000ull,0xf1f1f1f1d0f80000ull,0xe1e1e1f1d4f80000ull,0xf9f9f5efd4f80000ull,0xf1f1f9dd94f80000ull,0xf1f1f1b994f80000ull,0xbfbfbf7fdefc0000ull,0xf9f9f8f9dcfc0000ull,0xf1f1f1f9dcfc0000ull,0xf1f1f1f9dcfc0000ull,0xe1e1f1fddefc0000ull,0xffffefffdefc0000ull,0x8181dfffdefc0000ull,0xffffbfffdefc0000ull,0xbfbf7fffdefc0000ull,0xfff8f9fddefc0000ull,0xf9f1f9fddefc0000ull,0xf1f1f9fddefc0000ull,0xf1f1fdffdefc0000ull,0xffefffffdefc0000ull,0xffdfffffdefc0000ull,0xffbfffffdefc0000ull,0xff7fffffdefc0000ull,0xf8f9fdffdefc0000ull,0xf9f9fdffdefc0000ull,0xf9f9fdffdefc0000ull,0xf1fdffffdefc0000ull,0xedffffffdefc0000ull,0xdfffffffdefc0000ull,0xbfffffffdefc0000ull,0x7fffffffdefc0000ull}, - {0xfcfcfcf8b0f00000ull,0xfcfcfcf8b0f00000ull,0xfcfcfcf8b0e00000ull,0xfcfcfcf8b0e00000ull,0xfcfcfcf8b0e00000ull,0xfffffffebce00000ull,0xfffffffebcf80000ull,0xfffffffebcf80000ull,0xf8f8f8f0b0f00000ull,0xf8f8f8f0b0f00000ull,0xf8f8f8f0a0e00000ull,0xf8f8f8f0a0e00000ull,0xf8f8f8f0a0c00000ull,0xfffffffea0800000ull,0xfffffffebc000000ull,0xfffffffebc380000ull,0xf0f0f0f0b0f00000ull,0xf0f0f0f0b0f00000ull,0xf0f0e0e0a0e00000ull,0xf0f0e0e0a0e00000ull,0xf0f0e0e080c00000ull,0xf1f1f9fcbcd80000ull,0xf0f0f0f898b00000ull,0xf0f0f0f0b0700000ull,0xf0f0f0f0b0f00000ull,0xf0f0f0f0b0f00000ull,0xe0e0e0e0a0e00000ull,0xe0e0e0e0a0e00000ull,0xc0c0c0c080c00000ull,0xf1f1f9fc9ca00000ull,0x0ull,0xf0f0f0f030300000ull,0xf0f0f0f0b0f00000ull,0xf0f0f0f0b0f00000ull,0xe0e0e0e0a0f00000ull,0xe0e0e0e0a0f00000ull,0xc0c0c0e0a8f00000ull,0xf1f1f9dc90f00000ull,0xf0f0f0b810f00000ull,0xf0f0f07030f00000ull,0xf1f1f0f0b8f80000ull,0xf1f1f1f0b8f80000ull,0xe1e1e1f0b8f80000ull,0xe1e1e1f0b8f80000ull,0xc1c1e1f8bcf80000ull,0xffffdffebcf80000ull,0x8181bffebcf80000ull,0xffff7ffebcf80000ull,0xfff0f1f8bcf80000ull,0xf1f1f1f8bcf80000ull,0xe1e1f1f8bcf80000ull,0xe1e1f1f8bcf80000ull,0xf1e1f9fcbcf80000ull,0xffdffffebcf80000ull,0xffbffffebcf80000ull,0xff7ffffebcf80000ull,0xf0f1f9fcbcf80000ull,0xf1f1f9fcbcf80000ull,0xf1f1f9fcbcf80000ull,0xf1f1f9fcbcf80000ull,0xe1f9fdfebcf80000ull,0xd9fffffebcf80000ull,0xbffffffebcf80000ull,0x7ffffffebcf80000ull}, - {0xf8f8f8f070f00000ull,0xf8f8f8f060e00000ull,0xf8f8f8f060e00000ull,0xf8f8f8f060c00000ull,0xf8f8f8f060c00000ull,0xf8f8f8f060c00000ull,0xfefefefc78c00000ull,0xfefefefc78f00000ull,0xf0f0f0f070f00000ull,0xf0f0f0e060e00000ull,0xf0f0f0e060e00000ull,0xf0f0f0e040c00000ull,0xf0f0f0e040c00000ull,0xf0f0f0e040800000ull,0xfefefefc40000000ull,0xfefefefc78000000ull,0xf0f0f0f070f00000ull,0xe0e0e0e060e00000ull,0xe0e0e0e060e00000ull,0xe0e0c0c040c00000ull,0xe0e0c0c040c00000ull,0xe0e0c0c000800000ull,0xe0f0f0f878b00000ull,0xe0e0e0f030600000ull,0xf0f0f0f070f00000ull,0xe0e0e0e060e00000ull,0xe0e0e0e060e00000ull,0xc0c0c0c040c00000ull,0xc0c0c0c040c00000ull,0x8080808000800000ull,0xf0f0f0f838100000ull,0x0ull,0xf0f0f0f070f00000ull,0xe0e0e0e060e00000ull,0xe0e0e0e060e00000ull,0xc0c0c0c040e00000ull,0xc0c0c0c040e00000ull,0x808080c050e00000ull,0xe0f0f0b830f00000ull,0xe0e0e07030f00000ull,0xf0f0f0f070f00000ull,0xe0e0e0e070f00000ull,0xe0e0e0e070f00000ull,0xc0c0c0e070f00000ull,0xc0c0c0e070f00000ull,0x8080c0f078f00000ull,0xfefebefc78f00000ull,0x80807efc78f00000ull,0xfef0f0f078f00000ull,0xe0e0e0f078f00000ull,0xe0e0e0f078f00000ull,0xc0c0e0f078f00000ull,0xc0c0e0f078f00000ull,0xf0c0f0f878f00000ull,0xfebefefc78f00000ull,0xfe7efefc78f00000ull,0xe0f0f0f878f00000ull,0xe0e0f0f878f00000ull,0xe0e0f0f878f00000ull,0xe0e0f0f878f00000ull,0xe0e0f0f878f00000ull,0xd0f0f8fc78f00000ull,0xb0fefefc78f00000ull,0x7efefefc78f00000ull}, - {0x7f7f7f3e1f000000ull,0x7f7f7f3e07000000ull,0x1f1f1f0e07000000ull,0x1f1f1f0e07000000ull,0x1f1f1f0e07000000ull,0x1f1f1f0e07000000ull,0x1f1f1f0e07000000ull,0x1f1f1f0e0f000000ull,0x7f7f7f3e1f000000ull,0x7f7f7f3e03000000ull,0xf0f0f0603000000ull,0xf0f0f0603000000ull,0xf0f0f0603000000ull,0xf0f0f0607000000ull,0xf0f0f0607000000ull,0xf0f0f0e0f000000ull,0x7f7f7f3e00000000ull,0x7f7f7f0200000000ull,0x707070201000000ull,0x707070203000000ull,0x707070203000000ull,0x707070607000000ull,0x707070607000000ull,0xf0f0f0e0f000000ull,0xf3f3f1c0e000000ull,0x7f7f7f3e1d000000ull,0x303030001000000ull,0x303030203000000ull,0x303030203000000ull,0x707070607000000ull,0x707070607000000ull,0xf0f0f0e0f000000ull,0x0ull,0x7f7f7f3c08000000ull,0x101010001000000ull,0x303030203000000ull,0x303030203000000ull,0x707070607000000ull,0x707070607000000ull,0xf0f0f0e0f000000ull,0xf3f3e0e0f000000ull,0x7f7f7d0e0f000000ull,0x101030a17000000ull,0x303030207000000ull,0x303030207000000ull,0x707070607000000ull,0x707070607000000ull,0xf0f0f0e0f000000ull,0x7f7e7f3e1f000000ull,0x7f7d7f3e1f000000ull,0xf030f1e1f000000ull,0x303070e1f000000ull,0x303070e1f000000ull,0x707070e1f000000ull,0x707070e1f000000ull,0x7f0f0f0e1f000000ull,0x7e7f7f3e1f000000ull,0xd7f7f3e1f000000ull,0xb0f1f3e1f000000ull,0x7070f1e1f000000ull,0x7070f1e1f000000ull,0x7070f1e1f000000ull,0x7070f1e1f000000ull,0x70f0f1e1f000000ull}, - {0xffffff7d3f000000ull,0xffffff7d3f000000ull,0xffffff7d0f000000ull,0x3f3f3f1d0f000000ull,0x3f3f3f1d0f000000ull,0x3f3f3f1d0f000000ull,0x3f3f3f1d0f000000ull,0x3f3f3f1d0f000000ull,0xffffff7d3f000000ull,0xffffff7d3f000000ull,0xffffff7d07000000ull,0x1f1f1f0d07000000ull,0x1f1f1f0d07000000ull,0x1f1f1f0d07000000ull,0x1f1f1f0d0f000000ull,0x1f1f1f0d0f000000ull,0xffffff7d3c000000ull,0xffffff7d00000000ull,0xffffff0501000000ull,0xf0f0f0503000000ull,0xf0f0f0507000000ull,0xf0f0f0507000000ull,0xf0f0f0d0f000000ull,0xf0f0f0d0f000000ull,0xf3f3f1d0e000000ull,0x7f7f7f391d000000ull,0xffffff7d3b000000ull,0x707070103000000ull,0x707070507000000ull,0x707070507000000ull,0xf0f0f0d0f000000ull,0xf0f0f0d0f000000ull,0xf3f3f1c0c000000ull,0x0ull,0xffffff7905000000ull,0x303030103000000ull,0x707070507000000ull,0x707070507000000ull,0xf0f0f0d0f000000ull,0xf0f0f0d0f000000ull,0x8fbfbe0c0f000000ull,0xfffffd0c0f000000ull,0xfffffb0d0f000000ull,0x838387152f000000ull,0x878787050f000000ull,0x878787050f000000ull,0x8f8f8f0d0f000000ull,0x8f8f0f0d0f000000ull,0xfffeff7d3f000000ull,0xfffdff7d3f000000ull,0xfffbff7d3f000000ull,0x8f879f3d3f000000ull,0x87878f1d3f000000ull,0x87878f1d3f000000ull,0x8f8f8f1d3f000000ull,0xff0f8f1d3f000000ull,0xfeffff7d3f000000ull,0xfdffff7d3f000000ull,0x9bffff7d3f000000ull,0x879fbf7d3f000000ull,0x8f8f9f3d3f000000ull,0x8f8f9f3d3f000000ull,0x8f8f9f3d3f000000ull,0xf8f9f3d3f000000ull}, - {0xfffffffb7f000000ull,0xfffffffb7f000000ull,0xfffffffb7f000000ull,0xfffffffb1f000000ull,0x7f7f7f3b1f000000ull,0x7f7f7f3b1f000000ull,0x7f7f7f3b1f000000ull,0x7f7f7f3b1f000000ull,0xfffffffb7e000000ull,0xfffffffb7e000000ull,0xfffffffb7f000000ull,0xfffffffb0f000000ull,0x3f3f3f1b0f000000ull,0x3f3f3f1b0f000000ull,0x3f3f3f1b0f000000ull,0x3f3f3f1b1f000000ull,0xfffffffb7c000000ull,0xfffffffa78000000ull,0xfffffffb00000000ull,0xffffff0b03000000ull,0x1f1f1f0b07000000ull,0x1f1f1f0b0f000000ull,0x1f1f1f0b0f000000ull,0x1f1f1f1b1f000000ull,0xfffffff97c000000ull,0x7f7f7f3b1d000000ull,0xffffff713b000000ull,0xffffffeb77000000ull,0xf0f0f0307000000ull,0xf0f0f0b0f000000ull,0xf0f0f0b0f000000ull,0x1f1f1f1b1f000000ull,0xfdfdfdf87d000000ull,0x7f7f7f390d000000ull,0x0ull,0xfdfdeff30b000000ull,0x707070307000000ull,0xf0f0f0b0f000000ull,0xf0f0f0b0f000000ull,0x1f1f1f1b1f000000ull,0xfdfdfefb7f000000ull,0xfffffda95f000000ull,0xfffffba95f000000ull,0xffeff7ab5f000000ull,0x87878fab5f000000ull,0x8f8f8f8b1f000000ull,0x8f8f8f8b1f000000ull,0x9f9f1f9b1f000000ull,0xfffefffb7f000000ull,0xfffdfffb7f000000ull,0xfffbfffb7f000000ull,0xfff7fffb7f000000ull,0x8f8fbffb7f000000ull,0x8f8f9fbb7f000000ull,0x9f8f9fbb7f000000ull,0xff1f9fbb7f000000ull,0xfefffffb7f000000ull,0xfdfffffb7f000000ull,0xfbfffffb7f000000ull,0xb7fffffb7f000000ull,0x8fbffffb7f000000ull,0x9f9fbffb7f000000ull,0x9f9fbffb7f000000ull,0x1f9fbffb7f000000ull}, - {0xfffffff7fe000000ull,0xfffffff7fe000000ull,0xfffffff7fe000000ull,0xfffffff7ff000000ull,0xfffffff73f000000ull,0xffffff773f000000ull,0xffffff773f000000ull,0xffffff773f000000ull,0xfffffff7fc000000ull,0xfffffff6fc000000ull,0xfffffff7fc000000ull,0xfffffff7ff000000ull,0xfffffff71f000000ull,0x7f7f7f371f000000ull,0x7f7f7f371f000000ull,0x7f7f7f371f000000ull,0xfffffff5fc000000ull,0xfefefef4f8000000ull,0xfffffff4f0000000ull,0xfffffff700000000ull,0xffffff1707000000ull,0x3f3f3f170f000000ull,0x3f3f3f171f000000ull,0x3f3f3f171f000000ull,0xfdfdfdf5fc000000ull,0xfcfcfcf0f8000000ull,0xffffff753b000000ull,0xfdfdffe377000000ull,0xfdfdfdd7ef000000ull,0x1f1f1f070f000000ull,0x1f1f1f171f000000ull,0x1f1f1f171f000000ull,0xfdfdfdf4fd000000ull,0xf8f8f8f0f8000000ull,0xfffffd7319000000ull,0x0ull,0xf9f9dde704000000ull,0xf0f0f070f000000ull,0x1f1f1f171f000000ull,0x1f1f1f171f000000ull,0xfdfdfcf5ff000000ull,0xf9f9fdf5ff000000ull,0xfffdfbd5bf000000ull,0xfdfdf7d5bf000000ull,0xfdddefd5bf000000ull,0x8f8f9fd7bf000000ull,0x9f9f9f97bf000000ull,0x9f9f1f97bf000000ull,0xfffcfff7ff000000ull,0xfdfdfff7ff000000ull,0xfffbfff7ff000000ull,0xfff7fff7ff000000ull,0xffeffff7ff000000ull,0x9f9ffff7ff000000ull,0x9f9fbff7ff000000ull,0xff1fbff7ff000000ull,0xfefffff7ff000000ull,0xfdfffff7ff000000ull,0xfbfffff7ff000000ull,0xf7fffff7ff000000ull,0xeffffff7ff000000ull,0x9ffffff7ff000000ull,0xbfbffff7ff000000ull,0x3fbffff7ff000000ull}, - {0xffffffeefc000000ull,0xffffffeefc000000ull,0xffffffeefc000000ull,0xffffffeffc000000ull,0xffffffefff000000ull,0xffffffef7f000000ull,0xffffffef7f000000ull,0xffffffef7f000000ull,0xfefefeecf8000000ull,0xfefefeecf8000000ull,0xfefefeecf8000000ull,0xffffffeff8000000ull,0xffffffefff000000ull,0xffffffef3f000000ull,0xffffff6f3f000000ull,0xffffffef3f000000ull,0xfcfcfce8f8000000ull,0xfcfcfce8f8000000ull,0xfcfcfce8f0000000ull,0xffffffe8e0000000ull,0xffffffef00000000ull,0xffffff2f0f000000ull,0x7f7f7f2f1f000000ull,0xffffffaf3f000000ull,0xf8f8f8e8f8000000ull,0xf8f8f8e8f8000000ull,0xf8f8f8e0f0000000ull,0xfdfdffebf7000000ull,0xf9f9fdc7ee000000ull,0xf9f9f9acdc000000ull,0x3f3f3f0f1f000000ull,0xbfbfbfaf3f000000ull,0xf8f8f8e8f8000000ull,0xf8f8f8e8f8000000ull,0xf0f0f0e0f0000000ull,0xfdfdfbe720000000ull,0x0ull,0xf1f1b9cc98000000ull,0x1f1f1f0f1f000000ull,0xbfbfbf2fbf000000ull,0xf9f9f8e9fd000000ull,0xf9f9f9e9fd000000ull,0xf1f1f9ebfd000000ull,0xfdf9f5abfd000000ull,0xf9f9e9abfd000000ull,0xf9b9d9abfd000000ull,0x9f9fbfafff000000ull,0xbfbf3fafff000000ull,0xfff8fdefff000000ull,0xf9f9fdefff000000ull,0xf9f9ffefff000000ull,0xfff7ffefff000000ull,0xffefffefff000000ull,0xffdfffefff000000ull,0xbfbfffefff000000ull,0xff3fffefff000000ull,0xfcfdffefff000000ull,0xfdfdffefff000000ull,0xf9ffffefff000000ull,0xf7ffffefff000000ull,0xefffffefff000000ull,0xdfffffefff000000ull,0xbfffffefff000000ull,0x7fffffefff000000ull}, - {0xfefefedcf8000000ull,0xfefefedcf8000000ull,0xfefefedcf8000000ull,0xfefefedcf8000000ull,0xffffffdff8000000ull,0xffffffdffe000000ull,0xffffffdffe000000ull,0xffffffdffe000000ull,0xfcfcfcd8f8000000ull,0xfcfcfcd8f0000000ull,0xfcfcfcd8f0000000ull,0xfcfcfcd8f0000000ull,0xffffffdff0000000ull,0xffffffdffe000000ull,0xffffffdf7e000000ull,0xffffffdf7e000000ull,0xf8f8f8d8f8000000ull,0xf8f8f8d0f0000000ull,0xf8f8f8d0f0000000ull,0xf8f8f8d0e0000000ull,0xffffffd0c0000000ull,0xffffffdf00000000ull,0xffffff5f1e000000ull,0xffffffdf3e000000ull,0xf8f8f8d8f8000000ull,0xf0f0f0d0f0000000ull,0xf0f0f0d0f0000000ull,0xf0f0f0c0e0000000ull,0xf9f9fdd7ee000000ull,0xf1f1f98cdc000000ull,0xf0f0f0d8b8000000ull,0xffffff9f3e000000ull,0xf8f8f8d8f8000000ull,0xf0f0f0d0f0000000ull,0xf0f0f0d0f0000000ull,0xe0e0e0c0e0000000ull,0xf9f9f5cfd0000000ull,0x0ull,0xf0f0f098b0000000ull,0xbfbfbf1fbe000000ull,0xf9f9f8d9f8000000ull,0xf1f1f1d1f8000000ull,0xf1f1f1d1f8000000ull,0xe1e1f1d5fa000000ull,0xf9f1e9d5fa000000ull,0xf1f1d195fa000000ull,0xf1f1b195fa000000ull,0xbfbf7fdffe000000ull,0xfff8f9ddfe000000ull,0xf9f1f9ddfe000000ull,0xf1f1f9ddfe000000ull,0xf1f1fddffe000000ull,0xffefffdffe000000ull,0xffdfffdffe000000ull,0xffbfffdffe000000ull,0xff7fffdffe000000ull,0xf8f9fddffe000000ull,0xf9f9fddffe000000ull,0xf9f9fddffe000000ull,0xf1fdffdffe000000ull,0xedffffdffe000000ull,0xdfffffdffe000000ull,0xbfffffdffe000000ull,0x7fffffdffe000000ull}, - {0xfcfcfcb8f0000000ull,0xfcfcfcb8f0000000ull,0xfcfcfcb8f0000000ull,0xfcfcfcb8f0000000ull,0xfcfcfcb8f0000000ull,0xffffffbef0000000ull,0xffffffbefc000000ull,0xffffffbefc000000ull,0xf8f8f8b0f0000000ull,0xf8f8f8b0f0000000ull,0xf8f8f8b0e0000000ull,0xf8f8f8b0e0000000ull,0xf8f8f8b0e0000000ull,0xffffffbee0000000ull,0xffffffbefc000000ull,0xffffffbefc000000ull,0xf0f0f0b0f0000000ull,0xf0f0f0b0f0000000ull,0xf0f0f0a0e0000000ull,0xf0f0f0a0e0000000ull,0xf0f0f0a0c0000000ull,0xffffffa080000000ull,0xffffffbe00000000ull,0xffffffbe3c000000ull,0xf0f0f0b0f0000000ull,0xf0f0f0b0f0000000ull,0xe0e0e0a0e0000000ull,0xe0e0e0a0e0000000ull,0xe0e0e080c0000000ull,0xf1f1f9bcdc000000ull,0xf0f0f098b8000000ull,0xf0f0f0b070000000ull,0xf0f0f0b0f0000000ull,0xf0f0f0b0f0000000ull,0xe0e0e0a0e0000000ull,0xe0e0e0a0e0000000ull,0xc0c0c080c0000000ull,0xf1f1f99ca0000000ull,0x0ull,0xf0f0f03030000000ull,0xf1f1f0b0f0000000ull,0xf1f1f1b0f0000000ull,0xe1e1e1a0f0000000ull,0xe1e1e1a0f0000000ull,0xc1c1e1a8f4000000ull,0xf1f1d1b0f0000000ull,0xf1f1b130f0000000ull,0xf1f17130f0000000ull,0xfff0f1b8fc000000ull,0xf1f1f1b8fc000000ull,0xe1e1f1b8fc000000ull,0xe1e1f1b8fc000000ull,0xf1e1f9bcfc000000ull,0xffdfffbefc000000ull,0xffbfffbefc000000ull,0xff7fffbefc000000ull,0xf0f1f9bcfc000000ull,0xf1f1f9bcfc000000ull,0xf1f1f9bcfc000000ull,0xf1f1f9bcfc000000ull,0xe1f9fdbefc000000ull,0xd9ffffbefc000000ull,0xbfffffbefc000000ull,0x7fffffbefc000000ull}, - {0xf8f8f870f0000000ull,0xf8f8f870e0000000ull,0xf8f8f870e0000000ull,0xf8f8f870e0000000ull,0xf8f8f870e0000000ull,0xf8f8f870e0000000ull,0xfefefe7ce0000000ull,0xfefefe7cf8000000ull,0xf0f0f070f0000000ull,0xf0f0f060e0000000ull,0xf0f0f060e0000000ull,0xf0f0f060c0000000ull,0xf0f0f060c0000000ull,0xf0f0f060c0000000ull,0xfefefe7cc0000000ull,0xfefefe7cf8000000ull,0xf0f0f070f0000000ull,0xe0e0e060e0000000ull,0xe0e0e060e0000000ull,0xe0e0e040c0000000ull,0xe0e0e040c0000000ull,0xe0e0e04080000000ull,0xfefefe4000000000ull,0xfefefe7c00000000ull,0xf0f0f070f0000000ull,0xe0e0e060e0000000ull,0xe0e0e060e0000000ull,0xc0c0c040c0000000ull,0xc0c0c040c0000000ull,0xc0c0c00080000000ull,0xe0f0f078b8000000ull,0xe0e0e03070000000ull,0xf0f0f070f0000000ull,0xe0e0e060e0000000ull,0xe0e0e060e0000000ull,0xc0c0c040c0000000ull,0xc0c0c040c0000000ull,0x8080800080000000ull,0xf0f0f03810000000ull,0x0ull,0xf0f0f070f0000000ull,0xe0e0e060e0000000ull,0xe0e0e060e0000000ull,0xc0c0c040e0000000ull,0xc0c0c040e0000000ull,0x8080c050e8000000ull,0xe0f0b070f0000000ull,0xe0e06070f0000000ull,0xfef0f070f8000000ull,0xe0e0e070f8000000ull,0xe0e0e070f8000000ull,0xc0c0e070f8000000ull,0xc0c0e070f8000000ull,0xf0c0f078f8000000ull,0xfebefe7cf8000000ull,0xfe7efe7cf8000000ull,0xe0f0f078f8000000ull,0xe0e0f078f8000000ull,0xe0e0f078f8000000ull,0xe0e0f078f8000000ull,0xe0e0f078f8000000ull,0xd0f0f87cf8000000ull,0xb0fefe7cf8000000ull,0x7efefe7cf8000000ull}, - {0x7f7f7e3f00000000ull,0x7f7f7e3f00000000ull,0x1f1f1e0f00000000ull,0x1f1f1e0f00000000ull,0x1f1f1e0f00000000ull,0x1f1f1e0f00000000ull,0x1f1f1e0f00000000ull,0x1f1f1e0f00000000ull,0x7f7f7e3f00000000ull,0x7f7f7e0700000000ull,0xf0f0e0700000000ull,0xf0f0e0700000000ull,0xf0f0e0700000000ull,0xf0f0e0700000000ull,0xf0f0e0700000000ull,0xf0f0e0f00000000ull,0x7f7f7e3f00000000ull,0x7f7f7e0300000000ull,0x707060300000000ull,0x707060300000000ull,0x707060300000000ull,0x707060700000000ull,0x707060700000000ull,0xf0f0e0f00000000ull,0x3037e0000000000ull,0x303020000000000ull,0x303020100000000ull,0x303020300000000ull,0x303020300000000ull,0x707060700000000ull,0x707060700000000ull,0xf0f0e0f00000000ull,0xf3f3c1e00000000ull,0x7f7f7e3d00000000ull,0x303000100000000ull,0x303020300000000ull,0x303020300000000ull,0x707060700000000ull,0x707060700000000ull,0xf0f0e0f00000000ull,0x0ull,0x7f7f7c0800000000ull,0x101000100000000ull,0x303020300000000ull,0x303020300000000ull,0x707060700000000ull,0x707060700000000ull,0xf0f0e0f00000000ull,0xf060e0f00000000ull,0x7050e0f00000000ull,0x7030a1700000000ull,0x303020700000000ull,0x303020700000000ull,0x707060700000000ull,0x707060700000000ull,0x7f0f0e0f00000000ull,0x7e7f7e3f00000000ull,0xd7f7e3f00000000ull,0xb0f1e3f00000000ull,0x7070e1f00000000ull,0x7070e1f00000000ull,0x7070e1f00000000ull,0x7070e1f00000000ull,0x70f0e1f00000000ull}, - {0xfffffd7f00000000ull,0xfffffd7f00000000ull,0xfffffd7f00000000ull,0x3f3f3d1f00000000ull,0x3f3f3d1f00000000ull,0x3f3f3d1f00000000ull,0x3f3f3d1f00000000ull,0x3f3f3d1f00000000ull,0xfffffd7f00000000ull,0xfffffd7f00000000ull,0xfffffd0f00000000ull,0x1f1f1d0f00000000ull,0x1f1f1d0f00000000ull,0x1f1f1d0f00000000ull,0x1f1f1d0f00000000ull,0x1f1f1d0f00000000ull,0xfffffd7f00000000ull,0xfffffd7f00000000ull,0xfffffd0700000000ull,0xf0f0d0700000000ull,0xf0f0d0700000000ull,0xf0f0d0700000000ull,0xf0f0d0f00000000ull,0xf0f0d0f00000000ull,0xfffffd7c00000000ull,0x707fd0000000000ull,0x707050100000000ull,0x707050300000000ull,0x707050700000000ull,0x707050700000000ull,0xf0f0d0f00000000ull,0xf0f0d0f00000000ull,0xf3f3d1e00000000ull,0x7f7f793d00000000ull,0xfffffd7b00000000ull,0x707010300000000ull,0x707050700000000ull,0x707050700000000ull,0xf0f0d0f00000000ull,0xf0f0d0f00000000ull,0xf3f3c0c00000000ull,0x0ull,0xfffff90d00000000ull,0x303010300000000ull,0x707050700000000ull,0x707050700000000ull,0xf0f0d0f00000000ull,0xf0f0d0f00000000ull,0x8f8e8d0f00000000ull,0x8f8d8d0f00000000ull,0x8f8b8d0f00000000ull,0x8f87952f00000000ull,0x8787850f00000000ull,0x8787850f00000000ull,0x8f8f8d0f00000000ull,0xff0f8d0f00000000ull,0xfefffd7f00000000ull,0xfdfffd7f00000000ull,0x9bfffd7f00000000ull,0x879fbd7f00000000ull,0x8f8f9d3f00000000ull,0x8f8f9d3f00000000ull,0x8f8f9d3f00000000ull,0xf8f9d3f00000000ull}, - {0xfdfffbff00000000ull,0xfdfffbff00000000ull,0xfdfffbff00000000ull,0xfdfffbff00000000ull,0x7d7f7b3f00000000ull,0x7d7f7b3f00000000ull,0x7d7f7b3f00000000ull,0x7d7f7b3f00000000ull,0xfdfffbff00000000ull,0xfdfffbff00000000ull,0xfdfffbff00000000ull,0xfdfffb1f00000000ull,0x3d3f3b1f00000000ull,0x3d3f3b1f00000000ull,0x3d3f3b1f00000000ull,0x3d3f3b1f00000000ull,0xfdfffbfe00000000ull,0xfdfffbfe00000000ull,0xfdfffbff00000000ull,0xfdfffb0f00000000ull,0x1d1f1b0f00000000ull,0x1d1f1b0f00000000ull,0x1d1f1b0f00000000ull,0x1d1f1b1f00000000ull,0xfdfffbfc00000000ull,0xfcfefaf800000000ull,0xc0efb0000000000ull,0xd0f0b0300000000ull,0xd0f0b0700000000ull,0xd0f0b0f00000000ull,0xd0f0b0f00000000ull,0x1d1f1b1f00000000ull,0xfdfff9fc00000000ull,0x7f7f7b3d00000000ull,0xfffff17b00000000ull,0xfdffebf700000000ull,0xd0f030700000000ull,0xd0f0b0f00000000ull,0xd0f0b0f00000000ull,0x1d1f1b1f00000000ull,0xfdfdf8fd00000000ull,0x7f7f790d00000000ull,0x0ull,0xfdeff30b00000000ull,0x507030700000000ull,0xd0f0b0f00000000ull,0xd0f0b0f00000000ull,0x1d1f1b1f00000000ull,0xfffefbff00000000ull,0x8f8dabdf00000000ull,0x8f8babdf00000000ull,0x8f87abdf00000000ull,0x8f8fabdf00000000ull,0x8f8f8b9f00000000ull,0x9f8f8b9f00000000ull,0xff1f9b9f00000000ull,0xfefffbff00000000ull,0xfdfffbff00000000ull,0xfbfffbff00000000ull,0xb7fffbff00000000ull,0x8fbffbff00000000ull,0x9f9fbbff00000000ull,0x9f9fbbff00000000ull,0x1f9fbbff00000000ull}, - {0xebfff7ff00000000ull,0xebfff7ff00000000ull,0xebfff7ff00000000ull,0xebfff7ff00000000ull,0xebfff7ff00000000ull,0xebfff77f00000000ull,0xebfff77f00000000ull,0xebfff77f00000000ull,0xebfff7fe00000000ull,0xebfff7fe00000000ull,0xebfff7fe00000000ull,0xebfff7ff00000000ull,0xebfff73f00000000ull,0x6b7f773f00000000ull,0x6b7f773f00000000ull,0x6b7f773f00000000ull,0xebfff7fc00000000ull,0xeafef6fc00000000ull,0xebfff7fc00000000ull,0xebfff7ff00000000ull,0xebfff71f00000000ull,0x2b3f371f00000000ull,0x2b3f371f00000000ull,0x2b3f371f00000000ull,0xe9fdf5fc00000000ull,0xe8fcf4f800000000ull,0xe8fcf4f000000000ull,0x81cf70000000000ull,0xb1f170700000000ull,0xb1f170f00000000ull,0xb1f171f00000000ull,0xb1f171f00000000ull,0xe9fdf5fc00000000ull,0xe8fcf0f800000000ull,0xfffff57b00000000ull,0xfdfde3f700000000ull,0xf9fdd5ef00000000ull,0xb1f070f00000000ull,0xb1f171f00000000ull,0xb1f171f00000000ull,0xedfdf4fd00000000ull,0xe8f8f0f800000000ull,0xfffdf31900000000ull,0x0ull,0xf9dde50400000000ull,0xb0f070f00000000ull,0x1b1f171f00000000ull,0x1b1f171f00000000ull,0xfffcf5ff00000000ull,0xfdfdf5ff00000000ull,0x9f9bd5bf00000000ull,0x9f97d5bf00000000ull,0x9f8fd5bf00000000ull,0x9f9fd7bf00000000ull,0x9f9f97bf00000000ull,0xff1f97bf00000000ull,0xfefff7ff00000000ull,0xfdfff7ff00000000ull,0xfbfff7ff00000000ull,0xf7fff7ff00000000ull,0xeffff7ff00000000ull,0x9ffff7ff00000000ull,0xbfbff7ff00000000ull,0x3fbff7ff00000000ull}, - {0xd7ffeffe00000000ull,0xd7ffeffe00000000ull,0xd7ffeffe00000000ull,0xd7ffefff00000000ull,0xd7ffefff00000000ull,0xd7ffefff00000000ull,0xd7ffefff00000000ull,0xd7ffefff00000000ull,0xd6feeefc00000000ull,0xd6feeefc00000000ull,0xd6feeefc00000000ull,0xd7ffeffc00000000ull,0xd7ffefff00000000ull,0xd7ffef7f00000000ull,0xd7ffef7f00000000ull,0xd7ffef7f00000000ull,0xd4fcecf800000000ull,0xd4fcecf800000000ull,0xd4fcecf800000000ull,0xd7ffeff800000000ull,0xd7ffefff00000000ull,0xd7ffef3f00000000ull,0x577f6f3f00000000ull,0xd7ffef3f00000000ull,0xd0f8e8f800000000ull,0xd0f8e8f800000000ull,0xd0f8e8f000000000ull,0xd0f8e8e000000000ull,0x1038ef0000000000ull,0x173f2f0f00000000ull,0x173f2f1f00000000ull,0x97bfaf3f00000000ull,0xd0f8e8f800000000ull,0xd0f8e8f800000000ull,0xd0f8e0f000000000ull,0xfdfdebf700000000ull,0xf9f9c5ef00000000ull,0xf1f9a9dc00000000ull,0x173f0f1f00000000ull,0x97bfaf3f00000000ull,0xd8f8e8f800000000ull,0xd8f8e8f800000000ull,0xd0f0e0f000000000ull,0xfdf9e52000000000ull,0x0ull,0xf1b9c99800000000ull,0x171f0f1f00000000ull,0xb7bf2fbf00000000ull,0xfff8e9fd00000000ull,0xf9f9e9fd00000000ull,0xf9f9ebfd00000000ull,0xf9f1abfd00000000ull,0xf9e9abfd00000000ull,0xf9d9abfd00000000ull,0xbfbfafff00000000ull,0xff3fafff00000000ull,0xfcfdefff00000000ull,0xfdfdefff00000000ull,0xf9ffefff00000000ull,0xf7ffefff00000000ull,0xefffefff00000000ull,0xdfffefff00000000ull,0xbfffefff00000000ull,0x7fffefff00000000ull}, - {0xbefedefc00000000ull,0xbefedefc00000000ull,0xbefedefc00000000ull,0xbefedefc00000000ull,0xbfffdfff00000000ull,0xbfffdfff00000000ull,0xbfffdfff00000000ull,0xbfffdfff00000000ull,0xbcfcdcf800000000ull,0xbcfcdcf800000000ull,0xbcfcdcf800000000ull,0xbcfcdcf800000000ull,0xbfffdff800000000ull,0xbfffdfff00000000ull,0xbfffdfff00000000ull,0xbfffdfff00000000ull,0xb8f8d8f800000000ull,0xb8f8d8f000000000ull,0xb8f8d8f000000000ull,0xb8f8d8f000000000ull,0xbfffdff000000000ull,0xbfffdfff00000000ull,0xbfffdf7f00000000ull,0xbfffdf7f00000000ull,0xb8f8d8f800000000ull,0xb0f0d0f000000000ull,0xb0f0d0f000000000ull,0xb0f0d0e000000000ull,0xb0f0d0c000000000ull,0x3070df0000000000ull,0x3f7f5f1f00000000ull,0xbfffdf3f00000000ull,0xb8f8d8f800000000ull,0xb0f0d0f000000000ull,0xb0f0d0f000000000ull,0xb0f0c0e000000000ull,0xf9f9d5ef00000000ull,0xf1f189dc00000000ull,0xf0f0d0b800000000ull,0xbfff9f3f00000000ull,0xb8f8d8f800000000ull,0xb0f0d0f000000000ull,0xb0f0d0f000000000ull,0xa0e0c0e000000000ull,0xf9f1c9d000000000ull,0x0ull,0xf0f090b000000000ull,0xbfbf1fbf00000000ull,0xfff8d9f900000000ull,0xf9f1d1f900000000ull,0xf1f1d1f900000000ull,0xf1f1d5fb00000000ull,0xf1e1d5fb00000000ull,0xf1d1d5fb00000000ull,0xf1b1d5fb00000000ull,0xff7fdfff00000000ull,0xf8f9ddff00000000ull,0xf9f9ddff00000000ull,0xf9f9ddff00000000ull,0xf1fddfff00000000ull,0xedffdfff00000000ull,0xdfffdfff00000000ull,0xbfffdfff00000000ull,0x7fffdfff00000000ull}, - {0xfcfcbcf800000000ull,0xfcfcbcf800000000ull,0xfcfcbcf800000000ull,0xfcfcbcf800000000ull,0xfcfcbcf800000000ull,0xffffbffe00000000ull,0xffffbffe00000000ull,0xffffbffe00000000ull,0xf8f8b8f000000000ull,0xf8f8b8f000000000ull,0xf8f8b8f000000000ull,0xf8f8b8f000000000ull,0xf8f8b8f000000000ull,0xffffbff000000000ull,0xffffbffe00000000ull,0xffffbffe00000000ull,0xf0f0b0f000000000ull,0xf0f0b0f000000000ull,0xf0f0b0e000000000ull,0xf0f0b0e000000000ull,0xf0f0b0e000000000ull,0xffffbfe000000000ull,0xffffbffe00000000ull,0xffffbffe00000000ull,0xf0f0b0f000000000ull,0xf0f0b0f000000000ull,0xe0e0a0e000000000ull,0xe0e0a0e000000000ull,0xe0e0a0c000000000ull,0xe0e0a08000000000ull,0xe0e0bf0000000000ull,0xffffbf3e00000000ull,0xf0f0b0f000000000ull,0xf0f0b0f000000000ull,0xe0e0a0e000000000ull,0xe0e0a0e000000000ull,0xe0e080c000000000ull,0xf1f1b9dc00000000ull,0xf0f090b800000000ull,0xf0f0b07000000000ull,0xf0f0b0f000000000ull,0xf0f0b0f000000000ull,0xe0e0a0e000000000ull,0xe0e0a0e000000000ull,0xc0c080c000000000ull,0xf1f191b000000000ull,0x0ull,0xf0f0303000000000ull,0xfff0b1f000000000ull,0xf1f1b1f000000000ull,0xe1e1a1f000000000ull,0xe1e1a1f000000000ull,0xf1e1a9f400000000ull,0xf1d1b1f000000000ull,0xf1b1b1f000000000ull,0xf171b1f000000000ull,0xf0f1b9fc00000000ull,0xf1f1b9fc00000000ull,0xf1f1b9fc00000000ull,0xf1f1b9fc00000000ull,0xe1f9bdfe00000000ull,0xd9ffbffe00000000ull,0xbfffbffe00000000ull,0x7fffbffe00000000ull}, - {0xf8f878f000000000ull,0xf8f878f000000000ull,0xf8f878f000000000ull,0xf8f878f000000000ull,0xf8f878f000000000ull,0xf8f878f000000000ull,0xfefe7efc00000000ull,0xfefe7efc00000000ull,0xf0f070f000000000ull,0xf0f070e000000000ull,0xf0f070e000000000ull,0xf0f070e000000000ull,0xf0f070e000000000ull,0xf0f070e000000000ull,0xfefe7ee000000000ull,0xfefe7efc00000000ull,0xf0f070f000000000ull,0xe0e060e000000000ull,0xe0e060e000000000ull,0xe0e060c000000000ull,0xe0e060c000000000ull,0xe0e060c000000000ull,0xfefe7ec000000000ull,0xfefe7efc00000000ull,0xf0f070f000000000ull,0xe0e060e000000000ull,0xe0e060e000000000ull,0xc0c040c000000000ull,0xc0c040c000000000ull,0xc0c0408000000000ull,0xc0c0400000000000ull,0xc0c07e0000000000ull,0xf0f070f000000000ull,0xe0e060e000000000ull,0xe0e060e000000000ull,0xc0c040c000000000ull,0xc0c040c000000000ull,0xc0c0008000000000ull,0xe0f070b800000000ull,0xe0e0207000000000ull,0xf0f070f000000000ull,0xe0e060e000000000ull,0xe0e060e000000000ull,0xc0c040c000000000ull,0xc0c040c000000000ull,0x8080008000000000ull,0xf0f0301000000000ull,0x0ull,0xfef070f000000000ull,0xe0e060e000000000ull,0xe0e060e000000000ull,0xc0c040e000000000ull,0xc0c040e000000000ull,0xe0c050e800000000ull,0xe0a070f000000000ull,0xf06070f000000000ull,0xe0f070f800000000ull,0xe0e070f800000000ull,0xe0e070f800000000ull,0xe0e070f800000000ull,0xe0e070f800000000ull,0xd0f078fc00000000ull,0xb0fe7efc00000000ull,0x7efe7efc00000000ull}, - {0x737e7f0000000000ull,0x737e7f0000000000ull,0x131e1f0000000000ull,0x131e1f0000000000ull,0x131e1f0000000000ull,0x131e1f0000000000ull,0x131e1f0000000000ull,0x131e1f0000000000ull,0x737e7f0000000000ull,0x737e7f0000000000ull,0x30e0f0000000000ull,0x30e0f0000000000ull,0x30e0f0000000000ull,0x30e0f0000000000ull,0x30e0f0000000000ull,0x30e0f0000000000ull,0x3027f0000000000ull,0x302070000000000ull,0x302070000000000ull,0x302070000000000ull,0x302070000000000ull,0x302070000000000ull,0x306070000000000ull,0x30e0f0000000000ull,0x3027f0000000000ull,0x302030000000000ull,0x302030000000000ull,0x302030000000000ull,0x302030000000000ull,0x302070000000000ull,0x306070000000000ull,0x30e0f0000000000ull,0x302000000000000ull,0x302000000000000ull,0x302010000000000ull,0x302030000000000ull,0x302030000000000ull,0x302070000000000ull,0x306070000000000ull,0x30e0f0000000000ull,0xf3c3e0000000000ull,0x7b7e7d0000000000ull,0x300010000000000ull,0x302030000000000ull,0x302030000000000ull,0x302070000000000ull,0x306070000000000ull,0x30e0f0000000000ull,0x0ull,0x80000000000ull,0x100010000000000ull,0x302030000000000ull,0x302030000000000ull,0x302070000000000ull,0x306070000000000ull,0x30e0f0000000000ull,0x30000000000ull,0x30000000000ull,0x10a170000000000ull,0x302070000000000ull,0x302070000000000ull,0x302070000000000ull,0x306070000000000ull,0x30e0f0000000000ull}, - {0xfffdff0000000000ull,0xfffdff0000000000ull,0xfffdff0000000000ull,0x3f3d3f0000000000ull,0x3f3d3f0000000000ull,0x3f3d3f0000000000ull,0x3f3d3f0000000000ull,0x3f3d3f0000000000ull,0xfffdff0000000000ull,0xfffdff0000000000ull,0xfffdff0000000000ull,0x1f1d1f0000000000ull,0x1f1d1f0000000000ull,0x1f1d1f0000000000ull,0x1f1d1f0000000000ull,0x1f1d1f0000000000ull,0xf7f5ff0000000000ull,0x705ff0000000000ull,0x7050f0000000000ull,0x7050f0000000000ull,0x7050f0000000000ull,0x7050f0000000000ull,0x7050f0000000000ull,0xf0d0f0000000000ull,0xf7f5ff0000000000ull,0x705ff0000000000ull,0x705070000000000ull,0x705070000000000ull,0x705070000000000ull,0x705070000000000ull,0x7050f0000000000ull,0xf0d0f0000000000ull,0xf7f5fc0000000000ull,0x705000000000000ull,0x705010000000000ull,0x705030000000000ull,0x705070000000000ull,0x705070000000000ull,0x7050f0000000000ull,0xf0d0f0000000000ull,0xf3d3e0000000000ull,0x7f797d0000000000ull,0xfff5fb0000000000ull,0x701030000000000ull,0x705070000000000ull,0x705070000000000ull,0x7050f0000000000ull,0xf0d0f0000000000ull,0xc040c0000000000ull,0x0ull,0x1090d0000000000ull,0x301030000000000ull,0x705070000000000ull,0x705070000000000ull,0x7050f0000000000ull,0x8f0d0f0000000000ull,0x8484870000000000ull,0x8080870000000000ull,0x9981870000000000ull,0x8395af0000000000ull,0x87858f0000000000ull,0x87858f0000000000ull,0x87858f0000000000ull,0x78d8f0000000000ull}, - {0xfffbff0000000000ull,0xfffbff0000000000ull,0xfffbff0000000000ull,0xfffbff0000000000ull,0x7f7b7f0000000000ull,0x7f7b7f0000000000ull,0x7f7b7f0000000000ull,0x7f7b7f0000000000ull,0xfffbff0000000000ull,0xfffbff0000000000ull,0xfffbff0000000000ull,0xfffbff0000000000ull,0x3f3b3f0000000000ull,0x3f3b3f0000000000ull,0x3f3b3f0000000000ull,0x3f3b3f0000000000ull,0xfefaff0000000000ull,0xeeeaff0000000000ull,0xe0aff0000000000ull,0xe0a1f0000000000ull,0xf0b1f0000000000ull,0xf0b1f0000000000ull,0xf0b1f0000000000ull,0xf0b1f0000000000ull,0xfefafe0000000000ull,0xeeeafe0000000000ull,0xe0aff0000000000ull,0xe0a0f0000000000ull,0xf0b0f0000000000ull,0xf0b0f0000000000ull,0xf0b0f0000000000ull,0xf0b1f0000000000ull,0xfefafc0000000000ull,0xeeeaf80000000000ull,0xe0a000000000000ull,0xe0a030000000000ull,0xf0b070000000000ull,0xf0b0f0000000000ull,0xf0b0f0000000000ull,0xf0b1f0000000000ull,0xfff9fc0000000000ull,0x7f7b7d0000000000ull,0xfff1fb0000000000ull,0xffebf70000000000ull,0xf03070000000000ull,0xf0b0f0000000000ull,0xf0b0f0000000000ull,0xf0b1f0000000000ull,0xfdf8fd0000000000ull,0x9090d0000000000ull,0x0ull,0xb030b0000000000ull,0x703070000000000ull,0xf0b0f0000000000ull,0xf0b0f0000000000ull,0xff0b1f0000000000ull,0xaefbff0000000000ull,0xa9a9df0000000000ull,0xa1a9df0000000000ull,0xa3abdf0000000000ull,0x87abdf0000000000ull,0x8f8b9f0000000000ull,0x8f8b9f0000000000ull,0xf8b9f0000000000ull}, - {0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0xfff7ff0000000000ull,0x7f777f0000000000ull,0x7f777f0000000000ull,0x7f777f0000000000ull,0xfcf4fe0000000000ull,0xfcf4fe0000000000ull,0xdcd4fe0000000000ull,0x1c14ff0000000000ull,0x1d153f0000000000ull,0x1f173f0000000000ull,0x1f173f0000000000ull,0x1f173f0000000000ull,0xfcf4fc0000000000ull,0xfcf4fc0000000000ull,0xdcd4fc0000000000ull,0x1c14ff0000000000ull,0x1d151f0000000000ull,0x1f171f0000000000ull,0x1f171f0000000000ull,0x1f171f0000000000ull,0xfcf4fc0000000000ull,0xfcf4f80000000000ull,0xdcd4f00000000000ull,0x1c14000000000000ull,0x1d15070000000000ull,0x1f170f0000000000ull,0x1f171f0000000000ull,0x1f171f0000000000ull,0xfdf5fc0000000000ull,0xfcf0f80000000000ull,0xfff5fb0000000000ull,0xfde1f70000000000ull,0xfdd5ef0000000000ull,0x1f070f0000000000ull,0x1f171f0000000000ull,0x1f171f0000000000ull,0xfff4fd0000000000ull,0xfcf0f80000000000ull,0x1911190000000000ull,0x0ull,0x404040000000000ull,0x1f070f0000000000ull,0x1f171f0000000000ull,0xff171f0000000000ull,0xfcf5ff0000000000ull,0xddf5ff0000000000ull,0xd9d5bf0000000000ull,0xd5d5bf0000000000ull,0xcdd5bf0000000000ull,0x9dd7bf0000000000ull,0x9f97bf0000000000ull,0x1f97bf0000000000ull}, - {0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xfeeefe0000000000ull,0xfeeefe0000000000ull,0xfeeefe0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xffefff0000000000ull,0xf8e8fc0000000000ull,0xf8e8fc0000000000ull,0xf8e8fc0000000000ull,0xb8a8fc0000000000ull,0x3828ff0000000000ull,0x3b2b7f0000000000ull,0x3f2f7f0000000000ull,0x3f2f7f0000000000ull,0xf8e8f80000000000ull,0xf8e8f80000000000ull,0xf8e8f80000000000ull,0xb8a8f80000000000ull,0x3828ff0000000000ull,0x3b2b3f0000000000ull,0x3f2f3f0000000000ull,0x3f2f3f0000000000ull,0xf8e8f80000000000ull,0xf8e8f80000000000ull,0xf8e8f00000000000ull,0xb8a8e00000000000ull,0x3828000000000000ull,0x3b2b0f0000000000ull,0x3f2f1f0000000000ull,0x3f2f3f0000000000ull,0xf8e8f80000000000ull,0xf8e8f80000000000ull,0xf8e0f00000000000ull,0xfde9f50000000000ull,0xf9c1e90000000000ull,0xf9a9d90000000000ull,0x3f0f1f0000000000ull,0xbfaf3f0000000000ull,0xffe8f80000000000ull,0xf8e8f80000000000ull,0xf8e0f00000000000ull,0x2020200000000000ull,0x0ull,0x9888980000000000ull,0x3f0f1f0000000000ull,0xff2fbf0000000000ull,0xf8e9fd0000000000ull,0xf9e9fd0000000000ull,0xb9ebfd0000000000ull,0xb3abfd0000000000ull,0xababfd0000000000ull,0x9babfd0000000000ull,0xbbafff0000000000ull,0x3fafff0000000000ull}, - {0xfedefe0000000000ull,0xfedefe0000000000ull,0xfedefe0000000000ull,0xfedefe0000000000ull,0xffdfff0000000000ull,0xffdfff0000000000ull,0xffdfff0000000000ull,0xffdfff0000000000ull,0xfcdcfc0000000000ull,0xfcdcfc0000000000ull,0xfcdcfc0000000000ull,0xfcdcfc0000000000ull,0xffdfff0000000000ull,0xffdfff0000000000ull,0xffdfff0000000000ull,0xffdfff0000000000ull,0xf0d0f80000000000ull,0xf0d0f80000000000ull,0xf0d0f80000000000ull,0xf0d0f80000000000ull,0x7050f80000000000ull,0x7050ff0000000000ull,0x7757ff0000000000ull,0x7f5fff0000000000ull,0xf0d0f80000000000ull,0xf0d0f00000000000ull,0xf0d0f00000000000ull,0xf0d0f00000000000ull,0x7050f00000000000ull,0x7050ff0000000000ull,0x77577f0000000000ull,0x7f5f7f0000000000ull,0xf0d0f80000000000ull,0xf0d0f00000000000ull,0xf0d0f00000000000ull,0xf0d0e00000000000ull,0x7050c00000000000ull,0x7050000000000000ull,0x77571f0000000000ull,0x7f5f3f0000000000ull,0xf0d0f80000000000ull,0xf0d0f00000000000ull,0xf0d0f00000000000ull,0xf0c0e00000000000ull,0xf9d1e90000000000ull,0xf181d10000000000ull,0xf0d0b00000000000ull,0xff9f3f0000000000ull,0xffd0f80000000000ull,0xf0d0f00000000000ull,0xf0d0f00000000000ull,0xe0c0e00000000000ull,0xd0c0d00000000000ull,0x0ull,0x9090b00000000000ull,0xbf1fbf0000000000ull,0xf0d1f90000000000ull,0xf1d1f90000000000ull,0xf1d1f90000000000ull,0xe1d5fb0000000000ull,0xc5d5fb0000000000ull,0x8595fb0000000000ull,0x9595fb0000000000ull,0x75dfff0000000000ull}, - {0xfcbcfc0000000000ull,0xfcbcfc0000000000ull,0xfcbcfc0000000000ull,0xfcbcfc0000000000ull,0xfcbcfc0000000000ull,0xffbfff0000000000ull,0xffbfff0000000000ull,0xffbfff0000000000ull,0xf8b8f80000000000ull,0xf8b8f80000000000ull,0xf8b8f80000000000ull,0xf8b8f80000000000ull,0xf8b8f80000000000ull,0xffbfff0000000000ull,0xffbfff0000000000ull,0xffbfff0000000000ull,0xf0b0f00000000000ull,0xe0a0f00000000000ull,0xe0a0f00000000000ull,0xe0a0f00000000000ull,0xe0a0f00000000000ull,0xe0a0f00000000000ull,0xe0a0ff0000000000ull,0xefafff0000000000ull,0xf0b0f00000000000ull,0xe0a0f00000000000ull,0xe0a0e00000000000ull,0xe0a0e00000000000ull,0xe0a0e00000000000ull,0xe0a0e00000000000ull,0xe0a0ff0000000000ull,0xefafff0000000000ull,0xf0b0f00000000000ull,0xe0a0f00000000000ull,0xe0a0e00000000000ull,0xe0a0e00000000000ull,0xe0a0c00000000000ull,0xe0a0800000000000ull,0xe0a0000000000000ull,0xefaf3f0000000000ull,0xf0b0f00000000000ull,0xe0a0f00000000000ull,0xe0a0e00000000000ull,0xe0a0e00000000000ull,0xe080c00000000000ull,0xf1a1d10000000000ull,0xe090b00000000000ull,0xe0a0700000000000ull,0xf1b0f00000000000ull,0xe0a0f00000000000ull,0xe0a0e00000000000ull,0xe0a0e00000000000ull,0xc080c00000000000ull,0x8090b00000000000ull,0x0ull,0x3020300000000000ull,0xe0b1f10000000000ull,0xe1a1f10000000000ull,0xe1a1f10000000000ull,0xe1a1f10000000000ull,0xc1a9f50000000000ull,0x9981e10000000000ull,0x101e10000000000ull,0x2121e10000000000ull}, - {0xc878f80000000000ull,0xc878f80000000000ull,0xc878f80000000000ull,0xc878f80000000000ull,0xc878f80000000000ull,0xc878f80000000000ull,0xce7efe0000000000ull,0xce7efe0000000000ull,0xc070f00000000000ull,0xc070f00000000000ull,0xc070f00000000000ull,0xc070f00000000000ull,0xc070f00000000000ull,0xc070f00000000000ull,0xce7efe0000000000ull,0xce7efe0000000000ull,0xc070f00000000000ull,0xc060e00000000000ull,0xc040e00000000000ull,0xc040e00000000000ull,0xc040e00000000000ull,0xc040e00000000000ull,0xc040e00000000000ull,0xc040fe0000000000ull,0xc070f00000000000ull,0xc060e00000000000ull,0xc040e00000000000ull,0xc040c00000000000ull,0xc040c00000000000ull,0xc040c00000000000ull,0xc040c00000000000ull,0xc040fe0000000000ull,0xc070f00000000000ull,0xc060e00000000000ull,0xc040e00000000000ull,0xc040c00000000000ull,0xc040c00000000000ull,0xc040800000000000ull,0xc040000000000000ull,0xc040000000000000ull,0xc070f00000000000ull,0xc060e00000000000ull,0xc040e00000000000ull,0xc040c00000000000ull,0xc040c00000000000ull,0xc000800000000000ull,0xc070b00000000000ull,0xe020600000000000ull,0xc070f00000000000ull,0xc060e00000000000ull,0xc040e00000000000ull,0xc040c00000000000ull,0xc040c00000000000ull,0x8000800000000000ull,0x100000000000ull,0x0ull,0xc070f00000000000ull,0xc060e00000000000ull,0xc040e00000000000ull,0xc040e00000000000ull,0xc040e00000000000ull,0x8050e80000000000ull,0xc00000000000ull,0xc00000000000ull}, - {0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x200000000000002ull,0x200000000000000ull,0x201000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x0ull,0x0ull,0x1000000000040ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x0ull,0x0ull,0x1000000000040ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull,0x203000000000000ull}, - {0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x504000000000000ull,0x500000000000000ull,0x501000000000000ull,0x503000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x404000000000000ull,0x0ull,0x101000000000000ull,0x103000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x404000000000000ull,0x0ull,0x101000000000000ull,0x103000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull,0x507000000000000ull}, - {0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0c000000000000ull,0xa08000000000000ull,0xa00000000000000ull,0xa02000000000000ull,0xa06000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0x80c000000000000ull,0x808000000000000ull,0x0ull,0x202000000000000ull,0x206000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0x80c000000000000ull,0x808000000000000ull,0x0ull,0x202000000000000ull,0x206000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull,0xa0e000000000000ull}, - {0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x1418000000000000ull,0x1410000000000000ull,0x1400000000000000ull,0x1404000000000000ull,0x140c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x1018000000000000ull,0x1010000000000000ull,0x0ull,0x404000000000000ull,0x40c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x141c000000000000ull,0x1018000000000000ull,0x1010000000000000ull,0x0ull,0x404000000000000ull,0x40c000000000000ull,0x141c000000000000ull,0x141c000000000000ull}, - {0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2830000000000000ull,0x2820000000000000ull,0x2800000000000000ull,0x2808000000000000ull,0x2818000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2030000000000000ull,0x2020000000000000ull,0x0ull,0x808000000000000ull,0x818000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2838000000000000ull,0x2030000000000000ull,0x2020000000000000ull,0x0ull,0x808000000000000ull,0x818000000000000ull,0x2838000000000000ull}, - {0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5060000000000000ull,0x5040000000000000ull,0x5000000000000000ull,0x5010000000000000ull,0x5030000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x4060000000000000ull,0x4040000000000000ull,0x0ull,0x1010000000000000ull,0x1030000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x5070000000000000ull,0x4060000000000000ull,0x4040000000000000ull,0x0ull,0x1010000000000000ull,0x1030000000000000ull}, - {0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0c0000000000000ull,0xa080000000000000ull,0xa000000000000000ull,0xa020000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0x80c0000000000000ull,0x8080000000000000ull,0x0ull,0x2020000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0xa0e0000000000000ull,0x80c0000000000000ull,0x8080000000000000ull,0x0ull,0x2020000000000000ull}, - {0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x4080000000000000ull,0x4000000000000000ull,0x4000000000000040ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x80000000000002ull,0x0ull,0x0ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x40c0000000000000ull,0x80000000000002ull,0x0ull,0x0ull} - - } - }; - - - static constexpr u64 KPK_WHITE_PAWN[2][64][64] = { - { - {0x0ull,0x404ull,0xc08ull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x30000ull,0x878484ull,0xfffbaeull,0xfff5fcull,0xfde9f8ull,0xf9d1f0ull,0xf1b1e0ull,0xf070c0ull,0x3f7e7f7eull,0x7ffdfffeull,0xfffbfffeull,0xfff7fffeull,0xffeffdfcull,0xffddf9f8ull,0xfcb9f1f0ull,0xf870f0e0ull,0x1f3e7f7f7eull,0x3f7dfffffeull,0x7ffbfffffeull,0xfff7fffffeull,0xffeffffdfcull,0xfedffdf9f8ull,0xfcbcf9f1f0ull,0xf878f0f0e0ull,0xf1e3f7f7f7eull,0x1f3d7ffffffeull,0x3f7bfffffffeull,0x7ff7fffffffeull,0xfeeffffffdfcull,0xfcdefffdf9f8ull,0xf8bcfcf9f1f0ull,0xf078f8f0f0e0ull,0x70e1f3f7f7f7eull,0xf1d3f7ffffffeull,0x1f3b7ffffffffeull,0x3e77fffffffffeull,0x7ceefffffffdfcull,0xf8dcfefffdf9f8ull,0xf0b8fcfcf9f1f0ull,0xe070f8f8f0f0e0ull,0x3060f1f3f7f7f7eull,0x70d1f3f7ffffffeull,0xe1b3f7ffffffffeull,0x1c367ffffffffffeull,0x386cfefffffffdfcull,0x70d8fcfefffdf9f8ull,0xe0b0f8fcfcf9f1f0ull,0xc060f0f8f8f0f0e0ull,0x2070f1f3f7f7f7eull,0x50f1f3f7ffffffeull,0xa1f3f7ffffffffeull,0x143e7ffffffffffeull,0x287cfefffffffdfcull,0x50f8fcfefffdf9f8ull,0xa0f0f8fcfcf9f1f0ull,0x40e0f0f8f8f0f0e0ull}, - {0x0ull,0x0ull,0x808ull,0x1810ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x30000ull,0x878080ull,0xdfa9a9ull,0xfff5ddull,0xfde9f9ull,0xf9d1f1ull,0xf1a1e1ull,0xe060c0ull,0x3f7e7f0dull,0x7ffdfffdull,0xfffbfffdull,0xfff7fffdull,0xffeffdfdull,0xffddf9f9ull,0xfcb9f1f1ull,0xf870e0e0ull,0x1f3e7f7f0dull,0x3f7dfffffdull,0x7ffbfffffdull,0xfff7fffffdull,0xffeffffdfdull,0xfedffdf9f9ull,0xfcbcf9f1f1ull,0xf878f0e0e0ull,0xf1e3f7f7f0dull,0x1f3d7ffffffdull,0x3f7bfffffffdull,0x7ff7fffffffdull,0xfeeffffffdfdull,0xfcdefffdf9f9ull,0xf8bcfcf9f1f1ull,0xf078f8f0e0e0ull,0x70e1f3f7f7f0dull,0xf1d3f7ffffffdull,0x1f3b7ffffffffdull,0x3e77fffffffffdull,0x7ceefffffffdfdull,0xf8dcfefffdf9f9ull,0xf0b8fcfcf9f1f1ull,0xe070f8f8f0e0e0ull,0x3060f1f3f7f7f0dull,0x70d1f3f7ffffffdull,0xe1b3f7ffffffffdull,0x1c367ffffffffffdull,0x386cfefffffffdfdull,0x70d8fcfefffdf9f9ull,0xe0b0f8fcfcf9f1f1ull,0xc060f0f8f8f0e0e0ull,0x2070f1f3f7f7f0dull,0x50f1f3f7ffffffdull,0xa1f3f7ffffffffdull,0x143e7ffffffffffdull,0x287cfefffffffdfdull,0x50f8fcfefffdf9f9ull,0xa0f0f8fcfcf9f1f1ull,0x40e0f0f8f8f0e0e0ull}, - {0x4000000000000100ull,0x101ull,0x0ull,0x1010ull,0x3020ull,0x7050ull,0xe0a0ull,0xc040ull,0x170a01ull,0x878199ull,0xdfa9a1ull,0xbfd5d9ull,0xfdebb9ull,0xf9d1f1ull,0xf1a1e1ull,0xe040c0ull,0x3f1e0f0bull,0x7ffdff9bull,0xfffbfffbull,0xfff7fffbull,0xffeffff9ull,0xffddf9f9ull,0xfcb9f1f1ull,0xf870e0e0ull,0x1f3e1f0f0bull,0x3f7dffff9bull,0x7ffbfffffbull,0xfff7fffffbull,0xffeffffff9ull,0xfedffdf9f9ull,0xfcbcf9f1f1ull,0xf878f0e0e0ull,0xf1e3f1f0f0bull,0x1f3d7fffff9bull,0x3f7bfffffffbull,0x7ff7fffffffbull,0xfeeffffffff9ull,0xfcdefffdf9f9ull,0xf8bcfcf9f1f1ull,0xf078f8f0e0e0ull,0x70e1f3f1f0f0bull,0xf1d3f7fffff9bull,0x1f3b7ffffffffbull,0x3e77fffffffffbull,0x7ceefffffffff9ull,0xf8dcfefffdf9f9ull,0xf0b8fcfcf9f1f1ull,0xe070f8f8f0e0e0ull,0x3060f1f3f1f0f0bull,0x70d1f3f7fffff9bull,0xe1b3f7ffffffffbull,0x1c367ffffffffffbull,0x386cfefffffffff9ull,0x70d8fcfefffdf9f9ull,0xe0b0f8fcfcf9f1f1ull,0xc060f0f8f8f0e0e0ull,0x2070f1f3f1f0f0bull,0x50f1f3f7fffff9bull,0xa1f3f7ffffffffbull,0x143e7ffffffffffbull,0x287cfefffffffff9ull,0x50f8fcfefffdf9f9ull,0xa0f0f8fcfcf9f1f1ull,0x40e0f0f8f8f0e0e0ull}, - {0x302ull,0x301ull,0x202ull,0x0ull,0x2020ull,0x6040ull,0xe0a0ull,0xc040ull,0x70203ull,0xaf9583ull,0xdfaba3ull,0xbfd5d5ull,0xfdabb3ull,0xfbd5e1ull,0xf1a1e1ull,0xe040c0ull,0x1f0e0707ull,0x7fbd9f87ull,0xfffbffb7ull,0xfff7fff7ull,0xffeffff7ull,0xffdffdf1ull,0xfcb9f1f1ull,0xf870e0e0ull,0x1f1e0f0707ull,0x3f7dbf9f87ull,0x7ffbffffb7ull,0xfff7fffff7ull,0xffeffffff7ull,0xfedffffdf1ull,0xfcbcf9f1f1ull,0xf878f0e0e0ull,0xf1e1f0f0707ull,0x1f3d7fbf9f87ull,0x3f7bffffffb7ull,0x7ff7fffffff7ull,0xfeeffffffff7ull,0xfcdefffffdf1ull,0xf8bcfcf9f1f1ull,0xf078f8f0e0e0ull,0x70e1f1f0f0707ull,0xf1d3f7fbf9f87ull,0x1f3b7fffffffb7ull,0x3e77fffffffff7ull,0x7ceefffffffff7ull,0xf8dcfefffffdf1ull,0xf0b8fcfcf9f1f1ull,0xe070f8f8f0e0e0ull,0x3060f1f1f0f0707ull,0x70d1f3f7fbf9f87ull,0xe1b3f7fffffffb7ull,0x1c367ffffffffff7ull,0x386cfefffffffff7ull,0x70d8fcfefffffdf1ull,0xe0b0f8fcfcf9f1f1ull,0xc060f0f8f8f0e0e0ull,0x2070f1f1f0f0707ull,0x50f1f3f7fbf9f87ull,0xa1f3f7fffffffb7ull,0x143e7ffffffffff7ull,0x287cfefffffffff7ull,0x50f8fcfefffffdf1ull,0xa0f0f8fcfcf9f1f1ull,0x40e0f0f8f8f0e0e0ull}, - {0x302ull,0x705ull,0x602ull,0x404ull,0x0ull,0x4040ull,0xc080ull,0xc040ull,0x70203ull,0x8f8587ull,0xdfab87ull,0xbfd5cdull,0xfdababull,0xfbd5c5ull,0xf5a9c1ull,0xe040c0ull,0x1f0e0707ull,0x3f9d8f8full,0xfffbbf8full,0xfff7ffefull,0xffefffefull,0xffdfffedull,0xfebdf9e1ull,0xf870e0e0ull,0x1f1e0f0707ull,0x3f3d9f8f8full,0x7ffbffbf8full,0xfff7ffffefull,0xffefffffefull,0xfedfffffedull,0xfcbefdf9e1ull,0xf878f0e0e0ull,0xf1e1f0f0707ull,0x1f3d3f9f8f8full,0x3f7bffffbf8full,0x7ff7ffffffefull,0xfeefffffffefull,0xfcdeffffffedull,0xf8bcfefdf9e1ull,0xf078f8f0e0e0ull,0x70e1f1f0f0707ull,0xf1d3f3f9f8f8full,0x1f3b7fffffbf8full,0x3e77ffffffffefull,0x7ceeffffffffefull,0xf8dcfeffffffedull,0xf0b8fcfefdf9e1ull,0xe070f8f8f0e0e0ull,0x3060f1f1f0f0707ull,0x70d1f3f3f9f8f8full,0xe1b3f7fffffbf8full,0x1c367fffffffffefull,0x386cfeffffffffefull,0x70d8fcfeffffffedull,0xe0b0f8fcfefdf9e1ull,0xc060f0f8f8f0e0e0ull,0x2070f1f1f0f0707ull,0x50f1f3f3f9f8f8full,0xa1f3f7fffffbf8full,0x143e7fffffffffefull,0x287cfeffffffffefull,0x50f8fcfeffffffedull,0xa0f0f8fcfefdf9e1ull,0x40e0f0f8f8f0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0xc04ull,0x808ull,0x0ull,0x8080ull,0x200000000008000ull,0x70203ull,0x8f8587ull,0x9f8b8full,0xbfd79dull,0xfdab9bull,0xfb9585ull,0xe18199ull,0xe85080ull,0x1f0e0707ull,0x3f9d8f8full,0xffbb9f9full,0xfff7ff9full,0xffefffdfull,0xffdfffdfull,0xfebfffd9ull,0xfc78f0d0ull,0x1f1e0f0707ull,0x3f3d9f8f8full,0x7ffbbf9f9full,0xfff7ffff9full,0xffefffffdfull,0xfedfffffdfull,0xfcbeffffd9ull,0xf87cf8f0d0ull,0xf1e1f0f0707ull,0x1f3d3f9f8f8full,0x3f7bffbf9f9full,0x7ff7ffffff9full,0xfeefffffffdfull,0xfcdeffffffdfull,0xf8bcfeffffd9ull,0xf078fcf8f0d0ull,0x70e1f1f0f0707ull,0xf1d3f3f9f8f8full,0x1f3b7fffbf9f9full,0x3e77ffffffff9full,0x7ceeffffffffdfull,0xf8dcfeffffffdfull,0xf0b8fcfeffffd9ull,0xe070f8fcf8f0d0ull,0x3060f1f1f0f0707ull,0x70d1f3f3f9f8f8full,0xe1b3f7fffbf9f9full,0x1c367fffffffff9full,0x386cfeffffffffdfull,0x70d8fcfeffffffdfull,0xe0b0f8fcfeffffd9ull,0xc060f0f8fcf8f0d0ull,0x2070f1f1f0f0707ull,0x50f1f3f3f9f8f8full,0xa1f3f7fffbf9f9full,0x143e7fffffffff9full,0x287cfeffffffffdfull,0x50f8fcfeffffffdfull,0xa0f0f8fcfeffffd9ull,0x40e0f0f8fcf8f0d0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x1808ull,0x1010ull,0x0ull,0x0ull,0x70603ull,0x8f8587ull,0x9f8b8full,0xbf979full,0xffafbbull,0xfb9595ull,0xe10101ull,0xc00000ull,0x1f0e0707ull,0x3f9d8f8full,0xffbb9f9full,0xfff7bfbfull,0xffefffbfull,0xffdfffbfull,0xfebfffbfull,0xfc7efeb0ull,0x1f1e0f0707ull,0x3f3d9f8f8full,0x7ffbbf9f9full,0xfff7ffbfbfull,0xffefffffbfull,0xfedfffffbfull,0xfcbeffffbfull,0xf87cfefeb0ull,0xf1e1f0f0707ull,0x1f3d3f9f8f8full,0x3f7bffbf9f9full,0x7ff7ffffbfbfull,0xfeefffffffbfull,0xfcdeffffffbfull,0xf8bcfeffffbfull,0xf078fcfefeb0ull,0x70e1f1f0f0707ull,0xf1d3f3f9f8f8full,0x1f3b7fffbf9f9full,0x3e77ffffffbfbfull,0x7ceeffffffffbfull,0xf8dcfeffffffbfull,0xf0b8fcfeffffbfull,0xe070f8fcfefeb0ull,0x3060f1f1f0f0707ull,0x70d1f3f3f9f8f8full,0xe1b3f7fffbf9f9full,0x1c367fffffffbfbfull,0x386cfeffffffffbfull,0x70d8fcfeffffffbfull,0xe0b0f8fcfeffffbfull,0xc060f0f8fcfefeb0ull,0x2070f1f1f0f0707ull,0x50f1f3f3f9f8f8full,0xa1f3f7fffbf9f9full,0x143e7fffffffbfbfull,0x287cfeffffffffbfull,0x50f8fcfeffffffbfull,0xa0f0f8fcfeffffbfull,0x40e0f0f8fcfefeb0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x3010ull,0x2020ull,0x0ull,0xf0e03ull,0x8f8d07ull,0x9f8b0full,0xbf971full,0xffaf3full,0xffdf75ull,0xe12121ull,0xc00000ull,0x1f0e0f07ull,0x3f9d8f0full,0xffbb9f1full,0xfff7bf3full,0xffefff7full,0xffdfff7full,0xfebfff7full,0xfc7efe7eull,0x1f1e0f0f07ull,0x3f3d9f8f0full,0x7ffbbf9f1full,0xfff7ffbf3full,0xffefffff7full,0xfedfffff7full,0xfcbeffff7full,0xf87cfefe7eull,0xf1e1f0f0f07ull,0x1f3d3f9f8f0full,0x3f7bffbf9f1full,0x7ff7ffffbf3full,0xfeefffffff7full,0xfcdeffffff7full,0xf8bcfeffff7full,0xf078fcfefe7eull,0x70e1f1f0f0f07ull,0xf1d3f3f9f8f0full,0x1f3b7fffbf9f1full,0x3e77ffffffbf3full,0x7ceeffffffff7full,0xf8dcfeffffff7full,0xf0b8fcfeffff7full,0xe070f8fcfefe7eull,0x3060f1f1f0f0f07ull,0x70d1f3f3f9f8f0full,0xe1b3f7fffbf9f1full,0x1c367fffffffbf3full,0x386cfeffffffff7full,0x70d8fcfeffffff7full,0xe0b0f8fcfeffff7full,0xc060f0f8fcfefe7eull,0x2070f1f1f0f0f07ull,0x50f1f3f3f9f8f0full,0xa1f3f7fffbf9f1full,0x143e7fffffffbf3full,0x287cfeffffffff7full,0x50f8fcfeffffff7full,0xa0f0f8fcfeffff7full,0x40e0f0f8fcfefe7eull}, - {0x0ull,0x404ull,0xc08ull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x0ull,0xc040cull,0xfdf8fdull,0xfdf4ffull,0xf8e8ffull,0xf8d0ffull,0xf0b0f1ull,0xf070c0ull,0xf0e060full,0xf8d8e8full,0xfffbfeffull,0xfff5fcffull,0xfde9f8ffull,0xf9d9f8ffull,0xf0b1f0ffull,0xf070f0feull,0x1f3e7f7e7full,0x3f7dfffeffull,0x7ffbfffeffull,0xfff7fffcffull,0xffeffdf8ffull,0xfeddf9f8ffull,0xfcb8f1f0ffull,0xf870f0f0feull,0xf1e3f7f7e7full,0x1f3d7ffffeffull,0x3f7bfffffeffull,0x7ff7fffffcffull,0xfeeffffdf8ffull,0xfcdefdf9f8ffull,0xf8bcf8f1f0ffull,0xf078f0f0f0feull,0x70e1f3f7f7e7full,0xf1d3f7ffffeffull,0x1f3b7ffffffeffull,0x3e77fffffffcffull,0x7ceefffffdf8ffull,0xf8dcfefdf9f8ffull,0xf0b8fcf8f1f0ffull,0xe070f8f0f0f0feull,0x3060f1f3f7f7e7full,0x70d1f3f7ffffeffull,0xe1b3f7ffffffeffull,0x1c367ffffffffcffull,0x386cfefffffdf8ffull,0x70d8fcfefdf9f8ffull,0xe0b0f8fcf8f1f0ffull,0xc060f0f8f0f0f0feull,0x2070f1f3f7f000full,0x50f1f3f7ffff0ffull,0xa1f3f7ffffff0ffull,0x143e7ffffffff0ffull,0x287cfefffffdf0ffull,0x50f8fcfefdf9f0ffull,0xa0f0f8fcf8f1f0ffull,0x40e0f0f8f0f0f0feull}, - {0x0ull,0x0ull,0x808ull,0x1810ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x80000ull,0x0ull,0xd0909ull,0xf8f0fcull,0xf8e8f8ull,0xf0d0f0ull,0xf0a0e0ull,0xe060c0ull,0xf0e0507ull,0xf8d8d8full,0xdfab8d8full,0xfff5fdfdull,0xfde9f9f9ull,0xf9d1f1f9ull,0xf0b1f1f1ull,0xe060e0e0ull,0x1f3e7f7d7full,0x3f7dfffdffull,0x7ffbfffdffull,0xfff7fffdfdull,0xffeffdf9f9ull,0xfeddf9f1f9ull,0xfcb8f1f1f1ull,0xf870e0e0e0ull,0xf1e3f7f7d7full,0x1f3d7ffffdffull,0x3f7bfffffdffull,0x7ff7fffffdfdull,0xfeeffffdf9f9ull,0xfcdefdf9f1f9ull,0xf8bcf8f1f1f1ull,0xf078f0e0e0e0ull,0x70e1f3f7f7d7full,0xf1d3f7ffffdffull,0x1f3b7ffffffdffull,0x3e77fffffffdfdull,0x7ceefffffdf9f9ull,0xf8dcfefdf9f1f9ull,0xf0b8fcf8f1f1f1ull,0xe070f8f0e0e0e0ull,0x3060f1f3f7f7d7full,0x70d1f3f7ffffdffull,0xe1b3f7ffffffdffull,0x1c367ffffffffdfdull,0x386cfefffffdf9f9ull,0x70d8fcfefdf9f1f9ull,0xe0b0f8fcf8f1f1f1ull,0xc060f0f8f0e0e0e0ull,0x2070f1f3f7f0101ull,0x50f1f3f7fff8181ull,0xa1f3f7fffffe1e1ull,0x143e7fffffffe1e1ull,0x287cfefffffde1e1ull,0x50f8fcfefdf9e1e1ull,0xa0f0f8fcf8f1e1e1ull,0x40e0f0f8f0e0e0e0ull}, - {0x4000000000000100ull,0x101ull,0x0ull,0x1010ull,0x3020ull,0x7050ull,0xe0a0ull,0xc040ull,0x10001ull,0xd0901ull,0x0ull,0x191119ull,0xf0e0f8ull,0xf0d0f0ull,0xe0a0e0ull,0xe040c0ull,0x170a0307ull,0xf8d8b8full,0xdfab8b8full,0xbfd59b9full,0xfdebf9f9ull,0xf9d1f1f1ull,0xf0a1e1e1ull,0xe060e0e0ull,0x1f1e0f030full,0x3f7dfffbffull,0x7ffbfffbffull,0xfff7fffbffull,0xffeffff9f9ull,0xfeddf9f1f1ull,0xfcb8f1e1e1ull,0xf870e0e0e0ull,0xf1e1f0f030full,0x1f3d7ffffbffull,0x3f7bfffffbffull,0x7ff7fffffbffull,0xfeeffffff9f9ull,0xfcdefdf9f1f1ull,0xf8bcf8f1e1e1ull,0xf078f0e0e0e0ull,0x70e1f1f0f030full,0xf1d3f7ffffbffull,0x1f3b7ffffffbffull,0x3e77fffffffbffull,0x7ceefffffff9f9ull,0xf8dcfefdf9f1f1ull,0xf0b8fcf8f1e1e1ull,0xe070f8f0e0e0e0ull,0x3060f1f1f0f030full,0x70d1f3f7ffffbffull,0xe1b3f7ffffffbffull,0x1c367ffffffffbffull,0x386cfefffffff9f9ull,0x70d8fcfefdf9f1f1ull,0xe0b0f8fcf8f1e1e1ull,0xc060f0f8f0e0e0e0ull,0x2070f1f1f0f0101ull,0x50f1f3f7fff8181ull,0xa1f3f7fffff8181ull,0x143e7fffffffc1c1ull,0x287cfeffffffc1c1ull,0x50f8fcfefdf9c1c1ull,0xa0f0f8fcf8f1c1c1ull,0x40e0f0f8f0e0c0c0ull}, - {0x302ull,0x301ull,0x202ull,0x0ull,0x2020ull,0x6040ull,0xe0a0ull,0xc040ull,0x30203ull,0x30103ull,0xb030bull,0x0ull,0x202020ull,0xe0c0e0ull,0xe0a0e0ull,0xc040c0ull,0x7020303ull,0x2f95878full,0xdfab878full,0xbfd5979full,0xfdabf1f9ull,0xfbd5f1f1ull,0xf0a1e1e1ull,0xe040c0c0ull,0x1f0e070303ull,0x3f3d9f878full,0x7ffbfff7ffull,0xfff7fff7ffull,0xffeffff7ffull,0xfedffdf1f1ull,0xfcb8f1e1e1ull,0xf870e0c0c0ull,0xf1e0f070303ull,0x1f3d3f9f878full,0x3f7bfffff7ffull,0x7ff7fffff7ffull,0xfeeffffff7ffull,0xfcdefffdf1f1ull,0xf8bcf8f1e1e1ull,0xf078f0e0c0c0ull,0x70e1f0f070303ull,0xf1d3f3f9f878full,0x1f3b7ffffff7ffull,0x3e77fffffff7ffull,0x7ceefffffff7ffull,0xf8dcfefffdf1f1ull,0xf0b8fcf8f1e1e1ull,0xe070f8f0e0c0c0ull,0x3060f1f0f070303ull,0x70d1f3f3f9f878full,0xe1b3f7ffffff7ffull,0x1c367ffffffff7ffull,0x386cfefffffff7ffull,0x70d8fcfefffdf1f1ull,0xe0b0f8fcf8f1e1e1ull,0xc060f0f8f0e0c0c0ull,0x2070f1f0f070101ull,0x50f1f3f3f9f8181ull,0xa1f3f7fffff8181ull,0x143e7fffffff8181ull,0x287cfeffffff8181ull,0x50f8fcfefffd8181ull,0xa0f0f8fcf8f18181ull,0x40e0f0f8f0e08080ull}, - {0x302ull,0x705ull,0x602ull,0x404ull,0x0ull,0x4040ull,0xc080ull,0xc040ull,0x30203ull,0x70507ull,0x70307ull,0x40404ull,0x0ull,0xd0c0d0ull,0xc080c0ull,0xc040c0ull,0x7020303ull,0xf858787ull,0xdfab8f8full,0xbfd58f9full,0xfdabe9f9ull,0xfbd5e1f1ull,0xf4a9e1f1ull,0xe040c0c0ull,0x1f0e070303ull,0x3f1d8f8787ull,0x7ffbbf8f8full,0xfff7ffefffull,0xffefffefffull,0xfedfffefffull,0xfcbcf9e1f1ull,0xf870e0c0c0ull,0xf1e0f070303ull,0x1f3d1f8f8787ull,0x3f7bffbf8f8full,0x7ff7ffffefffull,0xfeefffffefffull,0xfcdeffffefffull,0xf8bcfcf9e1f1ull,0xf078f0e0c0c0ull,0x70e1f0f070303ull,0xf1d3f1f8f8787ull,0x1f3b7fffbf8f8full,0x3e77ffffffefffull,0x7ceeffffffefffull,0xf8dcfeffffefffull,0xf0b8fcfcf9e1f1ull,0xe070f8f0e0c0c0ull,0x3060f1f0f070303ull,0x70d1f3f1f8f8787ull,0xe1b3f7fffbf8f8full,0x1c367fffffffefffull,0x386cfeffffffefffull,0x70d8fcfeffffefffull,0xe0b0f8fcfcf9e1f1ull,0xc060f0f8f0e0c0c0ull,0x2070f1f0f070101ull,0x50f1f3f1f8f8181ull,0xa1f3f7fffbf8181ull,0x143e7fffffff8181ull,0x287cfeffffff8181ull,0x50f8fcfeffff8181ull,0xa0f0f8fcfcf98181ull,0x40e0f0f8f0e08080ull}, - {0x302ull,0x705ull,0xe0aull,0xc04ull,0x808ull,0x0ull,0x8080ull,0x200000000008000ull,0x70203ull,0x70507ull,0xf0b0full,0xf071full,0x988898ull,0x0ull,0xb09080ull,0x800080ull,0x7060707ull,0xf858787ull,0x9f8b8f8full,0xbfd79f9full,0xfdabd9f9ull,0xfbd5d1f1ull,0xf0b1d1f1ull,0xe850c0e0ull,0x1f0e070707ull,0x3f1d8f8787ull,0x7fbb9f8f8full,0xfff7ff9f9full,0xffefffdfffull,0xfedfffdfffull,0xfcbeffdfffull,0xf878f0c0f0ull,0xf1e0f070707ull,0x1f3d1f8f8787ull,0x3f7bbf9f8f8full,0x7ff7ffff9f9full,0xfeefffffdfffull,0xfcdeffffdfffull,0xf8bcfeffdfffull,0xf078f8f0c0f0ull,0x70e1f0f070707ull,0xf1d3f1f8f8787ull,0x1f3b7fbf9f8f8full,0x3e77ffffff9f9full,0x7ceeffffffdfffull,0xf8dcfeffffdfffull,0xf0b8fcfeffdfffull,0xe070f8f8f0c0f0ull,0x3060f1f0f070707ull,0x70d1f3f1f8f8787ull,0xe1b3f7fbf9f8f8full,0x1c367fffffff9f9full,0x386cfeffffffdfffull,0x70d8fcfeffffdfffull,0xe0b0f8fcfeffdfffull,0xc060f0f8f8f0c0f0ull,0x2070f1f0f070303ull,0x50f1f3f1f8f8383ull,0xa1f3f7fbf9f8383ull,0x143e7fffffff8383ull,0x287cfeffffff8383ull,0x50f8fcfeffff8181ull,0xa0f0f8fcfeff8181ull,0x40e0f0f8f8f08080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x1808ull,0x1010ull,0x0ull,0x0ull,0x70603ull,0xf0507ull,0xf0b0full,0x1f171full,0x1f0f3full,0xb09090ull,0x0ull,0x100000ull,0x7060707ull,0xf8d8f8full,0x9f8b8f9full,0xbf979f9full,0xffafbfbfull,0xfbd5b1f1ull,0xf0b1b1f1ull,0xf070a0e0ull,0x1f0e070707ull,0x3f1d8f8f8full,0x7fbb9f8f9full,0xfff7bf9f9full,0xffefffbfbfull,0xfedfffbfffull,0xfcbeffbfffull,0xf87cfebefeull,0xf1e0f070707ull,0x1f3d1f8f8f8full,0x3f7bbf9f8f9full,0x7ff7ffbf9f9full,0xfeefffffbfbfull,0xfcdeffffbfffull,0xf8bcfeffbfffull,0xf078fcfebefeull,0x70e1f0f070707ull,0xf1d3f1f8f8f8full,0x1f3b7fbf9f8f9full,0x3e77ffffbf9f9full,0x7ceeffffffbfbfull,0xf8dcfeffffbfffull,0xf0b8fcfeffbfffull,0xe070f8fcfebefeull,0x3060f1f0f070707ull,0x70d1f3f1f8f8f8full,0xe1b3f7fbf9f8f9full,0x1c367fffffbf9f9full,0x386cfeffffffbfbfull,0x70d8fcfeffffbfffull,0xe0b0f8fcfeffbfffull,0xc060f0f8fcfebefeull,0x2070f1f0f070707ull,0x50f1f3f1f8f8787ull,0xa1f3f7fbf9f8787ull,0x143e7fffffbf8787ull,0x287cfeffffff8787ull,0x50f8fcfeffff8787ull,0xa0f0f8fcfeff8181ull,0x40e0f0f8fcfe8080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x3010ull,0x2020ull,0x0ull,0xf0e03ull,0xf0d8full,0x1f0bffull,0x1f17ffull,0xbf2fffull,0xbf1fbfull,0x302030ull,0x0ull,0xf0e0f7full,0xf8d0fffull,0x9f9b1fffull,0xbf971fffull,0xffaf3fffull,0xffdf7fffull,0xf0b171f1ull,0xf07060f0ull,0x1f0e0f0f7full,0x3f1d8f0fffull,0x7fbb9f1fffull,0xfff7bf1fffull,0xffefff3fffull,0xfedfff7fffull,0xfcbeff7fffull,0xf87cfe7efeull,0xf1e0f0f0f7full,0x1f3d1f8f0fffull,0x3f7bbf9f1fffull,0x7ff7ffbf1fffull,0xfeefffff3fffull,0xfcdeffff7fffull,0xf8bcfeff7fffull,0xf078fcfe7efeull,0x70e1f0f0f0f7full,0xf1d3f1f8f0fffull,0x1f3b7fbf9f1fffull,0x3e77ffffbf1fffull,0x7ceeffffff3fffull,0xf8dcfeffff7fffull,0xf0b8fcfeff7fffull,0xe070f8fcfe7efeull,0x3060f1f0f0f0f7full,0x70d1f3f1f8f0fffull,0xe1b3f7fbf9f1fffull,0x1c367fffffbf1fffull,0x386cfeffffff3fffull,0x70d8fcfeffff7fffull,0xe0b0f8fcfeff7fffull,0xc060f0f8fcfe7efeull,0x2070f1f0f0f0f7full,0x50f1f3f1f8f0fffull,0xa1f3f7fbf9f0fffull,0x143e7fffffbf0fffull,0x287cfeffffff0fffull,0x50f8fcfeffff0fffull,0xa0f0f8fcfeff0fffull,0x40e0f0f8fcfe00f0ull}, - {0x200000000000002ull,0x405ull,0xc0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x3e3c3full,0x3e3d3full,0xfcf9ffull,0xfcf5fdull,0xf8e8f8ull,0xf8d0f0ull,0xf0b0f0ull,0xf070c0ull,0x0ull,0xc3c3f3full,0xfdf8fdfdull,0xfdf4fdedull,0xf8e8f8d8ull,0xf8d8f8b8ull,0xf0b0f0f0ull,0xf070f0f0ull,0xf0e3e3f3full,0xf0cbebfbfull,0x7ffbfefdfdull,0xfff5fcfdfdull,0xfde9f8f9f9ull,0xf8d9f8f9f9ull,0xf0b0f0f1f1ull,0xf070f0f0f0ull,0xf1e3f7e0101ull,0x1f3d7ffeffffull,0x3f7bfffefdfdull,0x7ff7fffcfdfdull,0xfeeffdf8f9f9ull,0xfcdcf9f8f9f9ull,0xf8b8f0f0f1f1ull,0xf070f0f0f0f0ull,0x70e1f3f7e3f3full,0xf1d3f7ffeffffull,0x1f3b7ffffefdfdull,0x3e77fffffcfdfdull,0x7ceefffdf8f9f9ull,0xf8dcfcf9f8f9f9ull,0xf0b8f8f0f0f1f1ull,0xe070f0f0f0f0f0ull,0x3060f1f3f7e0101ull,0x70d1f3f7ffef9f9ull,0xe1b3f7ffffef9f9ull,0x1c367ffffffcf9f9ull,0x386cfefffdf8f9f9ull,0x70d8fcfcf9f8f9f9ull,0xe0b0f8f8f0f0f1f1ull,0xc060f0f0f0f0f0f0ull,0x2070f1f3f7e0101ull,0x50f1f3f7ffef1f1ull,0xa1f3f7ffffef1f1ull,0x143e7ffffffcf1f1ull,0x287cfefffdf8f1f1ull,0x50f8fcfcf9f8f1f1ull,0xa0f0f8f8f0f0f1f1ull,0x40e0f0f0f0f0f0f0ull}, - {0x2ull,0x5ull,0x80aull,0x1814ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x7d7e7full,0x7d797full,0x7d7b7full,0xf8f0fcull,0xf8e8f8ull,0xf0d0f0ull,0xf0a0e0ull,0xe060c0ull,0x87c7f7full,0x0ull,0xd797f7full,0xf8f0f8e8ull,0xf8e8f8d8ull,0xf0d0f0b0ull,0xf0b0f0f0ull,0xe060e0e0ull,0xf0e7d7f7full,0xf0cfdffffull,0x5fa9fdffffull,0xfff5fdf9f9ull,0xfde9f9f9f9ull,0xf8d1f1f1f1ull,0xf0b0f1f1f1ull,0xe060e0e0e0ull,0xf1e3f7d7f7full,0x1f3d7ffd8181ull,0x3f7bfffdffffull,0x7ff7fffdf9f9ull,0xfeeffdf9f9f9ull,0xfcdcf9f1f1f1ull,0xf8b8f0f1f1f1ull,0xf070e0e0e0e0ull,0x70e1f3f7d7f7full,0xf1d3f7ffdffffull,0x1f3b7ffffdffffull,0x3e77fffffdf9f9ull,0x7ceefffdf9f9f9ull,0xf8dcfcf9f1f1f1ull,0xf0b8f8f0f1f1f1ull,0xe070f0e0e0e0e0ull,0x3060f1f3f7d0101ull,0x70d1f3f7ffd8181ull,0xe1b3f7ffffdf1f1ull,0x1c367ffffffdf1f1ull,0x386cfefffdf9f1f1ull,0x70d8fcfcf9f1f1f1ull,0xe0b0f8f8f0f1f1f1ull,0xc060f0f0e0e0e0e0ull,0x2070f1f3f7d0101ull,0x50f1f3f7ffd8181ull,0xa1f3f7ffffde1e1ull,0x143e7ffffffde1e1ull,0x287cfefffdf9e1e1ull,0x50f8fcfcf9f1e1e1ull,0xa0f0f8f8f0f1e1e1ull,0x40e0f0f0e0e0e0e0ull}, - {0x102ull,0x105ull,0xaull,0x1014ull,0x3028ull,0x7050ull,0xe0a0ull,0xc040ull,0x10003ull,0xfbf5ffull,0xfbf1ffull,0xfbf5fdull,0xf0e0f8ull,0xf0d0f0ull,0xe0a0e0ull,0xe040c0ull,0x1000101ull,0xdf9ffffull,0x0ull,0x19f3fdfdull,0xf0e0f0d0ull,0xf0d0f0b0ull,0xe0a0e0e0ull,0xe060e0e0ull,0x170a030101ull,0xf0dfbffffull,0x5fa9fbffffull,0xbfd5fbfdfdull,0xfdebf9f1f1ull,0xf8d1f1f1f1ull,0xf0a0e1e1e1ull,0xe060e0e0e0ull,0xf1e0f030101ull,0x1f3d7ffbffffull,0x3f7bfffb8181ull,0x7ff7fffbffffull,0xfeeffff9f1f1ull,0xfcdcf9f1f1f1ull,0xf8b8f0e1e1e1ull,0xf070e0e0e0e0ull,0x70e1f0f030101ull,0xf1d3f7ffbffffull,0x1f3b7ffffbffffull,0x3e77fffffbffffull,0x7ceefffff9f1f1ull,0xf8dcfcf9f1f1f1ull,0xf0b8f8f0e1e1e1ull,0xe070f0e0e0e0e0ull,0x3060f1f0f030101ull,0x70d1f3f7ffb8181ull,0xe1b3f7ffffb8181ull,0x1c367ffffffbe1e1ull,0x386cfefffff9e1e1ull,0x70d8fcfcf9f1e1e1ull,0xe0b0f8f8f0e1e1e1ull,0xc060f0f0e0e0e0e0ull,0x2070f1f0f030101ull,0x50f1f3f7ffb8181ull,0xa1f3f7ffffb8181ull,0x143e7ffffffbc1c1ull,0x287cfefffff9c1c1ull,0x50f8fcfcf9f1c1c1ull,0xa0f0f8f8f0e1c1c1ull,0x40e0f0f0e0e0c0c0ull}, - {0x302ull,0x305ull,0x20aull,0x14ull,0x2028ull,0x6050ull,0xe0a0ull,0xc040ull,0x30203ull,0x30107ull,0xf7ebefull,0xf7e3ffull,0xf7ebfbull,0xe0c0f0ull,0xe0a0e0ull,0xc040c0ull,0x3020303ull,0x3010303ull,0xbf3efefull,0x0ull,0x20e7fbfbull,0xe0c0e0a0ull,0xe0a0e0e0ull,0xc040c0c0ull,0x702030303ull,0x2f15878383ull,0x5fabf7efefull,0xbfd5f7ffffull,0xfdabf7fbfbull,0xfad5f1e1e1ull,0xf0a0e1e1e1ull,0xe040c0c0c0ull,0xf0e07030303ull,0x1f3d1f878383ull,0x3f7bfff7ffffull,0x7ff7fff78181ull,0xfeeffff7ffffull,0xfcdefdf1e1e1ull,0xf8b8f0e1e1e1ull,0xf070e0c0c0c0ull,0x70e0f07030303ull,0xf1d3f1f878383ull,0x1f3b7ffff7ffffull,0x3e77fffff7ffffull,0x7ceefffff7ffffull,0xf8dcfefdf1e1e1ull,0xf0b8f8f0e1e1e1ull,0xe070f0e0c0c0c0ull,0x3060f0f07030101ull,0x70d1f3f1f878181ull,0xe1b3f7ffff78181ull,0x1c367ffffff78181ull,0x386cfefffff7c1c1ull,0x70d8fcfefdf1c1c1ull,0xe0b0f8f8f0e1c1c1ull,0xc060f0f0e0c0c0c0ull,0x2070f0f07030101ull,0x50f1f3f1f878181ull,0xa1f3f7ffff78181ull,0x143e7ffffff78181ull,0x287cfefffff78181ull,0x50f8fcfefdf18181ull,0xa0f0f8f8f0e18181ull,0x40e0f0f0e0c08080ull}, - {0x302ull,0x705ull,0x60aull,0x414ull,0x28ull,0x4050ull,0xc0a0ull,0xc040ull,0x30203ull,0x70507ull,0x7030full,0xefd7dfull,0xeec6feull,0xeed6f6ull,0xc080e0ull,0xc040c0ull,0x3020303ull,0x7050707ull,0x7030705ull,0x4e6dedeull,0x0ull,0xd0cef6f6ull,0xc080c0c0ull,0xc040c0c0ull,0x702030303ull,0xf05878787ull,0x5fab8f8787ull,0xbfd5efdfdfull,0xfdabefffffull,0xfad5eff7f7ull,0xf4a8e1c1c1ull,0xe040c0c0c0ull,0xf0e07030303ull,0x1f1d0f878787ull,0x3f7bbf8f8787ull,0x7ff7ffefffffull,0xfeefffef8181ull,0xfcdeffefffffull,0xf8bcf8e1c1c1ull,0xf070e0c0c0c0ull,0x70e0f07030303ull,0xf1d1f0f878787ull,0x1f3b7fbf8f8787ull,0x3e77ffffefffffull,0x7ceeffffefffffull,0xf8dcfeffefffffull,0xf0b8fcf8e1c1c1ull,0xe070f0e0c0c0c0ull,0x3060f0f07030303ull,0x70d1f1f0f878383ull,0xe1b3f7fbf8f8383ull,0x1c367fffffef8383ull,0x386cfeffffef8181ull,0x70d8fcfeffef8181ull,0xe0b0f8fcf8e18181ull,0xc060f0f0e0c08080ull,0x2070f0f07030101ull,0x50f1f1f0f878181ull,0xa1f3f7fbf8f8181ull,0x143e7fffffef8181ull,0x287cfeffffef8181ull,0x50f8fcfeffef8181ull,0xa0f0f8fcf8e18181ull,0x40e0f0f0e0c08080ull}, - {0x302ull,0x705ull,0xe0aull,0xc14ull,0x828ull,0x50ull,0x80a0ull,0x8040ull,0x70203ull,0x70507ull,0xf0b0full,0xf071full,0xdcacbcull,0xdc8cfcull,0xdcacfcull,0x8000c0ull,0x7060707ull,0x7050707ull,0xf0b0f0dull,0xf070f0bull,0x98ccbcbcull,0x0ull,0xb09cfcfcull,0x80008080ull,0x706070707ull,0xf05878787ull,0x1f8b8f8f8full,0xbfd79f8f8full,0xfdabddbdbdull,0xfa95ddfdfdull,0xf0b0ddfdfdull,0xe850c08080ull,0xf0e07070707ull,0x1f1d0f878787ull,0x3f3b9f8f8f8full,0x7ff7ff9f8f8full,0xfeefffdfffffull,0xfcdeffdf8181ull,0xf8bcfedfffffull,0xf078f0c08080ull,0x70e0f07070707ull,0xf1d1f0f878787ull,0x1f3b3f9f8f8f8full,0x3e77ffff9f8f8full,0x7ceeffffdfffffull,0xf8dcfeffdfffffull,0xf0b8fcfedfffffull,0xe070f8f0c08080ull,0x3060f0f07070707ull,0x70d1f1f0f878787ull,0xe1b3f3f9f8f8787ull,0x1c367fffff9f8787ull,0x386cfeffffdf8787ull,0x70d8fcfeffdf8181ull,0xe0b0f8fcfedf8181ull,0xc060f0f8f0c08080ull,0x2070f0f07070303ull,0x50f1f1f0f878383ull,0xa1f3f3f9f8f8383ull,0x143e7fffff9f8383ull,0x287cfeffffdf8383ull,0x50f8fcfeffdf8181ull,0xa0f0f8fcfedf8181ull,0x40e0f0f8f0c08080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x1828ull,0x1050ull,0xa0ull,0x40ull,0x70603ull,0xf0507ull,0xf0b0full,0x1f171full,0x1f0f3full,0xb8d8f8ull,0xb898f8ull,0xb878f8ull,0x7060707ull,0xf0d0f0full,0xf0b0f0dull,0x1f171f1bull,0x1f0f1f17ull,0xb098f8f8ull,0x0ull,0x1038f8f8ull,0x706070707ull,0xf0d8f8f8full,0x1f8b8f8f8full,0xbf979f9f9full,0xffafbf9f9full,0xfa95b9f9f9ull,0xf030b9f9f9ull,0xf070b8f8f8ull,0xf0e07070707ull,0x1f1d0f8f8f8full,0x3f3b9f8f8f8full,0x7ff7bf9f9f9full,0xfeefffbf9f9full,0xfcdeffbfffffull,0xf8bcfebf8181ull,0xf078fcbefefeull,0x70e0f07070707ull,0xf1d1f0f8f8f8full,0x1f3b3f9f8f8f8full,0x3e77ffbf9f9f9full,0x7ceeffffbf9f9full,0xf8dcfeffbfffffull,0xf0b8fcfebfffffull,0xe070f8fcbefefeull,0x3060f0f07070707ull,0x70d1f1f0f8f8f8full,0xe1b3f3f9f8f8f8full,0x1c367fffbf9f8f8full,0x386cfeffffbf8f8full,0x70d8fcfeffbf8f8full,0xe0b0f8fcfebf8181ull,0xc060f0f8fcbe8080ull,0x2070f0f07070707ull,0x50f1f1f0f8f8787ull,0xa1f3f3f9f8f8787ull,0x143e7fffbf9f8787ull,0x287cfeffffbf8787ull,0x50f8fcfeffbf8787ull,0xa0f0f8fcfebf8181ull,0x40e0f0f8fcbe8080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x3050ull,0x20a0ull,0x4000000000000040ull,0xf0e03ull,0xf0d0full,0x1f0b0full,0x1f171full,0x3fafbfull,0x3f9fffull,0x70b0f0ull,0x7030f0ull,0xf0e0f0full,0xf0d0f0full,0x1f1b1f1dull,0x1f171f1bull,0xbf2fbfb7ull,0xbf1fbfbfull,0x3030f0f0ull,0x0ull,0xf0e0f0f0full,0xf0d0f8f8full,0x1f9b1f9f9full,0xbf971f9f9full,0xffaf3fbfbfull,0xfedf7fbfbfull,0xf03071f1f1ull,0xf07070f0f0ull,0xf0e0f0f0f0full,0x1f1d0f0f8f8full,0x3f3b9f1f9f9full,0x7ff7bf1f9f9full,0xfeefff3fbfbfull,0xfcdeff7fbfbfull,0xf8bcfe7fffffull,0xf078fc7e8080ull,0x70e0f0f0f0f0full,0xf1d1f0f0f8f8full,0x1f3b3f9f1f9f9full,0x3e77ffbf1f9f9full,0x7ceeffff3fbfbfull,0xf8dcfeff7fbfbfull,0xf0b8fcfe7fffffull,0xe070f8fc7efcfcull,0x3060f0f0f0f0f0full,0x70d1f1f0f0f8f8full,0xe1b3f3f9f1f9f9full,0x1c367fffbf1f9f9full,0x386cfeffff3f9f9full,0x70d8fcfeff7f9f9full,0xe0b0f8fcfe7f9f9full,0xc060f0f8fc7e8080ull,0x2070f0f0f0f0f0full,0x50f1f1f0f0f8f8full,0xa1f3f3f9f1f8f8full,0x143e7fffbf1f8f8full,0x287cfeffff3f8f8full,0x50f8fcfeff7f8f8full,0xa0f0f8fcfe7f8f8full,0x40e0f0f8fc7e8080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x203ull,0xfcf5f7ull,0xfcfafeull,0xfcf4fcull,0xf8e8f8ull,0xf8d0f0ull,0xf0b0f0ull,0xf070c0ull,0x1e3c3f3full,0x1e3d3f3full,0xfcf9fffdull,0xfcf5fde9ull,0xf8e8f8d0ull,0xf8d8f8b8ull,0xf0b0f0f0ull,0xf070f0f0ull,0x0ull,0xc1c3f3f3full,0x7df8fdfdfdull,0xfdf4fdfdfdull,0xf8e8f8f8f8ull,0xf8d8f8f8f8ull,0xf0b0f0f0f0ull,0xf070f0f0f0ull,0xf0c1e3f3f3full,0xf0c1e3f3f3full,0x3f7bfefdfdfdull,0x7ff5fcfdfdfdull,0xfce9f8f9f9f9ull,0xf8d8f8f9f9f9ull,0xf0b0f0f0f0f0ull,0xf070f0f0f0f0ull,0x2070e1f3e010101ull,0xf1d3f7efffdfdull,0x1f3b7ffefdfdfdull,0x3e77fffcfdfdfdull,0x7cecfdf8f9f9f9ull,0xf8d8f8f8f9f9f9ull,0xf0b0f0f0f0f0f0ull,0xe070f0f0f0f0f0ull,0x3060f1f3e3f0101ull,0x70d1f3f7efff9f9ull,0xe1b3f7ffefdf9f9ull,0x1c367ffffcfdf9f9ull,0x386cfcfdf8f9f9f9ull,0x70d8f8f8f8f9f9f9ull,0xe0b0f0f0f0f0f0f0ull,0xc060f0f0f0f0f0f0ull,0x207071f3e010101ull,0x50f1f3f7ef9f1f1ull,0xa1f3f7ffef9f1f1ull,0x143e7ffffcf9f1f1ull,0x287cfcfdf8f9f1f1ull,0x50f8f8f8f8f9f1f1ull,0xa0f0f0f0f0f0f0f0ull,0x40e0f0f0f0f0f0f0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x203ull,0x507ull,0xf8eaeeull,0xf8f4fcull,0xf8e8f8ull,0xf0d0f0ull,0xf0a0e0ull,0xe060c0ull,0x3d7e7f7full,0x3d797f7full,0x3d7b7f7full,0xf8f0fce8ull,0xf8e8f8d0ull,0xf0d0f0b0ull,0xf0b0f0f0ull,0xe060e0e0ull,0x83c7f7f7full,0x0ull,0xd397f7f7full,0xf8f0f8f8f8ull,0xf8e8f8f8f8ull,0xf0d0f0f0f0ull,0xf0b0f0f0f0ull,0xe060e0e0e0ull,0xf0c3d7f7f7full,0xf083d7f7f7full,0x1f29bdffffffull,0x7ff5fdf9f9f9ull,0xfce9f9f9f9f9ull,0xf8d0f1f1f1f1ull,0xf0b0f0f0f0f0ull,0xe060e0e0e0e0ull,0x2070e1f3d7f0101ull,0xf1d3f7d818181ull,0x1f3b7ffdfff9f9ull,0x3e77fffdf9f9f9ull,0x7cecfdf9f9f9f9ull,0xf8d8f8f1f1f1f1ull,0xf0b0f0f0f0f0f0ull,0xe060e0e0e0e0e0ull,0x3060f1f3d7f0101ull,0x70d1f3f7dff8181ull,0xe1b3f7ffdfff1f1ull,0x1c367ffffdf9f1f1ull,0x386cfcfdf9f9f1f1ull,0x70d8f8f8f1f1f1f1ull,0xe0b0f0f0f0f0f0f0ull,0xc060e0e0e0e0e0e0ull,0x207070f3d010101ull,0x50f0f3f7d818181ull,0xa1f3f7ffdf1e1e1ull,0x143e7ffffdf1e1e1ull,0x287cfcfdf9f1e1e1ull,0x50f8f8f8f1f1e1e1ull,0xa0f0f0f0f0f0e0e0ull,0x40e0e0e0e0e0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x10203ull,0x10507ull,0xa0eull,0xf0d4dcull,0xf0e8f8ull,0xf0d0f0ull,0xe0a0e0ull,0xe040c0ull,0x1000303ull,0x7bfdffffull,0x7bf1ffffull,0x7bf5ffffull,0xf0e0f8d0ull,0xf0d0f0b0ull,0xe0a0e0e0ull,0xe060e0e0ull,0x100010101ull,0x579ffffffull,0x0ull,0x1973fdffffull,0xf0e0f0f0f0ull,0xf0d0f0f0f0ull,0xe0a0e0e0e0ull,0xe060e0e0e0ull,0x70a03010101ull,0xf097bffffffull,0x1f29fbffffffull,0x3fd5fbfdffffull,0xfcebf9f1f1f1ull,0xf8d0f1f1f1f1ull,0xf0a0e0e0e0e0ull,0xe060e0e0e0e0ull,0x7060f03010101ull,0xf1d3f7bff8181ull,0x1f3b7ffb818181ull,0x3e77fffbfff1f1ull,0x7cecfff9f1f1f1ull,0xf8d8f8f1f1f1f1ull,0xf0b0f0e0e0e0e0ull,0xe060e0e0e0e0e0ull,0x306070f03010101ull,0x70d1f3f7bff8181ull,0xe1b3f7ffbff8181ull,0x1c367ffffbffe1e1ull,0x386cfcfff9f1e1e1ull,0x70d8f8f8f1f1e1e1ull,0xe0b0f0f0e0e0e0e0ull,0xc060e0e0e0e0e0e0ull,0x207070f03010101ull,0x50f0f1f7b818181ull,0xa1f1f7ffb818181ull,0x143e7ffffbe1c1c1ull,0x287cfcfff9e1c1c1ull,0x50f8f8f8f1e1c1c1ull,0xa0f0f0f0e0e0c0c0ull,0x40e0e0e0e0e0c0c0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x30203ull,0x30507ull,0x30a0eull,0x141cull,0xe0a8b8ull,0xe0d0f0ull,0xe0a0e0ull,0xc040c0ull,0x3020303ull,0x3010707ull,0xf7ebffffull,0xf7e3ffffull,0xf6ebffffull,0xe0c0f0b0ull,0xe0a0e0e0ull,0xc040c0c0ull,0x302030303ull,0x301030303ull,0xbf3efffffull,0x0ull,0x20e6fbffffull,0xe0c0e0e0e0ull,0xe0a0e0e0e0ull,0xc040c0c0c0ull,0x70203030303ull,0xf1507030303ull,0x1f2bf7efffffull,0x3fd5f7ffffffull,0xfcabf7fbffffull,0xf8d4f1e1e1e1ull,0xf0a0e0e0e0e0ull,0xe040c0c0c0c0ull,0x7060703030303ull,0xf0d1f07030303ull,0x1f3b7ff7ff8383ull,0x3e77fff7818181ull,0x7ceefff7ffe1e1ull,0xf8d8fcf1e1e1e1ull,0xf0b0f0e0e0e0e0ull,0xe060e0c0c0c0c0ull,0x306070703030101ull,0x70d0f1f07030101ull,0xe1b3f7ff7ff8181ull,0x1c367ffff7ff8181ull,0x386cfefff7ffc1c1ull,0x70d8f8fcf1e1c1c1ull,0xe0b0f0f0e0e0c0c0ull,0xc060e0e0c0c0c0c0ull,0x207070703010101ull,0x50f0f1f07010101ull,0xa1f1f3ff7818181ull,0x143e3ffff7818181ull,0x287cfcfff7c18181ull,0x50f8f8fcf1c18181ull,0xa0f0f0f0e0c08080ull,0x40e0e0e0c0c08080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x30203ull,0x70507ull,0x70b0full,0x7151dull,0x2838ull,0xc05070ull,0xc0a0e0ull,0xc040c0ull,0x3020303ull,0x7050707ull,0x7030f0dull,0xefd7ffffull,0xecc6fefeull,0xecd6fefeull,0xc080e0e0ull,0xc040c0c0ull,0x302030303ull,0x705070707ull,0x703070707ull,0x4e4defefeull,0x0ull,0xd0ccf6fefeull,0xc080c0c0c0ull,0xc040c0c0c0ull,0x70203030303ull,0xf0507070707ull,0x1f2b8f878787ull,0x3fd5efdfffffull,0xfcabedffffffull,0xf8d4edf7ffffull,0xf0a8e0c0c0c0ull,0xe040c0c0c0c0ull,0x7060703030303ull,0xf0d0f07070707ull,0x1f1b3f8f878787ull,0x3e77ffefff8787ull,0x7ceeffef818181ull,0xf8dcfeefffc1c1ull,0xf0b0f8e0c0c0c0ull,0xe060e0c0c0c0c0ull,0x306070703030303ull,0x70d0f0f07070303ull,0xe1b1f3f8f878383ull,0x1c367fffefff8383ull,0x386cfeffefff8181ull,0x70d8fcfeefff8181ull,0xe0b0f0f8e0c08080ull,0xc060e0e0c0c08080ull,0x207070703030101ull,0x50f0f0f07030101ull,0xa1f1f3f8f838181ull,0x143e3fffef838181ull,0x287cfcffef818181ull,0x50f8f8fcef818181ull,0xa0f0f0f8e0808080ull,0x40e0e0e0c0808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70203ull,0x70507ull,0xf0b0full,0xf171full,0xf2b3bull,0x5070ull,0x80a0e0ull,0x8040c0ull,0x7060707ull,0x7050707ull,0xf0b0f0dull,0xf071f0bull,0xd8acfcfcull,0xd88cfcfcull,0xd8bcfcfcull,0x8000c0c0ull,0x706070707ull,0x705070707ull,0xf0b0f0f0full,0xf070f0f0full,0x98c8bcfcfcull,0x0ull,0xa098fcfcfcull,0x8000808080ull,0x70607070707ull,0xf0507070707ull,0x1f0b8f8f8f8full,0x3fd79f8f8f8full,0xfcabd9bdfdfdull,0xf894d9fdfdfdull,0xf090d8fcfcfcull,0xe050c0808080ull,0x7060707070707ull,0xf0d0f07070707ull,0x1f1b1f8f8f8f8full,0x3e37ff9f8f8f8full,0x7ceeffdfff8f8full,0xf8dcfedf818181ull,0xf0b8fcdeff8181ull,0xe060f0c0808080ull,0x306070707070707ull,0x70d0f0f07070707ull,0xe1b1f1f8f8f8787ull,0x1c363fff9f8f8787ull,0x386cfeffdfff8787ull,0x70d8fcfedfff8181ull,0xe0b0f8fcdeff8181ull,0xc060e0f0c0808080ull,0x207070707070303ull,0x50f0f0f07070303ull,0xa1f1f1f8f878383ull,0x143e3fff9f878383ull,0x287cfeffdf878383ull,0x50f8f8fedf818181ull,0xa0f0f0f8de818181ull,0x40e0e0f0c0808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70603ull,0xf0507ull,0xf0b0full,0x1f171full,0x1f2f3full,0x1f5777ull,0xa0e0ull,0x40c0ull,0x7060707ull,0xf0d0f0full,0xf0b0f0dull,0x1f171f0bull,0x1f0f3f17ull,0xb0d8f8f8ull,0xb098f8f8ull,0xb078f8f8ull,0x706070707ull,0xf0d0f0f0full,0xf0b0f0f0full,0x1f171f1f1full,0x1f0f1f1f1full,0xb090f8f8f8ull,0x0ull,0x1030f8f8f8ull,0x70607070707ull,0xf0d0f0f0f0full,0x1f0b8f8f8f8full,0x3f979f9f9f9full,0xfeafbf9f9f9full,0xf894b1f9f9f9ull,0xf010b0f8f8f8ull,0xf030b0f8f8f8ull,0x7060707070707ull,0xf0d0f0f0f0f0full,0x1f1b1f8f8f8f8full,0x3e37bf9f9f9f9full,0x7ceeffbf9f9f9full,0xf8dcfebfff9f9full,0xf0b8fcbe818181ull,0x40e070f8bcfe8080ull,0x306070707070707ull,0x70d0f0f0f0f0f0full,0xe1b1f1f8f8f8f8full,0x1c363fbf9f9f8f8full,0x386cfeffbf9f8f8full,0x70d8fcfebfff8f8full,0xe0b0f8fcbeff8181ull,0xc060f0f8bcfe8080ull,0x207070707070707ull,0x50f0f0f0f0f0707ull,0xa1f1f1f8f8f8787ull,0x143e3fbf9f8f8787ull,0x287cfeffbf8f8787ull,0x50f8fcfebf8f8787ull,0xa0f0f0fcbe818181ull,0x40e0e0f0bc808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0xf0d0full,0x1f0b0full,0x1f171full,0x3f2f3full,0x3f5f7full,0x3fafefull,0x40c0ull,0xf0e0f0full,0xf0d0f0full,0x1f1b1f1dull,0x1f171f0bull,0x3fafbf97ull,0x3f9fffbfull,0x70b0f0f0ull,0x6030f0f0ull,0xf0e0f0f0full,0xf0d0f0f0full,0x1f1b1f1f1full,0x1f171f1f1full,0xbf2fbfbfbfull,0xbe1fbfbfbfull,0x3030f0f0f0ull,0x0ull,0xf0e0f0f0f0full,0xf0d0f0f0f0full,0x1f1b1f9f9f9full,0x3f971f9f9f9full,0xfeaf3fbfbfbfull,0xfcde7fbfbfbfull,0xf03070f0f0f0ull,0xf03060f0f0f0ull,0x70e0f0f0f0f0full,0xf0d0f0f0f0f0full,0x1f1b1f1f9f9f9full,0x3e37bf1f9f9f9full,0x7ceeff3fbfbfbfull,0xf8dcfe7fbfbfbfull,0xf0b8fc7effbfbfull,0x40e070f87c808080ull,0x3060f0f0f0f0f0full,0x70d0f0f0f0f0f0full,0xe1b1f1f1f9f9f9full,0x1c363fbf1f9f9f9full,0x386cfeff3fbf9f9full,0x70d8fcfe7fbf9f9full,0xe0b0f8fc7eff9f9full,0xc060f0f87cfc8080ull,0x2070f0f0f0f0f0full,0x50f0f0f0f0f0f0full,0xa1f1f1f1f9f8f8full,0x143e3fbf1f9f8f8full,0x287cfeff3f9f8f8full,0x50f8fcfe7f9f8f8full,0xa0f0f8fc7e9f8f8full,0x40e0e0f87c808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x7f0203ull,0xfff5f7ull,0xfefafeull,0xfcf4fcull,0xf8e8f8ull,0xf8d0f0ull,0xf0b0f0ull,0xf070c0ull,0x7e0303ull,0x7cfdffffull,0xfcfbfffdull,0xfcf5fde9ull,0xf8e8f8d0ull,0xf8d8f8b8ull,0xf0b0f0f0ull,0xf070f0f0ull,0x61c3f3f3full,0xe1d3f3f3full,0x7cf9ffffffull,0xfcf5fdfdfdull,0xf8e8f8f8f8ull,0xf8d8f8f8f8ull,0xf0b0f0f0f0ull,0xf070f0f0f0ull,0x0ull,0xc0c1f3f3f3full,0x3d78fdfdfdfdull,0x7df4fdfdfdfdull,0xf8e8f8f8f8f8ull,0xf8d8f8f8f8f8ull,0xf0b0f0f0f0f0ull,0xf070f0f0f0f0ull,0x704061f3f3f3full,0xf0c0e1f3f3f3full,0x1f3b7efdfdfdfdull,0x3e75fcfdfdfdfdull,0x7ce8f8f9f9f9f9ull,0xf8d8f8f8f8f8f8ull,0xf0b0f0f0f0f0f0ull,0xe070f0f0f0f0f0ull,0x706031e01010101ull,0x70d1f3e7ffdf9f9ull,0xe1b3f7efdfdf9f9ull,0x1c367dfcfdfdf9f9ull,0x386cf8f8f9f9f9f9ull,0x70d8f8f8f8f8f8f8ull,0xe0b0f0f0f0f0f0f0ull,0xc060f0f0f0f0f0f0ull,0x207031e1f010101ull,0x50f1f3e7ff9f1f1ull,0xa1f3f7efdf9f1f1ull,0x143e7dfcfdf9f1f1ull,0x287cf8f8f9f9f1f1ull,0x50f8f8f8f8f8f0f0ull,0xa0f0f0f0f0f0f0f0ull,0x40e0f0f0f0f0f0f0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x30203ull,0xff0507ull,0xfeeaeeull,0xfcf4fcull,0xf8e8f8ull,0xf0d0f0ull,0xf0a0e0ull,0xe060c0ull,0x20303ull,0xfd0707ull,0xf8fafefcull,0xf8f4fce8ull,0xf8e8f8d0ull,0xf0d0f0b0ull,0xf0b0f0f0ull,0xe060e0e0ull,0x1d3e7f7f7full,0x1d397f7f7full,0x1d3b7f7f7full,0xf8f0fcfcfcull,0xf8e8f8f8f8ull,0xf0d0f0f0f0ull,0xf0b0f0f0f0ull,0xe060e0e0e0ull,0x81c3f7f7f7full,0x0ull,0xd193f7f7f7full,0x78f0f8f8f8f8ull,0xf8e8f8f8f8f8ull,0xf0d0f0f0f0f0ull,0xf0b0f0f0f0f0ull,0xe060e0e0e0e0ull,0x7041d3f7f7f7full,0xf081d3f7f7f7full,0x1f091d3f7f7f7full,0x3e75fdf9f9f9f9ull,0x7ce8f9f9f9f9f9ull,0xf8d0f0f0f0f0f0ull,0xf0b0f0f0f0f0f0ull,0xe060e0e0e0e0e0ull,0x70603053f010101ull,0x70d073d01818181ull,0xe1b3f7dfff9f1f1ull,0x1c367dfdf9f9f1f1ull,0x386cf8f9f9f9f1f1ull,0x70d8f0f0f0f0f0f0ull,0xe0b0f0f0f0f0f0f0ull,0xc060e0e0e0e0e0e0ull,0x20703053f010101ull,0x50f073d3f818181ull,0xa1f3f7dfff1e1e1ull,0x143e7dfdf9f1e1e1ull,0x287cf8f9f9f1e1e1ull,0x50f8f0f0f0f0e0e0ull,0xa0f0f0f0f0f0e0e0ull,0x40e0e0e0e0e0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x30203ull,0x70507ull,0xff0a0eull,0xfcd4dcull,0xf8e8f8ull,0xf0d0f0ull,0xe0a0e0ull,0xe040c0ull,0x1020303ull,0x1050707ull,0xfb0e0cull,0xf0f4fce8ull,0xf0e8f8d0ull,0xf0d0f0b0ull,0xe0a0e0e0ull,0xe060e0e0ull,0x100030303ull,0x3b7dffffffull,0x3b71ffffffull,0x3b75ffffffull,0xf0e0f8f8f8ull,0xf0d0f0f0f0ull,0xe0a0e0e0e0ull,0xe060e0e0e0ull,0x10001010101ull,0x5397fffffffull,0x0ull,0x19337dffffffull,0xf0e0f0f0f0f0ull,0xf0d0f0f0f0f0ull,0xe0a0e0e0e0e0ull,0xe060e0e0e0e0ull,0x7020301010101ull,0xf093b7fffffffull,0x1f093b7fffffffull,0x3e15bbfdffffffull,0x7ce8f9f1f1f1f1ull,0xf8d0f0f0f0f0f0ull,0xf0a0e0e0e0e0e0ull,0xe060e0e0e0e0e0ull,0x706030301010101ull,0x70d070b7f818181ull,0xe1b0f7b81818181ull,0x1c367dfbfff1e1e1ull,0x386cf8f9f1f1e1e1ull,0x70d8f0f0f0f0e0e0ull,0xe0b0e0e0e0e0e0e0ull,0xc060e0e0e0e0e0e0ull,0x207030301010101ull,0x50f070b7f818181ull,0xa1f0f7bff818181ull,0x143e7dfbffe1c1c1ull,0x287cf8f9f1e1c1c1ull,0x50f8f0f0f0e0c0c0ull,0xa0f0e0e0e0e0c0c0ull,0x40e0e0e0e0e0c0c0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x30203ull,0x70507ull,0xf0a0eull,0xff141cull,0xf8a8b8ull,0xf0d0f0ull,0xe0a0e0ull,0xc040c0ull,0x3020303ull,0x3050707ull,0x30b0f0dull,0xf71c08ull,0xe0e8f8d0ull,0xe0d0f0b0ull,0xe0a0e0e0ull,0xc040c0c0ull,0x302030303ull,0x301070707ull,0x77ebffffffull,0x77e3ffffffull,0xf4eaffffffull,0xe0c0f0f0f0ull,0xe0a0e0e0e0ull,0xc040c0c0c0ull,0x30203030303ull,0x30103030303ull,0xb73efffffffull,0x0ull,0x2064faffffffull,0xe0c0e0e0e0e0ull,0xe0a0e0e0e0e0ull,0xc040c0c0c0c0ull,0x7020303030303ull,0xf050703030303ull,0x1f0b77efffffffull,0x3e15f7ffffffffull,0x7ca8f5fbffffffull,0xf8d0f0e0e0e0e0ull,0xf0a0e0e0e0e0e0ull,0xe040c0c0c0c0c0ull,0x306030303030101ull,0x70d070703030101ull,0xe1b0f17ff838181ull,0x1c361df781818181ull,0x386cf8f5ffe1c1c1ull,0x70d8f0f0e0e0c0c0ull,0xe0b0e0e0e0e0c0c0ull,0xc060c0c0c0c0c0c0ull,0x207030303010101ull,0x50f070703010101ull,0xa1f0f17ff818181ull,0x143e1df7ff818181ull,0x287cf8f5ffc18181ull,0x50f8f0f0e0c08080ull,0xa0f0e0e0e0c08080ull,0x40e0c0c0c0c08080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x30203ull,0x70507ull,0xf0b0full,0x1f151dull,0xff2838ull,0xf05070ull,0xe0a0e0ull,0xc040c0ull,0x3020303ull,0x7050707ull,0x70b0f0dull,0x7171f0bull,0xef3810ull,0xc0d0f0b0ull,0xc0a0e0e0ull,0xc040c0c0ull,0x302030303ull,0x705070707ull,0x7030f0f0full,0xefd5ffffffull,0xe8c4fefefeull,0xe8d4fefefeull,0xc080e0e0e0ull,0xc040c0c0c0ull,0x30203030303ull,0x70507070707ull,0x70307070707ull,0x4e4dcfefefeull,0x0ull,0xd0c8f4fefefeull,0xc080c0c0c0c0ull,0xc040c0c0c0c0ull,0x7020303030303ull,0xf050707070707ull,0x1f0b0f07070707ull,0x3e15efddffffffull,0x7ca8e9fdffffffull,0xf8d0e8f4fefefeull,0xf0a0e0c0c0c0c0ull,0xe040c0c0c0c0c0ull,0x306030303030303ull,0x70d070707070303ull,0xe1b0f0f07070303ull,0x1c361fafff878383ull,0x386cb8ef81818181ull,0x70d8f0e8ffc18181ull,0xe0b0e0e0c0c08080ull,0xc060c0c0c0c08080ull,0x207030303030101ull,0x50f070707030101ull,0xa1f0f0f07030101ull,0x143e1fafff838181ull,0x287cb8efff818181ull,0x50f8f0e8ff818181ull,0xa0f0e0e0c0808080ull,0x40e0c0c0c0808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70203ull,0x70507ull,0xf0b0full,0x1f171full,0x3f2b3bull,0xff5070ull,0xe0a0e0ull,0xc040c0ull,0x7060707ull,0x7050707ull,0xf0b0f0dull,0xf171f0bull,0xf2f3f17ull,0xdf7030ull,0x80a0e0e0ull,0x8040c0c0ull,0x706070707ull,0x705070707ull,0xf0b0f0f0full,0xf071f1f1full,0xd8a8fcfcfcull,0xd088fcfcfcull,0xd0b8fcfcfcull,0x8000c0c0c0ull,0x70607070707ull,0x70507070707ull,0xf0b0f0f0f0full,0xf070f0f0f0full,0x98c8b8fcfcfcull,0x0ull,0xa090f8fcfcfcull,0x800080808080ull,0x7060707070707ull,0xf050707070707ull,0x1f0b0f0f0f0f0full,0x3e179f8f8f8f8full,0x7ca8d9b9fdfdfdull,0xf890d0f8fcfcfcull,0xf090d0f8fcfcfcull,0xe040c080808080ull,0x306070707070707ull,0x70d070707070707ull,0xe1b0f0f0f0f0707ull,0x1c361f9f8f8f8787ull,0x386cbedfff8f8787ull,0x70d8f0de81818181ull,0xe0b0e0d0fe818181ull,0xe060c0c080808080ull,0x207070707070303ull,0x50f070707070303ull,0xa1f0f0f0f070303ull,0x143e1f9f8f878383ull,0x287cbedfff878383ull,0x50f8f0deff818181ull,0xa0f0e0d0fe818181ull,0x40e0c0c080808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70603ull,0xf0507ull,0xf0b0full,0x1f171full,0x3f2f3full,0x7f5777ull,0xffa0e0ull,0xc040c0ull,0x7060707ull,0xf0d0f0full,0xf0b0f0dull,0x1f171f0bull,0x1f2f3f17ull,0x1f5f7f3full,0xbfe0e0ull,0x40c0c0ull,0x706070707ull,0xf0d0f0f0full,0xf0b0f0f0full,0x1f171f1f1full,0x1f0f3f3f3full,0xb0d0f8f8f8ull,0xb090f8f8f8ull,0xb070f8f8f8ull,0x70607070707ull,0xf0d0f0f0f0full,0xf0b0f0f0f0full,0x1f171f1f1f1full,0x1e0f1f1f1f1full,0xb090f0f8f8f8ull,0x0ull,0x1030f0f8f8f8ull,0x7060707070707ull,0xf0d0f0f0f0f0full,0x1f0b0f0f0f0f0full,0x3e179f9f9f9f9full,0x7caebf9f9f9f9full,0xf890b0f0f8f8f8ull,0xf010b0f0f8f8f8ull,0xe020b0f0f8f8f8ull,0x306070707070707ull,0x70d0f0f0f0f0f0full,0xe1b0f0f0f0f0f0full,0x1c361f9f9f9f8f8full,0x386cbebf9f9f8f8full,0x70d8fcbeff9f8f8full,0xe0b0e0bc80818181ull,0xe060c0a0fc808080ull,0x207070707070707ull,0x50f0f0f0f0f0707ull,0xa1f0f0f0f0f0707ull,0x143e1f9f9f8f8787ull,0x287cbebf9f8f8787ull,0x50f8fcbeff8f8787ull,0xa0f0e0bcfc818181ull,0x40e0c0a0fc808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0xf0d0full,0x1f0b0full,0x1f171full,0x3f2f3full,0x7f5f7full,0xffafefull,0xfe40c0ull,0xf0e0f0full,0xf0d0f0full,0x1f1b1f1dull,0x1f171f0bull,0x3fafbf97ull,0x3fdfffbfull,0x3ebfffffull,0x7ec0c0ull,0xf0e0f0f0full,0xf0d0f0f0full,0x1f1b1f1f1full,0x1f171f1f1full,0x3fafbfbfbfull,0x3e9fffffffull,0x70b0f0f0f0ull,0x6020f0f0f0ull,0xf0e0f0f0f0full,0xf0d0f0f0f0full,0x1f1b1f1f1f1full,0x1f171f1f1f1full,0xbe2fbfbfbfbfull,0xbc1ebfbfbfbfull,0x3030f0f0f0f0ull,0x0ull,0x70e0f0f0f0f0full,0xf0d0f0f0f0f0full,0x1f1b1f1f1f1f1full,0x3e171f9f9f9f9full,0x7cae3fbfbfbfbfull,0xf8dc7ebfbfbfbfull,0xf03070f0f0f0f0ull,0xe02060e0f0f0f0ull,0x3060f0f0f0f0f0full,0x70d0f0f0f0f0f0full,0xe1b1f1f1f1f1f1full,0x1c361f1f9f9f9f9full,0x386cbe3fbfbf9f9full,0x70d8fc7ebfbf9f9full,0xe0b0f87cfebf9f9full,0xe060c07880808080ull,0x2070f0f0f0f0f0full,0x50f0f0f0f0f0f0full,0xa1f1f1f1f1f0f0full,0x143e1f1f9f9f8f8full,0x287cbe3fbf9f8f8full,0x50f8fc7ebf9f8f8full,0xa0f0f87cfe9f8f8full,0x40e0c078f8808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x7f0203ull,0xfff5f7ull,0xfffafeull,0xfef4fcull,0xfce8f8ull,0xf8d0f0ull,0xf0b0f0ull,0xf070c0ull,0x3f7e7f7full,0x7ffdffffull,0xfefbfffdull,0xfcf7ffebull,0xf8ecfcd4ull,0xf8d8f8b8ull,0xf0b0f0f0ull,0xf070f0f0ull,0x3e7f7f7full,0x3c7dffffffull,0x7cfbffffffull,0xfcf5ffffffull,0xf8e8fcfcfcull,0xf8d8f8f8f8ull,0xf0b0f0f0f0ull,0xf070f0f0f0ull,0x40c1f3f3f3full,0xc0d1f3f3f3full,0x3c79ffffffffull,0x7cf5fdfdffffull,0xf8e8f8f8fcfcull,0xf8d8f8f8f8f8ull,0xf0b0f0f0f0f0ull,0xf070f0f0f0f0ull,0x0ull,0xc0c0f1f3f3f3full,0x1c387dfdfdfdfdull,0x3c74fdfdfdfdfdull,0x78e8f8f8f8f8f8ull,0xf8d8f8f8f8f8f8ull,0xf0b0f0f0f0f0f0ull,0xe070f0f0f0f0f0ull,0x304060f1f3f3f3full,0x70c0e0f1f3f3f3full,0xe1a3c7dfdfdfdfdull,0x1c347cfdfdfdfdfdull,0x3868f8f8f8f8f8f8ull,0x70d8f8f8f8f8f8f8ull,0xe0b0f0f0f0f0f0f0ull,0xc060f0f0f0f0f0f0ull,0x207000101010101ull,0x50d1e3d7df9f1f1ull,0xa1e3c7dfdf9f1f1ull,0x143c7cfdfdf9f1f1ull,0x2878f8f8f8f8f0f0ull,0x50f8f8f8f8f8f0f0ull,0xa0f0f0f0f0f0f0f0ull,0x40e0f0f0f0f0f0f0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70203ull,0xff0507ull,0xffeaeeull,0xfef4fcull,0xfce8f8ull,0xf8d0f0ull,0xf0a0e0ull,0xe060c0ull,0x37e7f7full,0x7ffdffffull,0xfefbfffdull,0xfcf6feeaull,0xf8ecfcd4ull,0xf0d8f8b8ull,0xf0b0f0f0ull,0xe060e0e0ull,0x27f7f7full,0x7dffffffull,0x78faffffffull,0xf8f4fefefeull,0xf8e8fcfcfcull,0xf0d0f8f8f8ull,0xf0b0f0f0f0ull,0xe060e0e0e0ull,0xd1e3f7f7f7full,0xd193f7f7f7full,0xd1b3f7f7f7full,0x78f0fcfcfefeull,0xf8e8f8f8fcfcull,0xf0d0f0f0f8f8ull,0xf0b0f0f0f0f0ull,0xe060e0e0e0e0ull,0x80c1f3f7f7f7full,0x0ull,0xc091f3f7f7f7full,0x3870f8f8f8f8f8ull,0x78e8f8f8f8f8f8ull,0xf0d0f0f0f0f0f0ull,0xf0b0f0f0f0f0f0ull,0xe060e0e0e0e0e0ull,0x3040d1f3f7f7f7full,0x7080d1f3f7f7f7full,0xe090d1f3f7f7f7full,0x1c3478f9f9f9f9f9ull,0x3868f8f8f8f8f8f8ull,0x70d0f0f0f0f0f0f0ull,0xe0b0f0f0f0f0f0f0ull,0xc060e0e0e0e0e0e0ull,0x205050101010101ull,0x507010101818181ull,0xa183d79f9f1e1e1ull,0x143c78f9f9f1e1e1ull,0x2878f8f8f8f0e0e0ull,0x50f0f0f0f0f0e0e0ull,0xa0f0f0f0f0f0e0e0ull,0x40e0e0e0e0e0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70203ull,0xf0507ull,0xff0a0eull,0xfed4dcull,0xfce8f8ull,0xf8d0f0ull,0xf0a0e0ull,0xe040c0ull,0x3060707ull,0x7fdffffull,0xfffbfffdull,0xfcf7ffebull,0xf8ecfcd4ull,0xf0d8f8b8ull,0xe0b0f0f0ull,0xe060e0e0ull,0x102070707ull,0x105ffffffull,0xfbffffffull,0xf0f4ffffffull,0xf0e8fcfcfcull,0xf0d0f8f8f8ull,0xe0a0f0f0f0ull,0xe060e0e0e0ull,0x10003030707ull,0x193d7fffffffull,0x19317fffffffull,0x1b357fffffffull,0xf0e0f8f8fcfcull,0xf0d0f0f0f8f8ull,0xe0a0e0e0f0f0ull,0xe060e0e0e0e0ull,0x1000101010101ull,0x5193f7fffffffull,0x0ull,0x18113d7fffffffull,0x70e0f0f0f0f0f0ull,0xf0d0f0f0f0f0f0ull,0xe0a0e0e0e0e0e0ull,0xe060e0e0e0e0e0ull,0x702030101010101ull,0x7091b3f7fffffffull,0xe01193f7fffffffull,0x1c141b3d7fffffffull,0x3868f0f0f0f0f0f0ull,0x70d0f0f0f0f0f0f0ull,0xe0a0e0e0e0e0e0e0ull,0xc060e0e0e0e0e0e0ull,0x203010101010101ull,0x5010b0101818181ull,0xa0e010181818181ull,0x14307af1f1e1c1c1ull,0x2878f0f0f0e0c0c0ull,0x50f0f0f0f0e0c0c0ull,0xa0e0e0e0e0e0c0c0ull,0x40e0e0e0e0e0c0c0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70203ull,0xf0507ull,0x1f0a0eull,0xff141cull,0xfca8b8ull,0xf8d0f0ull,0xf0a0e0ull,0xe040c0ull,0x3060707ull,0x70d0f0full,0xffbfffdull,0xfff7ffebull,0xf8efffd7ull,0xf0d8f8b8ull,0xe0b0f0f0ull,0xc060e0e0ull,0x302070707ull,0x3050f0f0full,0x30bffffffull,0xf7ffffffull,0xe0e8ffffffull,0xe0d0f8f8f8ull,0xe0a0f0f0f0ull,0xc040e0e0e0ull,0x30203030707ull,0x30107070f0full,0x336bffffffffull,0x3361fdffffffull,0xf0e8fcffffffull,0xe0c0f0f0f8f8ull,0xe0a0e0e0f0f0ull,0xc040c0c0e0e0ull,0x3020303030303ull,0x3010303030303ull,0xa336ffdffffffull,0x0ull,0x202078fcffffffull,0xe0c0e0e0e0e0e0ull,0xe0a0e0e0e0e0e0ull,0xc040c0c0c0c0c0ull,0x302030303030303ull,0x705030303030303ull,0xe03376fffffffffull,0x1c14337dfdffffffull,0x3828f0f8fcffffffull,0x70d0e0e0e0e0e0e0ull,0xe0a0e0e0e0e0e0e0ull,0xc040c0c0c0c0c0c0ull,0x203030303010101ull,0x507030303010101ull,0xa03170383818181ull,0x141c018181818181ull,0x2860f4e1e1c18181ull,0x50f0e0e0e0c08080ull,0xa0e0e0e0e0c08080ull,0x40c0c0c0c0c08080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70203ull,0xf0507ull,0x1f0b0full,0x3f151dull,0xff2838ull,0xf85070ull,0xf0a0e0ull,0xe040c0ull,0x3060707ull,0x70d0f0full,0xf1b1f1dull,0x1ff7ffebull,0xffefffd7ull,0xf0dfffbfull,0xe0b0f0f0ull,0xc060e0e0ull,0x302070707ull,0x7050f0f0full,0x70b1f1f1full,0x717ffffffull,0xefffffffull,0xc0d0ffffffull,0xc0a0f0f0f0ull,0xc040e0e0e0ull,0x30203030707ull,0x70507070f0full,0x7030f0f1f1full,0x6fd5fdfdffffull,0xe8c0f8fcfefeull,0xe8d0f8fcfefeull,0xc080e0e0f0f0ull,0xc040c0c0e0e0ull,0x3020303030303ull,0x7050707070707ull,0x7030707070707ull,0x464dcf8fcfefeull,0x0ull,0x50c8f0f8fcfefeull,0xc080c0c0c0c0c0ull,0xc040c0c0c0c0c0ull,0x302030303030303ull,0x705070707070707ull,0xe0b070707070707ull,0x1c146fddfdfdffffull,0x3828e8f8f8fcfefeull,0x70c0e8f0f8fcfefeull,0xe0a0c0c0c0c0c0c0ull,0xc040c0c0c0c0c0c0ull,0x203030303030101ull,0x507070707030101ull,0xa0f070707030101ull,0x14062f8787838181ull,0x2838808181818181ull,0x50c0e8c0c1818181ull,0xa0e0c0c0c0808080ull,0x40c0c0c0c0808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70203ull,0xf0507ull,0x1f0b0full,0x3f171full,0x7f2b3bull,0xff5070ull,0xf0a0e0ull,0xe040c0ull,0x7060707ull,0x70d0f0full,0xf1b1f1dull,0x1f373f2bull,0x3fefffd7ull,0xffdfffbfull,0xe0bfffffull,0xc060e0e0ull,0x706070707ull,0x7050f0f0full,0xf0b1f1f1full,0xf173f3f3full,0xf2fffffffull,0xdfffffffull,0x80a0ffffffull,0x8040e0e0e0ull,0x70607070707ull,0x70507070f0full,0xf0b0f0f1f1full,0xf071f1f3f3full,0xd8a8f8f8fcfcull,0xd080f0f8fcfcull,0xd0b0f0f8fcfcull,0x8000c0c0e0e0ull,0x7060707070707ull,0x7050707070707ull,0xf0b0f0f0f0f0full,0xe070f0f0f0f0full,0x18c8b8f0f8fcfcull,0x0ull,0xa090f0f0f8fcfcull,0x80008080808080ull,0x306070707070707ull,0x705070707070707ull,0xe0b0f0f0f0f0f0full,0x1c160f0f0f0f0f0full,0x3828d8b8f8f8fcfcull,0x7080d0f0f0f8fcfcull,0xe090d0f0f0f8fcfcull,0xe040c08080808080ull,0x207070707070303ull,0x507070707070303ull,0xa0f0f0f0f070303ull,0x141e0f0f0f070303ull,0x280c5e8f8f878383ull,0x5070808081818181ull,0xa080d08080818181ull,0x40c0808080808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x70603ull,0xf0507ull,0x1f0b0full,0x3f171full,0x7f2f3full,0xff5777ull,0xffa0e0ull,0xe040c0ull,0x7060707ull,0xf0d0f0full,0xf1b1f1dull,0x1f373f2bull,0x3f6f7f57ull,0x7fdfffbfull,0xfebfffffull,0xc07efefeull,0x706070707ull,0xf0d0f0f0full,0xf0b1f1f1full,0x1f173f3f3full,0x1f2f7f7f7full,0x1e5fffffffull,0xbeffffffull,0x40fefefeull,0x70607070707ull,0xf0d0f0f0f0full,0xf0b0f0f1f1full,0x1f171f1f3f3full,0x1e0f3f3f7f7full,0xb0d0f0f0f8f8ull,0xb090f0f0f8f8ull,0xb070f0f0f8f8ull,0x7060707070707ull,0xf0d0f0f0f0f0full,0xf0b0f0f0f0f0full,0x1e171f1f1f1f1full,0x1c0e1f1f1f1f1full,0x3090f0f0f0f8f8ull,0x0ull,0x1030f0f0f0f8f8ull,0x306070707070707ull,0x70d0f0f0f0f0f0full,0xe0b0f0f0f0f0f0full,0x1c161f1f1f1f1f1full,0x382c1e9f9f9f9f9full,0x7090b0f0f0f0f8f8ull,0xe010b0f0f0f0f8f8ull,0xc020b0f0f0f0f8f8ull,0x207070707070707ull,0x50f0f0f0f0f0707ull,0xa0f0f0f0f0f0707ull,0x141e1f1f1f0f0707ull,0x283c1e9f9f8f8787ull,0x5018bc9e9f8f8787ull,0xa0e0808080818181ull,0x40a0a08080808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0xf0d0full,0x1f0b0full,0x3f171full,0x7f2f3full,0xff5f7full,0xffafefull,0xfe40c0ull,0xf0e0f0full,0xf0d0f0full,0x1f1b1f1dull,0x1f373f2bull,0x3fefffd7ull,0x7fdfffbfull,0xfebfffffull,0xfc7efefeull,0xf0e0f0f0full,0xf0d0f0f0full,0x1f1b1f1f1full,0x1f173f3f3full,0x3fafffffffull,0x3edfffffffull,0x3cbeffffffull,0x7cfefefeull,0xf0e0f0f0f0full,0xf0d0f0f0f0full,0x1f1b1f1f1f1full,0x1f171f1f3f3full,0x3eafbfbfffffull,0x3c9effffffffull,0x70b0f0f0f0f0ull,0x6020e0e0f0f0ull,0x70e0f0f0f0f0full,0xf0d0f0f0f0f0full,0x1f1b1f1f1f1f1full,0x1e171f1f1f1f1full,0x3c2ebfbfbfbfbfull,0x381cbebfbfbfbfull,0x3030f0f0f0f0f0ull,0x0ull,0x3060f0f0f0f0f0full,0x70d0f0f0f0f0f0full,0xe1b1f1f1f1f1f1full,0x1c161f1f1f1f1f1full,0x382c3ebfbfbfbfbfull,0x70583cbebfbfbfbfull,0xe03070f0f0f0f0f0ull,0xc02060e0e0e0f0f0ull,0x2070f0f0f0f0f0full,0x50f0f0f0f0f0f0full,0xa1f1f1f1f1f0f0full,0x141e1f1f1f1f0f0full,0x283c3ebfbf9f8f8full,0x50783cbebf9f8f8full,0xa0b078bcbe9f8f8full,0x40e0008080808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x7f7e73ull,0xfffdffull,0xfffbffull,0xfff7ffull,0xfeeefeull,0xfcdcfcull,0xf8b8f8ull,0xf070c0ull,0x3f7e7f7full,0x7ffdffffull,0xfffbfffdull,0xfef7ffebull,0xfceefed6ull,0xf8dcfcbcull,0xf0b8f8f8ull,0xf070f0f0ull,0x1f3e7f7f7full,0x3f7dffffffull,0x7efbffffffull,0xfcf7ffffffull,0xf8ecfefefeull,0xf8d8fcfcfcull,0xf0b0f8f8f8ull,0xf070f0f0f0ull,0x1e3f7f7f7full,0x1c3d7fffffffull,0x3c7bffffffffull,0x7cf5ffffffffull,0xf8e8fcfefefeull,0xf8d8f8fcfcfcull,0xf0b0f0f8f8f8ull,0xf070f0f0f0f0ull,0x6040707070f0full,0xe0d0f0f0f1f1full,0x1c397fffffffffull,0x3c75fdfdffffffull,0x78e8f8f8fcfefeull,0xf8d8f8f8f8fcfcull,0xf0b0f0f0f0f8f8ull,0xe070f0f0f0f0f0ull,0x0ull,0x40c0f0f0f0f0f0full,0xc183d7dfdfdfdfdull,0x1c347dfdfdfdfdfdull,0x3868f8f8f8f8f8f8ull,0x70d8f8f8f8f8f8f8ull,0xe0b0f0f0f0f0f0f0ull,0xc060f0f0f0f0f0f0ull,0x6070707070707ull,0x40e0f0f0f0f0707ull,0x81c3d7dfdfdfdfdull,0x143c7dfdfdfdfdfdull,0x2878f8f8f8f8f8f8ull,0x50f8f8f8f8f8f8f8ull,0xa0f0f0f0f0f0f0f0ull,0x40e0f0f0f0f0f0f0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x7f7e73ull,0xfffdffull,0xfffbffull,0xfff7ffull,0xfeeefeull,0xfcdcfcull,0xf8b8f8ull,0xf070c0ull,0x77e7f7full,0x7ffdffffull,0xfffbfffdull,0xfef7ffebull,0xfceefed6ull,0xf8dcfcbcull,0xf0b8f8f8ull,0xe070f0f0ull,0x33e7f7f7full,0x3f7dffffffull,0x7efbffffffull,0xfcf6ffffffull,0xf8ecfefefeull,0xf0d8fcfcfcull,0xf0b0f8f8f8ull,0xe060f0f0f0ull,0x23f7f7f7full,0x3d7fffffffull,0x387affffffffull,0x78f4feffffffull,0xf8e8fcfefefeull,0xf0d0f8fcfcfcull,0xf0b0f0f8f8f8ull,0xe060e0f0f0f0ull,0x5060707070f0full,0x9090f0f0f1f1full,0x90b0f0f1f3f3full,0x3870fcfcffffffull,0x78e8f8f8fcfefeull,0xf0d0f0f0f8fcfcull,0xf0b0f0f0f0f8f8ull,0xe060e0e0e0f0f0ull,0x80b0f0f0f0f0full,0x0ull,0x8090f0f0f0f0f0full,0x183078f8f8f8f8f8ull,0x3868f8f8f8f8f8f8ull,0x70d0f0f0f0f0f0f0ull,0xe0b0f0f0f0f0f0f0ull,0xc060e0e0e0e0e0e0ull,0x5070707070707ull,0x90f0f0f0f0707ull,0x8090f0f0f0f0f0full,0x103878f8f8f8f8f8ull,0x2878f8f8f8f8f8f8ull,0x50f0f0f0f0f0f0f0ull,0xa0f0f0f0f0f0f0f0ull,0x40e0e0e0e0e0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0xfffdffull,0xfffbffull,0xfff7ffull,0xfeeefeull,0xfcdcfcull,0xf8b8f8ull,0xf070c0ull,0x70e0f0full,0xffdffffull,0xfffbfffdull,0xfef7ffebull,0xfceefed6ull,0xf8dcfcbcull,0xf0b8f8f8ull,0xe070f0f0ull,0x3060f0f0full,0x77dffffffull,0x7ffbffffffull,0xfcf7ffffffull,0xf8ecfefefeull,0xf0d8fcfcfcull,0xe0b0f8f8f8ull,0xe060f0f0f0ull,0x102070f0f0full,0x1057fffffffull,0x7bffffffffull,0x70f4ffffffffull,0xf0e8fcfefefeull,0xf0d0f8fcfcfcull,0xe0a0f0f8f8f8ull,0xe060e0f0f0f0ull,0x1000303070f0full,0x91d3f7fffffffull,0x9113f7fffffffull,0x1a153d7dffffffull,0x70e0f8f8fcfefeull,0xf0d0f0f0f8fcfcull,0xe0a0e0e0f0f8f8ull,0xe060e0e0e0f0f0ull,0x500010101010101ull,0x109153f7fffffffull,0x0ull,0x10101d3d7dfdfdfdull,0x3060f0f0f0f0f0f0ull,0x70d0f0f0f0f0f0f0ull,0xe0a0e0e0e0e0e0e0ull,0xc060e0e0e0e0e0e0ull,0x1030101010101ull,0x1091f3f7fffffffull,0x91f3f7fffffffull,0x101a1d3d7dfdfdfdull,0x2070f0f0f0f0f0f0ull,0x50f0f0f0f0f0f0f0ull,0xa0e0e0e0e0e0e0e0ull,0x40e0e0e0e0e0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0x1f1d1full,0xfffbffull,0xfff7ffull,0xffefffull,0xfcdcfcull,0xf8b8f8ull,0xf070c0ull,0x70e0f0full,0xf1d1f1full,0x1ffbfffdull,0xfff7ffebull,0xfcefffd7ull,0xf8dcfcbcull,0xf0b8f8f8ull,0xe070f0f0ull,0x3060f0f0full,0x70d1f1f1full,0xffbffffffull,0xfff7ffffffull,0xf8efffffffull,0xf0d8fcfcfcull,0xe0b0f8f8f8ull,0xc060f0f0f0ull,0x302070f0f0full,0x3050f1f1f1full,0x30bffffffffull,0xf7ffffffffull,0xe0e8ffffffffull,0xe0d0f8fcfcfcull,0xe0a0f0f8f8f8ull,0xc040e0f0f0f0ull,0x3020303070f0full,0x30107070f1f1full,0x132b7fffffffffull,0x12217dfdffffffull,0x70a8f8f8fcfefeull,0xe0c0f0f0f8fcfcull,0xe0a0e0e0f0f8f8ull,0xc040c0c0e0f0f0ull,0x302030303030303ull,0x301030303030303ull,0x2122b7dfdfdfdfdull,0x0ull,0x20202878f8f8f8f8ull,0x60c0e0e0e0e0e0e0ull,0xe0a0e0e0e0e0e0e0ull,0xc040c0c0c0c0c0c0ull,0x203030303030303ull,0x103030303030303ull,0x2132f7fffffffffull,0x123d7dfdfdfdfdull,0x2070b8f8f8f8f8f8ull,0x40e0e0e0e0e0e0e0ull,0xa0e0e0e0e0e0e0e0ull,0x40c0c0c0c0c0c0c0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0x1f1d1full,0x3f3b3full,0xfff7ffull,0xffefffull,0xffdfffull,0xf8b8f8ull,0xf070c0ull,0x70e0f0full,0xf1d1f1full,0x1f3b3f3dull,0x3ff7ffebull,0xffefffd7ull,0xf8dfffbfull,0xf0b8f8f8ull,0xe070f0f0ull,0x3060f0f0full,0x70d1f1f1full,0xf1b3f3f3full,0x1ff7ffffffull,0xffefffffffull,0xf0dfffffffull,0xe0b0f8f8f8ull,0xc060f0f0f0ull,0x302070f0f0full,0x7050f1f1f1full,0x70b1f3f3f3full,0x717ffffffffull,0xefffffffffull,0xc0d0ffffffffull,0xc0a0f0f8f8f8ull,0xc040e0f0f0f0ull,0x3020303070f0full,0x70507070f1f1full,0x7030f0f1f3f3full,0x2e55fdfdffffffull,0x68c0f8f8fcfefeull,0xe8d0f8f8f8fcfcull,0xc080e0e0f0f8f8ull,0xc040c0c0e0f0f0ull,0x302030303030303ull,0x705070707070707ull,0x603070707070707ull,0x42454f8f8f8f8f8ull,0x0ull,0x4048d0f8f8f8f8f8ull,0xc080c0c0c0c0c0c0ull,0xc040c0c0c0c0c0c0ull,0x203030303030303ull,0x507070707070707ull,0x207070707070707ull,0x42e5dfdfdfdfdfdull,0x68f8f8f8f8f8f8ull,0x40e8f0f8f8f8f8f8ull,0x80c0c0c0c0c0c0c0ull,0x40c0c0c0c0c0c0c0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0x1f1d1full,0x3f3b3full,0x7f777full,0xffefffull,0xffdfffull,0xffbfffull,0xf070c0ull,0x70e0f0full,0xf1d1f1full,0x1f3b3f3dull,0x3f777f6bull,0x7fefffd7ull,0xffdfffbfull,0xf0bfffffull,0xe070f0f0ull,0x7060f0f0full,0x70d1f1f1full,0xf1b3f3f3full,0x1f377f7f7full,0x3fefffffffull,0xfedfffffffull,0xe0beffffffull,0xc060f0f0f0ull,0x706070f0f0full,0x7050f1f1f1full,0xf0b1f3f3f3full,0xf173f7f7f7full,0xe2fffffffffull,0xdeffffffffull,0x80a0feffffffull,0x8040e0f0f0f0ull,0x7060707070f0full,0x70507070f1f1full,0xf0b0f0f1f3f3full,0xe071f1f3f7f7full,0x58a8f8f8fcfefeull,0xd080f0f0f8fcfcull,0xd0b0f0f0f0f8f8ull,0x8000c0c0e0f0f0ull,0x306070707070707ull,0x705070707070707ull,0xe0b0f0f0f0f0f0full,0xc060f0f0f0f0f0full,0x848b8f0f0f0f0f0ull,0x0ull,0x8090a0f0f0f0f0f0ull,0xa000808080808080ull,0x207070707070707ull,0x507070707070707ull,0xa0f0f0f0f0f0f0full,0x40e0f0f0f0f0f0full,0x858b8f8f8f8f8f8ull,0xd0f0f0f0f0f0f0ull,0x80d0f0f0f0f0f0f0ull,0x80c08080808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0x1f1d1full,0x3f3b3full,0x7f777full,0xffefffull,0xffdfffull,0xffbfffull,0xfe7eceull,0x70e0f0full,0xf1d1f1full,0x1f3b3f3dull,0x3f777f6bull,0x7fefffd7ull,0xffdfffbfull,0xfebfffffull,0xe07efefeull,0x7060f0f0full,0xf0d1f1f1full,0xf1b3f3f3full,0x1f377f7f7full,0x3f6fffffffull,0x7edfffffffull,0xfcbeffffffull,0xc07cfefefeull,0x706070f0f0full,0xf0d0f1f1f1full,0xf0b1f3f3f3full,0x1f173f7f7f7full,0x1e2f7fffffffull,0x1c5effffffffull,0xbcfeffffffull,0x40fcfefefeull,0x7060707070f0full,0xf0d0f0f0f1f1full,0xf0b0f0f1f3f3full,0x1e171f1f3f7f7full,0x1c0e3f3fffffffull,0xb0d0f0f0f8fcfcull,0xb090f0f0f0f8f8ull,0xa070f0f0f0f0f0ull,0x306070707070707ull,0x70d0f0f0f0f0f0full,0xe0b0f0f0f0f0f0full,0x1c161f1f1f1f1f1full,0x180c1e1f1f1f1f1full,0x1090f0f0f0f0f0f0ull,0x0ull,0x30d0f0f0f0f0f0ull,0x207070707070707ull,0x50f0f0f0f0f0f0full,0xa0f0f0f0f0f0f0full,0x141e1f1f1f1f1f1full,0x81c1e1f1f1f1f1full,0x10b0f0f0f0f0f0f0ull,0xb0f0f0f0f0f0f0ull,0xa0f0f0f0f0f0f0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0xf0e03ull,0x1f1d1full,0x3f3b3full,0x7f777full,0xffefffull,0xffdfffull,0xffbfffull,0xfe7eceull,0xf0e0f0full,0xf1d1f1full,0x1f3b3f3dull,0x3f777f6bull,0x7fefffd7ull,0xffdfffbfull,0xfebfffffull,0xfc7efefeull,0xf0e0f0f0full,0xf0d1f1f1full,0x1f1b3f3f3full,0x1f377f7f7full,0x3fefffffffull,0x7edfffffffull,0xfcbeffffffull,0xf87cfefefeull,0xf0e0f0f0f0full,0xf0d0f1f1f1full,0x1f1b1f3f3f3full,0x1f173f7f7f7full,0x3eafffffffffull,0x3cdeffffffffull,0x38bcfeffffffull,0x78fcfefefeull,0x70e0f0f0f0f0full,0xf0d0f0f0f1f1full,0x1f1b1f1f1f3f3full,0x1e171f1f3f7f7full,0x3caebfbfffffffull,0x389cfeffffffffull,0x70b0f0f0f0f8f8ull,0x6020e0e0e0f0f0ull,0x3060f0f0f0f0f0full,0x70d0f0f0f0f0f0full,0xe1b1f1f1f1f1f1full,0x1c161f1f1f1f1f1full,0x382cbebfbfbfbfbfull,0x3018bcbebfbfbfbfull,0x2030f0f0f0f0f0f0ull,0x0ull,0x2070f0f0f0f0f0full,0x50f0f0f0f0f0f0full,0xa1f1f1f1f1f1f1full,0x141e1f1f1f1f1f1full,0x283cbebfbfbfbfbfull,0x1038bcbebfbfbfbfull,0x2070f0f0f0f0e0e0ull,0x60e0e0e0e0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x7f7e73ull,0xfffdffull,0xfffbffull,0xfff7ffull,0xffefffull,0xfedefeull,0xfcbcfcull,0xf878c8ull,0x3f7e7f7full,0x7ffdffffull,0xfffbfffdull,0xfff7ffebull,0xfeefffd7ull,0xfcdefebeull,0xf8bcfcfcull,0xf078f8f8ull,0x1f3e7f7f7full,0x3f7dffffffull,0x7ffbffffffull,0xfef7ffffffull,0xfceeffffffull,0xf8dcfefefeull,0xf0b8fcfcfcull,0xf070f8f8f8ull,0xf1e3f7f7f7full,0x1f3d7fffffffull,0x3f7bffffffffull,0x7cf7ffffffffull,0xf8ecfeffffffull,0xf8d8fcfefefeull,0xf0b0f8fcfcfcull,0xf070f0f8f8f8ull,0xe1f3f7f7f7full,0xd1d3f7fffffffull,0x1d3b7fffffffffull,0x3d75ffffffffffull,0x78e8fcfeffffffull,0xf8d8f8fcfefefeull,0xf0b0f0f8fcfcfcull,0xe070f0f0f8f8f8ull,0x40707070f1f1full,0x40d0f0f0f1f3f3full,0xc193f7fffffffffull,0x1c357dfdffffffffull,0x3868f8f8fcffffffull,0x70d8f8f8f8fcfefeull,0xe0b0f0f0f0f8fcfcull,0xc060f0f0f0f0f8f8ull,0x0ull,0x40d0f0f0f0f0f0full,0x81d3d7dfdfdfdfdull,0x143d7dfdfdfdfdfdull,0x2878f8f8f8f8f8f8ull,0x50f8f8f8f8f8f8f8ull,0xa0f0f0f0f0f0f0f0ull,0x40e0f0f0f0f0f0f0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x7f7e73ull,0xfffdffull,0xfffbffull,0xfff7ffull,0xffefffull,0xfedefeull,0xfcbcfcull,0xf878c8ull,0x3f7e7f7full,0x7ffdffffull,0xfffbfffdull,0xfff7ffebull,0xfeefffd7ull,0xfcdefebeull,0xf8bcfcfcull,0xf078f8f8ull,0x73e7f7f7full,0x3f7dffffffull,0x7ffbffffffull,0xfef7ffffffull,0xfceeffffffull,0xf8dcfefefeull,0xf0b8fcfcfcull,0xe070f8f8f8ull,0x31e3f7f7f7full,0x1f3d7fffffffull,0x3e7bffffffffull,0x7cf6ffffffffull,0xf8ecfeffffffull,0xf0d8fcfefefeull,0xf0b0f8fcfcfcull,0xe060f0f8f8f8ull,0x21f3f7f7f7full,0x1d3f7fffffffull,0x183a7fffffffffull,0x3874feffffffffull,0x78e8fcfeffffffull,0xf0d0f8fcfefefeull,0xf0b0f0f8fcfcfcull,0xe060e0f0f8f8f8ull,0x60707070f1f1full,0x90f0f0f1f3f3full,0x80b0f0f1f3f7f7full,0x18307cfcffffffffull,0x3868f8f8fcffffffull,0x70d0f0f0f8fcfefeull,0xe0b0f0f0f0f8fcfcull,0xc060e0e0e0f0f8f8ull,0xb0f0f0f0f0f0full,0x0ull,0x80b0f0f0f0f0f0full,0x103878f8f8f8f8f8ull,0x2878f8f8f8f8f8f8ull,0x50f0f0f0f0f0f0f0ull,0xa0f0f0f0f0f0f0f0ull,0x40e0e0e0e0e0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x1f1e13ull,0xfffdffull,0xfffbffull,0xfff7ffull,0xffefffull,0xfedefeull,0xfcbcfcull,0xf878c8ull,0xf1e1f1full,0x7ffdffffull,0xfffbfffdull,0xfff7ffebull,0xfeefffd7ull,0xfcdefebeull,0xf8bcfcfcull,0xf078f8f8ull,0x70e1f1f1full,0xf7dffffffull,0x7ffbffffffull,0xfef7ffffffull,0xfceeffffffull,0xf8dcfefefeull,0xf0b8fcfcfcull,0xe070f8f8f8ull,0x3060f1f1f1full,0x73d7fffffffull,0x3f7bffffffffull,0x7cf7ffffffffull,0xf8ecfeffffffull,0xf0d8fcfefefeull,0xe0b0f8fcfcfcull,0xe060f0f8f8f8ull,0x102070f1f1f1full,0x1053f7fffffffull,0x3b7fffffffffull,0x3074ffffffffffull,0x70e8fcfeffffffull,0xf0d0f8fcfefefeull,0xe0a0f0f8fcfcfcull,0xe060e0f0f8f8f8ull,0x1000303070f1f1full,0x10d1f3f7fffffffull,0x11f3f7fffffffull,0x10141d3d7fffffffull,0x3060f8f8fcffffffull,0x70d0f0f0f8fcfefeull,0xe0a0e0e0f0f8fcfcull,0xc060e0e0e0f0f8f8ull,0x1030101010101ull,0x1051f3f7fffffffull,0x0ull,0x10151d3d7dfdfdfdull,0x2070f0f0f0f0f0f0ull,0x50f0f0f0f0f0f0f0ull,0xa0e0e0e0e0e0e0e0ull,0x40e0e0e0e0e0e0e0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x1f1e13ull,0x3f3d3full,0xfffbffull,0xfff7ffull,0xffefffull,0xfedefeull,0xfcbcfcull,0xf878c8ull,0xf1e1f1full,0x1f3d3f3full,0xfffbfffdull,0xfff7ffebull,0xffefffd7ull,0xfcdefebeull,0xf8bcfcfcull,0xf078f8f8ull,0x70e1f1f1full,0xf1d3f3f3full,0x1ffbffffffull,0xfff7ffffffull,0xfcefffffffull,0xf8dcfefefeull,0xf0b8fcfcfcull,0xe070f8f8f8ull,0x3060f1f1f1full,0x70d1f3f3f3full,0xf7bffffffffull,0x7ff7ffffffffull,0xf8efffffffffull,0xf0d8fcfefefeull,0xe0b0f8fcfcfcull,0xc060f0f8f8f8ull,0x302070f1f1f1full,0x3050f1f3f3f3full,0x30b7fffffffffull,0x77ffffffffffull,0x60e8ffffffffffull,0xe0d0f8fcfefefeull,0xe0a0f0f8fcfcfcull,0xc040e0f0f8f8f8ull,0x3020303070f1f1full,0x30107070f1f3f3full,0x20b3f7fffffffffull,0x3d7dffffffffull,0x2028b8f8fcffffffull,0x60c0f0f0f8fcfefeull,0xe0a0e0e0f0f8fcfcull,0xc040c0c0e0f0f8f8ull,0x203030303030303ull,0x103030303030303ull,0x20b3d7dfdfdfdfdull,0x0ull,0x20283878f8f8f8f8ull,0x40e0e0e0e0e0e0e0ull,0xa0e0e0e0e0e0e0e0ull,0x40c0c0c0c0c0c0c0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x1f1e13ull,0x3f3d3full,0x7f7b7full,0xfff7ffull,0xffefffull,0xffdfffull,0xfcbcfcull,0xf878c8ull,0xf1e1f1full,0x1f3d3f3full,0x3f7b7f7dull,0xfff7ffebull,0xffefffd7ull,0xffdfffbfull,0xf8bcfcfcull,0xf078f8f8ull,0x70e1f1f1full,0xf1d3f3f3full,0x1f3b7f7f7full,0x3ff7ffffffull,0xffefffffffull,0xf8dfffffffull,0xf0b8fcfcfcull,0xe070f8f8f8ull,0x3060f1f1f1full,0x70d1f3f3f3full,0xf1b3f7f7f7full,0x1ff7ffffffffull,0xfeefffffffffull,0xf0deffffffffull,0xe0b0f8fcfcfcull,0xc060f0f8f8f8ull,0x302070f1f1f1full,0x7050f1f3f3f3full,0x70b1f3f7f7f7full,0x617ffffffffffull,0xeeffffffffffull,0xc0d0feffffffffull,0xc0a0f0f8fcfcfcull,0xc040e0f0f8f8f8ull,0x3020303070f1f1full,0x70507070f1f3f3full,0x6030f0f1f3f7f7full,0x4147dfdffffffffull,0xf8f8fcffffffull,0x40d0f8f8f8fcfefeull,0xc080e0e0f0f8fcfcull,0xc040c0c0e0f0f8f8ull,0x203030303030303ull,0x507070707070707ull,0x207070707070707ull,0x41478f8f8f8f8f8ull,0x0ull,0x40d0f8f8f8f8f8f8ull,0x80c0c0c0c0c0c0c0ull,0x40c0c0c0c0c0c0c0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x1f1e13ull,0x3f3d3full,0x7f7b7full,0xfff7ffull,0xffefffull,0xffdfffull,0xffbfffull,0xf878c8ull,0xf1e1f1full,0x1f3d3f3full,0x3f7b7f7dull,0x7ff7ffebull,0xffefffd7ull,0xffdfffbfull,0xfebfffffull,0xf078f8f8ull,0x70e1f1f1full,0xf1d3f3f3full,0x1f3b7f7f7full,0x3f77ffffffull,0x7fefffffffull,0xfedfffffffull,0xf0beffffffull,0xe070f8f8f8ull,0x7060f1f1f1full,0x70d1f3f3f3full,0xf1b3f7f7f7full,0x1f377fffffffull,0x3eefffffffffull,0xfcdeffffffffull,0xe0bcfeffffffull,0xc060f0f8f8f8ull,0x706070f1f1f1full,0x7050f1f3f3f3full,0xf0b1f3f7f7f7full,0xe173f7fffffffull,0xc2effffffffffull,0xdcfeffffffffull,0x80a0fcfeffffffull,0x8040e0f0f8f8f8ull,0x3060707070f1f1full,0x70507070f1f3f3full,0xe0b0f0f1f3f7f7full,0xc061f1f3fffffffull,0x828f8f8fcffffffull,0x80f0f0f8fcfefeull,0x80b0f0f0f0f8fcfcull,0x8000c0c0e0f0f8f8ull,0x207070707070707ull,0x507070707070707ull,0xa0f0f0f0f0f0f0full,0x40e0f0f0f0f0f0full,0x8a8f0f0f0f0f0f0ull,0x0ull,0x80a0f0f0f0f0f0f0ull,0x80c08080808080ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x1f1e13ull,0x3f3d3full,0x7f7b7full,0xfff7ffull,0xffefffull,0xffdfffull,0xffbfffull,0xfe7eceull,0xf1e1f1full,0x1f3d3f3full,0x3f7b7f7dull,0x7ff7ffebull,0xffefffd7ull,0xffdfffbfull,0xfebfffffull,0xfc7efefeull,0x70e1f1f1full,0xf1d3f3f3full,0x1f3b7f7f7full,0x3f77ffffffull,0x7fefffffffull,0xfedfffffffull,0xfcbeffffffull,0xe07cfefefeull,0x7060f1f1f1full,0xf0d1f3f3f3full,0xf1b3f7f7f7full,0x1f377fffffffull,0x3e6fffffffffull,0x7cdeffffffffull,0xf8bcfeffffffull,0xc078fcfefefeull,0x706070f1f1f1full,0xf0d0f1f3f3f3full,0xf0b1f3f7f7f7full,0x1e173f7fffffffull,0x1c2e7fffffffffull,0x185cfeffffffffull,0xb8fcfeffffffull,0x40f8fcfefefeull,0x3060707070f1f1full,0x70d0f0f0f1f3f3full,0xe0b0f0f1f3f7f7full,0x1c161f1f3fffffffull,0x180c3e3fffffffffull,0x10d0f0f0f8fcfefeull,0x90f0f0f0f8fcfcull,0x60f0f0f0f0f8f8ull,0x207070707070707ull,0x50f0f0f0f0f0f0full,0xa0f0f0f0f0f0f0full,0x141e1f1f1f1f1f1full,0x81c1e1f1f1f1f1full,0x10d0f0f0f0f0f0f0ull,0x0ull,0xd0f0f0f0f0f0f0ull}, - {0x302ull,0x705ull,0xe0aull,0x1c14ull,0x3828ull,0x7050ull,0xe0a0ull,0xc040ull,0x1f1e13ull,0x3f3d3full,0x7f7b7full,0xfff7ffull,0xffefffull,0xffdfffull,0xffbfffull,0xfe7eceull,0xf1e1f1full,0x1f3d3f3full,0x3f7b7f7dull,0x7ff7ffebull,0xffefffd7ull,0xffdfffbfull,0xfebfffffull,0xfc7efefeull,0xf0e1f1f1full,0xf1d3f3f3full,0x1f3b7f7f7full,0x3f77ffffffull,0x7fefffffffull,0xfedfffffffull,0xfcbeffffffull,0xf87cfefefeull,0xf0e0f1f1f1full,0xf0d1f3f3f3full,0x1f1b3f7f7f7full,0x1f377fffffffull,0x3eefffffffffull,0xfcdeffffffffull,0xf8bcfeffffffull,0xf078fcfefefeull,0x70e0f0f1f1f1full,0xf0d0f1f3f3f3full,0x1f1b1f3f7f7f7full,0x1e173f7fffffffull,0xbcaeffffffffffull,0xb8dcfeffffffffull,0xb0b8fcfeffffffull,0x70f8fcfefefeull,0x3060f0f0f0f1f1full,0x70d0f0f0f1f3f3full,0xe1b1f1f1f3f7f7full,0x1c161f1f3fffffffull,0x38acbebfffffffffull,0x3098fcfeffffffffull,0x20b0f0f0f0f8fcfcull,0x20e0e0e0f0f8f8ull,0x2070f0f0f0f0f0full,0x50f0f0f0f0f0f0full,0xa1f1f1f1f1f1f1full,0x141e1f1f1f1f1f1full,0x28bcbebfbfbfbfbfull,0x10b8bcbebfbfbfbfull,0x20b0f0f0f0f0f0f0ull,0x0ull} - - }, - { - - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x3e3d0cull,0x7d7a7aull,0xfbfffeull,0xf5fdfcull,0xe9f9f8ull,0xd1f1f0ull,0xb05040ull,0x60a0a0ull,0x1e3f3f0eull,0x3d7a7f7eull,0x7bfffffeull,0xf7fffdfcull,0xeffdf9f8ull,0xdcf9f1f0ull,0xb850f0e0ull,0x70a0e0e0ull,0xe1d3f3f0eull,0x1d3a7f7f7eull,0x3b77fffffeull,0x77fffffdfcull,0xeefffdf9f8ull,0xdcacf9f1f0ull,0xb858f0f0e0ull,0x70b0e0e0e0ull,0x60d1f3f3f0eull,0xd1a3f7f7f7eull,0x1b377ffffffeull,0x367ffffffdfcull,0x6cd6fffdf9f8ull,0xd8acfcf9f1f0ull,0xb058f8f0f0e0ull,0x60b0f0e0e0e0ull,0x2050f1f3f3f0eull,0x50a1f3f7f7f7eull,0xa173f7ffffffeull,0x142a7ffffffdfcull,0x2854fefffdf9f8ull,0x50a8fcfcf9f1f0ull,0xa050f8f8f0f0e0ull,0x40a0f0f0e0e0e0ull,0x1070f1f3f0100ull,0x20f1f3f7f0100ull,0x41f3f7fffe180ull,0x83e7fffffe1c0ull,0x107cfefffde1c0ull,0x20f8fcfcf9e1c0ull,0x40f0f8f8f0e0c0ull,0x80e0f0f0e0e0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0xa0505ull,0x7d7a08ull,0xfbfffdull,0xf5fdfdull,0xe9f9f9ull,0xd1f1f1ull,0xa04040ull,0x60a080ull,0x1e0f0705ull,0x3d7a7f0dull,0x7bfffffdull,0xf7fffdfdull,0xeffdf9f9ull,0xdcf9f1f1ull,0xb850e0e0ull,0x70a0e0c0ull,0xe1d0f0705ull,0x1d3a7f7f0dull,0x3b77fffffdull,0x77fffffdfdull,0xeefffdf9f9ull,0xdcacf9f1f1ull,0xb858f0e0e0ull,0x70b0e0e0c0ull,0x60d1f0f0705ull,0xd1a3f7f7f0dull,0x1b377ffffffdull,0x367ffffffdfdull,0x6cd6fffdf9f9ull,0xd8acfcf9f1f1ull,0xb058f8f0e0e0ull,0x60b0f0e0e0c0ull,0x2050f1f0f0705ull,0x50a1f3f7f7f0dull,0xa173f7ffffffdull,0x142a7ffffffdfdull,0x2854fefffdf9f9ull,0x50a8fcfcf9f1f1ull,0xa050f8f8f0e0e0ull,0x40a0f0f0e0e0c0ull,0x1070f1f0f0101ull,0x20f1f3f7f0101ull,0x41f3f7fff8181ull,0x83e7fffffc181ull,0x107cfefffdc181ull,0x20f8fcfcf9c181ull,0x40f0f8f8f0c080ull,0x80e0f0f0e0c080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20101ull,0x150a0aull,0xfbff9bull,0xf5fff9ull,0xe9f9f9ull,0xd1a1f1ull,0xa04040ull,0x408080ull,0xe070303ull,0x3d1a0f0bull,0x7bffff9bull,0xf7fffff9ull,0xeffdf9f9ull,0xdcf9f1f1ull,0xb850e0e0ull,0x70a0c0c0ull,0xe0d070303ull,0x1d3a1f0f0bull,0x3b77ffff9bull,0x77fffffff9ull,0xeefffdf9f9ull,0xdcacf9f1f1ull,0xb858f0e0e0ull,0x70b0e0c0c0ull,0x60d0f070303ull,0xd1a3f1f0f0bull,0x1b377fffff9bull,0x367ffffffff9ull,0x6cd6fffdf9f9ull,0xd8acfcf9f1f1ull,0xb058f8f0e0e0ull,0x60b0f0e0c0c0ull,0x2050f0f070303ull,0x50a1f3f1f0f0bull,0xa173f7fffff9bull,0x142a7ffffffff9ull,0x2854fefffdf9f9ull,0x50a8fcfcf9f1f1ull,0xa050f8f8f0e0e0ull,0x40a0f0f0e0c0c0ull,0x1070f0f070101ull,0x20f1f3f1f0101ull,0x41f3f7fff8181ull,0x83e7fffff8181ull,0x107cfefffd8181ull,0x20f8fcfcf98181ull,0x40f0f8f8f08080ull,0x80e0f0f0e08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20101ull,0x50202ull,0xab9f87ull,0xf7ffb7ull,0xebd5f1ull,0xd1a1f1ull,0xa04040ull,0x408080ull,0xe070303ull,0x1d0a0707ull,0x7bbf9f87ull,0xf7ffffb7ull,0xeffffdf1ull,0xdca9f1f1ull,0xb850e0e0ull,0x70a0c0c0ull,0xe0d070303ull,0x1d1a0f0707ull,0x3b77bf9f87ull,0x77ffffffb7ull,0xeefffffdf1ull,0xdcacf9f1f1ull,0xb858f0e0e0ull,0x70b0e0c0c0ull,0x60d0f070303ull,0xd1a1f0f0707ull,0x1b377fbf9f87ull,0x367fffffffb7ull,0x6cd6fffffdf1ull,0xd8acfcf9f1f1ull,0xb058f8f0e0e0ull,0x60b0f0e0c0c0ull,0x2050f0f070303ull,0x50a1f1f0f0707ull,0xa173f7fbf9f87ull,0x142a7fffffffb7ull,0x2854fefffffdf1ull,0x50a8fcfcf9f1f1ull,0xa050f8f8f0e0e0ull,0x40a0f0f0e0c0c0ull,0x1070f0f070101ull,0x20f1f1f0f0101ull,0x41f3f7fbf8181ull,0x83e7fffff8181ull,0x107cfeffff8181ull,0x20f8fcfcf98181ull,0x40f0f8f8f08080ull,0x80e0f0f0e08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20101ull,0x50202ull,0x8b8f8full,0xd7bf8full,0xefd7edull,0xd5a9e1ull,0xa04040ull,0x408080ull,0xe070303ull,0x1d0a0707ull,0x3b9f8f8full,0xf7ffbf8full,0xefffffedull,0xdeadf9e1ull,0xb850e0e0ull,0x70a0c0c0ull,0xe0d070303ull,0x1d1a0f0707ull,0x3b379f8f8full,0x77ffffbf8full,0xeeffffffedull,0xdcaefdf9e1ull,0xb858f0e0e0ull,0x70b0e0c0c0ull,0x60d0f070303ull,0xd1a1f0f0707ull,0x1b373f9f8f8full,0x367fffffbf8full,0x6cd6ffffffedull,0xd8acfefdf9e1ull,0xb058f8f0e0e0ull,0x60b0f0e0c0c0ull,0x2050f0f070303ull,0x50a1f1f0f0707ull,0xa173f3f9f8f8full,0x142a7fffffbf8full,0x2854feffffffedull,0x50a8fcfefdf9e1ull,0xa050f8f8f0e0e0ull,0x40a0f0f0e0c0c0ull,0x1070f0f070101ull,0x20f1f1f0f0101ull,0x41f3f3f9f8181ull,0x83e7fffff8181ull,0x107cfeffff8181ull,0x20f8fcfefd8181ull,0x40f0f8f8f08080ull,0x80e0f0f0e08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20101ull,0x50202ull,0x8b8f8full,0x979f9full,0xafd79full,0xdfafd9ull,0xa85050ull,0x408080ull,0xe070303ull,0x1d0a0707ull,0x3b9f8f8full,0xf7bf9f9full,0xefffff9full,0xdeafffd9ull,0xbc58f0d0ull,0x70a0c0c0ull,0xe0d070303ull,0x1d1a0f0707ull,0x3b379f8f8full,0x77ffbf9f9full,0xeeffffff9full,0xdcaeffffd9ull,0xb85cf8f0d0ull,0x70b0e0c0c0ull,0x60d0f070303ull,0xd1a1f0f0707ull,0x1b373f9f8f8full,0x367fffbf9f9full,0x6cd6ffffff9full,0xd8acfeffffd9ull,0xb058fcf8f0d0ull,0x60b0f0e0c0c0ull,0x2050f0f070303ull,0x50a1f1f0f0707ull,0xa173f3f9f8f8full,0x142a7fffbf9f9full,0x2854feffffff9full,0x50a8fcfeffffd9ull,0xa050f8fcf8f0d0ull,0x40a0f0f0e0c0c0ull,0x1070f0f070101ull,0x20f1f1f0f0101ull,0x41f3f3f9f8181ull,0x83e7fffbf8181ull,0x107cfeffff8181ull,0x20f8fcfeff8181ull,0x40f0f8fcf88080ull,0x80e0f0f0e08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60501ull,0x50202ull,0x8b8f8full,0x979f9full,0xaf97bfull,0xdfafbfull,0xbe5e10ull,0x50a0a0ull,0xe070703ull,0x1d0a0707ull,0x3b9f8f8full,0xf7bf9f9full,0xefffbfbfull,0xdeafffbfull,0xbc5efeb0ull,0x78b0e0a0ull,0xe0d070703ull,0x1d1a0f0707ull,0x3b379f8f8full,0x77ffbf9f9full,0xeeffffbfbfull,0xdcaeffffbfull,0xb85cfefeb0ull,0x70b8f0e0a0ull,0x60d0f070703ull,0xd1a1f0f0707ull,0x1b373f9f8f8full,0x367fffbf9f9full,0x6cd6ffffbfbfull,0xd8acfeffffbfull,0xb058fcfefeb0ull,0x60b0f8f0e0a0ull,0x2050f0f070703ull,0x50a1f1f0f0707ull,0xa173f3f9f8f8full,0x142a7fffbf9f9full,0x2854feffffbfbfull,0x50a8fcfeffffbfull,0xa050f8fcfefeb0ull,0x40a0f0f8f0e0a0ull,0x1070f0f070301ull,0x20f1f1f0f0301ull,0x41f3f3f9f8381ull,0x83e7fffbf8381ull,0x107cfeffff8381ull,0x20f8fcfeff8181ull,0x40f0f8fcfe8080ull,0x80e0f0f8f08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60505ull,0xd0a02ull,0x8b8f0full,0x979f1full,0xaf973full,0xdfaf7full,0xbe5e5eull,0x7cbc30ull,0xe070707ull,0x1d0a0f07ull,0x3b9f8f0full,0xf7bf9f1full,0xefffbf3full,0xdeafff7full,0xbc5efe7eull,0x78bcfc70ull,0xe0d070707ull,0x1d1a0f0f07ull,0x3b379f8f0full,0x77ffbf9f1full,0xeeffffbf3full,0xdcaeffff7full,0xb85cfefe7eull,0x70b8fcfc70ull,0x60d0f070707ull,0xd1a1f0f0f07ull,0x1b373f9f8f0full,0x367fffbf9f1full,0x6cd6ffffbf3full,0xd8acfeffff7full,0xb058fcfefe7eull,0x60b0f8fcfc70ull,0x2050f0f070707ull,0x50a1f1f0f0f07ull,0xa173f3f9f8f0full,0x142a7fffbf9f1full,0x2854feffffbf3full,0x50a8fcfeffff7full,0xa050f8fcfefe7eull,0x40a0f0f8fcfc70ull,0x1070f0f070703ull,0x20f1f1f0f0703ull,0x41f3f3f9f8703ull,0x83e7fffbf8703ull,0x107cfeffff8703ull,0x20f8fcfeff8701ull,0x40f0f8fcfe8000ull,0x80e0f0f8fc8000ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60001ull,0x50000ull,0xf9feffull,0xf0fcffull,0xe8f8ffull,0xd0f0ffull,0xb0505eull,0x60a0acull,0x1e3f3e37ull,0x3d7a7e7full,0x7bfffcffull,0xf5fdf8ffull,0xe9f9f8ffull,0xd0f1f0ffull,0xb050f0feull,0x60a0e0ecull,0xe1d3f0007ull,0x1d3a7f000full,0x3b77fffcffull,0x77fffdf8ffull,0xeefdf9f8ffull,0xdca8f1f0ffull,0xb850f0f0feull,0x70a0e0e0ecull,0x60d1f3f3e37ull,0xd1a3f7f7e7full,0x1b377ffffcffull,0x367ffffdf8ffull,0x6cd6fdf9f8ffull,0xd8acf8f1f0ffull,0xb058f0f0f0feull,0x60b0e0e0e0ecull,0x2050f1f3f0007ull,0x50a1f3f7f000full,0xa173f7ffff0ffull,0x142a7ffffdf0ffull,0x2854fefdf9f0ffull,0x50a8fcf8f1f0ffull,0xa050f8f0f0f0feull,0x40a0f0e0e0e0ecull,0x1070f1f3f0007ull,0x20f1f3f7f0007ull,0x41f3f7fffe0e7ull,0x83e7ffffde0e7ull,0x107cfefdf9e0e7ull,0x20f8fcf8f1e0e7ull,0x40f0f8f0f0e0e0ull,0x80e0f0e0e0e0e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60101ull,0x50000ull,0x30101ull,0xf0fcfcull,0xe0f8f8ull,0xd0f0f0ull,0xa04040ull,0x60a0a0ull,0xa07010full,0x3d7a7d7full,0x7bfffdfdull,0xf5fdf9f9ull,0xe9f9f1f9ull,0xd0f1f1f1ull,0xa040e0e0ull,0x60a0e0e0ull,0xe0d070101ull,0x1d3a7f0101ull,0x3b77ff818dull,0x77fffdf9f9ull,0xeefdf9f1f9ull,0xdca8f1f1f1ull,0xb850e0e0e0ull,0x70a0e0e0e0ull,0x60d0f07010full,0xd1a3f7f7d7full,0x1b377ffffdfdull,0x367ffffdf9f9ull,0x6cd6fdf9f1f9ull,0xd8acf8f1f1f1ull,0xb058f0e0e0e0ull,0x60b0e0e0e0e0ull,0x2050f0f070101ull,0x50a1f3f7f0101ull,0xa173f7fff8181ull,0x142a7ffffde1e1ull,0x2854fefdf9e1e1ull,0x50a8fcf8f1e1e1ull,0xa050f8f0e0e0e0ull,0x40a0f0e0e0e0e0ull,0x1070f0f070101ull,0x20f1f3f7f0101ull,0x41f3f7fff8181ull,0x83e7ffffdc1c1ull,0x107cfefdf9c1c1ull,0x20f8fcf8f1c1c1ull,0x40f0f8f0e0c0c0ull,0x80e0f0e0e0c0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x105ull,0x50000ull,0x30101ull,0x101ull,0xe0d0f8ull,0xc0a0f0ull,0xa04040ull,0x408080ull,0x2030101ull,0x150a030full,0x7bfffbffull,0xf5fff9f9ull,0xe9f9f1f1ull,0xd0a1e1e1ull,0xa040e0e0ull,0x4080c0c0ull,0xe05030101ull,0x1d1a0f0101ull,0x3b77ff8181ull,0x77ffff8189ull,0xeefdf9f1f1ull,0xdca8f1e1e1ull,0xb850e0e0e0ull,0x70a0c0c0c0ull,0x60d07030101ull,0xd1a1f0f030full,0x1b377ffffbffull,0x367ffffff9f9ull,0x6cd6fdf9f1f1ull,0xd8acf8f1e1e1ull,0xb058f0e0e0e0ull,0x60b0e0c0c0c0ull,0x2050f07030101ull,0x50a1f1f0f0101ull,0xa173f7fff8181ull,0x142a7fffff8181ull,0x2854fefdf9c1c1ull,0x50a8fcf8f1c1c1ull,0xa050f8f0e0c0c0ull,0x40a0f0e0c0c0c0ull,0x1070f07030101ull,0x20f1f1f0f0101ull,0x41f3f7fff8181ull,0x83e7fffff8181ull,0x107cfefdf98181ull,0x20f8fcf8f18181ull,0x40f0f8f0e08080ull,0x80e0f0e0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x101ull,0x10202ull,0x30101ull,0x101ull,0x0ull,0xc0a0f0ull,0x804040ull,0x408080ull,0x2030101ull,0x5020303ull,0x2b9f878full,0xf7fff7ffull,0xebd5f1f1ull,0xd0a1e1e1ull,0xa040c0c0ull,0x4080c0c0ull,0xe05030101ull,0x1d0a070303ull,0x3b379f8181ull,0x77ffff8181ull,0xeefffd8181ull,0xdca8f1e1e1ull,0xb850e0c0c0ull,0x70a0c0c0c0ull,0x60d07030101ull,0xd1a0f070303ull,0x1b373f9f878full,0x367ffffff7ffull,0x6cd6fffdf1f1ull,0xd8acf8f1e1e1ull,0xb058f0e0c0c0ull,0x60b0e0c0c0c0ull,0x2050f07030101ull,0x50a1f0f070101ull,0xa173f3f9f8181ull,0x142a7fffff8181ull,0x2854fefffd8181ull,0x50a8fcf8f18181ull,0xa050f8f0e08080ull,0x40a0f0e0c08080ull,0x1070f07030101ull,0x20f1f0f070101ull,0x41f3f3f9f8181ull,0x83e7fffff8181ull,0x107cfefffd8181ull,0x20f8fcf8f18181ull,0x40f0f8f0e08080ull,0x80e0f0e0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20101ull,0x10202ull,0x30f0full,0x101ull,0x0ull,0x0ull,0x804040ull,0x8080ull,0x2030303ull,0x5020303ull,0xb8f8787ull,0xd7bf8f8full,0xefd7efffull,0xd4a9e1f1ull,0xa040c0c0ull,0x40808080ull,0xe05030303ull,0x1d0a070303ull,0x3b178f8787ull,0x77ffbf8181ull,0xeeffff8181ull,0xdcacf98181ull,0xb850e0c0c0ull,0x70a0c08080ull,0x60d07030303ull,0xd1a0f070303ull,0x1b371f8f8787ull,0x367fffbf8f8full,0x6cd6ffffefffull,0xd8acfcf9e1f1ull,0xb058f0e0c0c0ull,0x60b0e0c08080ull,0x2050f07030101ull,0x50a1f0f070101ull,0xa173f1f8f8181ull,0x142a7fffbf8181ull,0x2854feffff8181ull,0x50a8fcfcf98181ull,0xa050f8f0e08080ull,0x40a0f0e0c08080ull,0x1070f07030101ull,0x20f1f0f070101ull,0x41f3f1f8f8181ull,0x83e7fffbf8181ull,0x107cfeffff8181ull,0x20f8fcfcf98181ull,0x40f0f8f0e08080ull,0x80e0f0e0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20101ull,0x50202ull,0x30f0full,0x70b1full,0x0ull,0x0ull,0x0ull,0x80a0ull,0x2030303ull,0x5020707ull,0xb8f8787ull,0x979f8f8full,0xafd79f9full,0xdeafdfffull,0xa850c0f0ull,0x40808080ull,0xe05030303ull,0x1d0a070707ull,0x3b178f8787ull,0x77bf9f8f8full,0xeeffff8191ull,0xdcaeff8181ull,0xb858f08080ull,0x70a0c08080ull,0x60d07030303ull,0xd1a0f070707ull,0x1b371f8f8787ull,0x367fbf9f8f8full,0x6cd6ffff9f9full,0xd8acfeffdfffull,0xb058f8f0c0f0ull,0x60b0e0c08080ull,0x2050f07030303ull,0x50a1f0f070303ull,0xa173f1f8f8383ull,0x142a7fbf9f8383ull,0x2854feffff8181ull,0x50a8fcfeff8181ull,0xa050f8f8f08080ull,0x40a0f0e0c08080ull,0x1070f07030101ull,0x20f1f0f070101ull,0x41f3f1f8f8181ull,0x83e7fbf9f8181ull,0x107cfeffff8181ull,0x20f8fcfeff8181ull,0x40f0f8f8f08080ull,0x80e0f0e0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60505ull,0x50202ull,0xb0f0full,0x70b1full,0xf173full,0x0ull,0x0ull,0x0ull,0x6070707ull,0x5020707ull,0xb8f8f8full,0x979f8f9full,0xaf979f9full,0xdeafbfbfull,0xbc5ebefeull,0x50a080f0ull,0xe05070707ull,0x1d0a070707ull,0x3b178f8f8full,0x77bf9f8f9full,0xeeffbf9f9full,0xdcaeff81b1ull,0xb85cfe8080ull,0x70b0e08080ull,0x60d07070707ull,0xd1a0f070707ull,0x1b371f8f8f8full,0x367fbf9f8f9full,0x6cd6ffbf9f9full,0xd8acfeffbfbfull,0xb058fcfebefeull,0x60b0f0e080f0ull,0x2050f07070707ull,0x50a1f0f070707ull,0xa173f1f8f8787ull,0x142a7fbf9f8787ull,0x2854feffbf8787ull,0x50a8fcfeff8181ull,0xa050f8fcfe8080ull,0x40a0f0f0e08080ull,0x1070f07070303ull,0x20f1f0f070303ull,0x41f3f1f8f8383ull,0x83e7fbf9f8383ull,0x107cfeffbf8383ull,0x20f8fcfeff8181ull,0x40f0f8fcfe8080ull,0x80e0f0f0e08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60535ull,0xd0a7aull,0xb0fffull,0x171fffull,0xf17ffull,0x9f2fffull,0x0ull,0x0ull,0x6070737ull,0xd0a0f7full,0xb8f0fffull,0x979f1fffull,0xaf971fffull,0xdeaf3fffull,0xbc5e7efeull,0x78bc7cecull,0xe05070737ull,0x1d0a0f0f7full,0x3b178f0fffull,0x77bf9f1fffull,0xeeffbf1fffull,0xdcaeff3fffull,0xb85cfe00f0ull,0x70b8fc00e0ull,0x60d07070737ull,0xd1a0f0f0f7full,0x1b371f8f0fffull,0x367fbf9f1fffull,0x6cd6ffbf1fffull,0xd8acfeff3fffull,0xb058fcfe7efeull,0x60b0f8fc7cecull,0x2050f07070737ull,0x50a1f0f0f0f7full,0xa173f1f8f0fffull,0x142a7fbf9f0fffull,0x2854feffbf0fffull,0x50a8fcfeff0fffull,0xa050f8fcfe00f0ull,0x40a0f0f8fc00e0ull,0x1070f07070707ull,0x20f1f0f0f0707ull,0x41f3f1f8f07e7ull,0x83e7fbf9f07e7ull,0x107cfeffbf07e7ull,0x20f8fcfeff07e7ull,0x40f0f8fcfe00e0ull,0x80e0f0f8fc00e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x40000ull,0xf8ffffull,0xf0ececull,0xe8d8d8ull,0xd0b0b0ull,0xb0f0f0ull,0x60a0e0ull,0x6000101ull,0x5000101ull,0x79fefdfdull,0xf0fcf8f8ull,0xe8f8f8f8ull,0xd0f0f0f0ull,0xb050f0f0ull,0x60a0e0e0ull,0xe1d3e3f3full,0x1d3a7e0101ull,0x3b77fcfdfdull,0x75fdf8f9f9ull,0xe8f9f8f9f9ull,0xd0a0f0f1f1ull,0xb050f0f0f0ull,0x60a0e0e0e0ull,0x60d1f000101ull,0xd1a3f000101ull,0x1b377ffcf9f9ull,0x367ffdf8f9f9ull,0x6cd4f9f8f9f9ull,0xd8a8f0f0f1f1ull,0xb050f0f0f0f0ull,0x60a0e0e0e0e0ull,0x2050f1f3e0101ull,0x50a1f3f7e0101ull,0xa173f7ffcf1f1ull,0x142a7ffdf8f1f1ull,0x2854fcf9f8f1f1ull,0x50a8f8f0f0f1f1ull,0xa050f0f0f0f0f0ull,0x40a0e0e0e0e0e0ull,0x1070f1f000101ull,0x20f1f3f000101ull,0x41f3f7ff0e1e1ull,0x83e7ffdf0e1e1ull,0x107cfcf9f0e1e1ull,0x20f8f8f0f0e1e1ull,0x40f0f0f0f0e0e0ull,0x80e0e0e0e0e0e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x40000ull,0x0ull,0x10101ull,0xf0ececull,0xe0d8d8ull,0xd0b0b0ull,0xa0e0e0ull,0x60a0e0ull,0x6010101ull,0x5000101ull,0x3010101ull,0xf0fcf8f8ull,0xe0f8f0f0ull,0xd0f0f0f0ull,0xa040e0e0ull,0x60a0e0e0ull,0xa05010101ull,0x1d3a7d7f7full,0x3b77fd8181ull,0x75fdf9f9f9ull,0xe8f9f1f1f1ull,0xd0a0f1f1f1ull,0xa040e0e0e0ull,0x60a0e0e0e0ull,0x60d07010101ull,0xd1a3f010101ull,0x1b377f818181ull,0x367ffdf9f1f1ull,0x6cd4f9f1f1f1ull,0xd8a8f0f1f1f1ull,0xb050e0e0e0e0ull,0x60a0e0e0e0e0ull,0x2050f07010101ull,0x50a1f3f7d0101ull,0xa173f7ffd8181ull,0x142a7ffdf9e1e1ull,0x2854fcf9f1e1e1ull,0x50a8f8f0f1e1e1ull,0xa050f0e0e0e0e0ull,0x40a0e0e0e0e0e0ull,0x1070f07010101ull,0x20f1f3f010101ull,0x41f3f7f818181ull,0x83e7ffde1c1c1ull,0x107cfcf9e1c1c1ull,0x20f8f8f0e1c1c1ull,0x40f0f0e0e0c0c0ull,0x80e0e0e0e0c0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x303ull,0x90101ull,0x0ull,0x30000ull,0xe0d0d8ull,0xc0a0b0ull,0xa040e0ull,0x4080c0ull,0x30101ull,0x5000101ull,0x3010101ull,0x10000ull,0xe0d0f0f0ull,0xc0a0e0e0ull,0xa040e0e0ull,0x4080c0c0ull,0x201010101ull,0x150a030101ull,0x3b77fbffffull,0x75fff98181ull,0xe8f9f1f1f1ull,0xd0a0e1e1e1ull,0xa040e0e0e0ull,0x4080c0c0c0ull,0x60503010101ull,0xd1a0f010101ull,0x1b377f818181ull,0x367fff818181ull,0x6cd4f9f1e1e1ull,0xd8a8f0e1e1e1ull,0xb050e0e0e0e0ull,0x60a0c0c0c0c0ull,0x2050703010101ull,0x50a1f0f030101ull,0xa173f7ffb8181ull,0x142a7ffff98181ull,0x2854fcf9f1c1c1ull,0x50a8f8f0e1c1c1ull,0xa050f0e0e0c0c0ull,0x40a0e0c0c0c0c0ull,0x1070703010101ull,0x20f1f0f010101ull,0x41f3f7f818181ull,0x83e7fff818181ull,0x107cfcf9c18181ull,0x20f8f8f0c18181ull,0x40f0f0e0c08080ull,0x80e0e0c0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x303ull,0x10707ull,0x30000ull,0x0ull,0x0ull,0xc0a0b0ull,0x8040e0ull,0x4080c0ull,0x30101ull,0x1020303ull,0x3010101ull,0x10000ull,0x0ull,0xc0a0e0e0ull,0x8040c0c0ull,0x4080c0c0ull,0x201010101ull,0x502030303ull,0x2b17878181ull,0x77fff7ffffull,0xead5f18181ull,0xd0a0e1e1e1ull,0xa040c0c0c0ull,0x4080c0c0c0ull,0x60503010101ull,0xd0a07030101ull,0x1b371f818181ull,0x367fff818181ull,0x6cd6fd818181ull,0xd8a8f0e1c1c1ull,0xb050e0c0c0c0ull,0x60a0c0c0c0c0ull,0x2050703010101ull,0x50a0f07030101ull,0xa173f1f878181ull,0x142a7ffff78181ull,0x2854fefdf18181ull,0x50a8f8f0e18181ull,0xa050f0e0c08080ull,0x40a0e0c0c08080ull,0x1070703010101ull,0x20f0f07010101ull,0x41f3f1f818181ull,0x83e7fff818181ull,0x107cfefd818181ull,0x20f8f8f0818181ull,0x40f0f0e0808080ull,0x80e0e0c0808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x10707ull,0x3050dull,0x0ull,0x0ull,0x0ull,0x8040e0ull,0x80c0ull,0x2030303ull,0x1020303ull,0x30f0707ull,0x10000ull,0x0ull,0x0ull,0x8040c0c0ull,0x808080ull,0x201030303ull,0x502030303ull,0xb07878787ull,0x57bf8f8181ull,0xeed7efffffull,0xd4a8e18181ull,0xa040c0c0c0ull,0x4080808080ull,0x60503030303ull,0xd0a07030303ull,0x1b170f878383ull,0x367fbf818181ull,0x6cd6ff818181ull,0xd8acf8818181ull,0xb050e0c08080ull,0x60a0c0808080ull,0x2050703030101ull,0x50a0f07030101ull,0xa171f0f878181ull,0x142a7fbf8f8181ull,0x2854feffef8181ull,0x50a8fcf8e18181ull,0xa050f0e0c08080ull,0x40a0e0c0808080ull,0x1070703010101ull,0x20f0f07010101ull,0x41f1f0f818181ull,0x83e7fbf818181ull,0x107cfeff818181ull,0x20f8fcf8818181ull,0x40f0f0e0808080ull,0x80e0e0c0808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x50707ull,0x30d0dull,0x70b1bull,0x0ull,0x0ull,0x0ull,0x80c0ull,0x2030303ull,0x5020707ull,0x30f0707ull,0x70b0f0full,0x0ull,0x0ull,0x0ull,0x808080ull,0x201030303ull,0x502070707ull,0xb07878787ull,0x179f8f8f8full,0xaed79f8181ull,0xdcaedfffffull,0xa850c08080ull,0x4080808080ull,0x60503030303ull,0xd0a07070707ull,0x1b170f878787ull,0x363f9f8f8787ull,0x6cd6ff818181ull,0xd8acfe818181ull,0xb058f0808080ull,0x60a0c0808080ull,0x2050703030303ull,0x50a0f07070303ull,0xa171f0f878383ull,0x142a3f9f8f8383ull,0x2854feff9f8181ull,0x50a8fcfedf8181ull,0xa050f8f0c08080ull,0x40a0e0c0808080ull,0x1070703030101ull,0x20f0f07030101ull,0x41f1f0f838181ull,0x83e3f9f838181ull,0x107cfeff818181ull,0x20f8fcfe818181ull,0x40f0f8f0808080ull,0x80e0e0c0808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0x50707ull,0xb0d0dull,0x70b1bull,0xf1737ull,0x0ull,0x0ull,0x0ull,0x6070707ull,0x5020707ull,0xb0f0f0full,0x70b0f0full,0xf171f1full,0x0ull,0x0ull,0x0ull,0x605070707ull,0x502070707ull,0xb078f8f8full,0x179f8f8f8full,0xae979f9f9full,0xdcaebf8181ull,0xb85cbefefeull,0x50a0808080ull,0x60507070707ull,0xd0a07070707ull,0x1b170f8f8f8full,0x363f9f8f8f8full,0x6cd6bf9f8f8full,0xd8acfe818181ull,0xb058fc808080ull,0x60b0e0808080ull,0x2050707070707ull,0x50a0f07070707ull,0xa171f0f8f8787ull,0x142a3f9f8f8787ull,0x2854febf9f8787ull,0x50a8fcfebf8181ull,0xa050f8fcbe8080ull,0x40a0f0e0808080ull,0x1070707070303ull,0x20f0f07070303ull,0x41f1f0f878383ull,0x83e3f9f878383ull,0x107cfebf878383ull,0x20f8fcfe818181ull,0x40f0f8fc808080ull,0x80e0f0e0808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0xb0d0dull,0x171b1bull,0xf1737ull,0x1fafffull,0x0ull,0x0ull,0x6070707ull,0xd0a0f0full,0xb0f0f0full,0x171f1f1full,0xf171f1full,0x9e2fbfbfull,0x0ull,0x0ull,0x605070707ull,0xd0a0f0f0full,0xb070f8f8full,0x179f1f9f9full,0xae971f9f9full,0xdcae3fbfbfull,0xb85c7e8080ull,0x70b87cfcfcull,0x60507070707ull,0xd0a0f0f0f0full,0x1b170f0f8f8full,0x363f9f1f9f9full,0x6cd6bf1f9f9full,0xd8acfe3f9f9full,0xb058fc008080ull,0x60b0f8008080ull,0x2050707070707ull,0x50a0f0f0f0f0full,0xa171f0f0f8f8full,0x142a3f9f1f8f8full,0x2854febf1f8f8full,0x50a8fcfe3f8f8full,0xa050f8fc7e8080ull,0x40a0f0f87c8080ull,0x1070707070707ull,0x20f0f0f0f0707ull,0x41f1f0f0f8787ull,0x83e3f9f0f8787ull,0x107cfebf0f8787ull,0x20f8fcfe0f8787ull,0x40f0f8fc008080ull,0x80e0f0f8008080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60101ull,0x50001ull,0xf8f4fcull,0xf0e8e8ull,0xe8d0d0ull,0xd0a0b0ull,0xb050f0ull,0x60a0e0ull,0x0ull,0x4000101ull,0x78fffdfdull,0xf0ecf8f8ull,0xe8d8f8f8ull,0xd0b0f0f0ull,0xb050f0f0ull,0x60a0e0e0ull,0x604010101ull,0x502010101ull,0x3976fdfdfdull,0x70fcf8f8f8ull,0xe8f8f8f8f8ull,0xd0a0f0f0f0ull,0xb050f0f0f0ull,0x60a0e0e0e0ull,0x60d1e3f0101ull,0xd1a3e010101ull,0x1b377cfdf9f9ull,0x3469f8f9f9f9ull,0x68d0f8f9f9f9ull,0xd0a0f0f0f0f0ull,0xb050f0f0f0f0ull,0x60a0e0e0e0e0ull,0x2010700010101ull,0x5021f00010101ull,0xa173f7cf9f1f1ull,0x14287df8f9f1f1ull,0x2850f8f8f9f1f1ull,0x50a0f0f0f0f0f0ull,0xa050f0f0f0f0f0ull,0x40a0e0e0e0e0e0ull,0x103071e010101ull,0x2071f3e010101ull,0x41f3f7cf1e1e1ull,0x83c7df8f1e1e1ull,0x1078f8f8f1e1e1ull,0x20f0f0f0f0e0e0ull,0x40f0f0f0f0e0e0ull,0x80e0e0e0e0e0e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60101ull,0x50001ull,0x30101ull,0xf0e8e8ull,0xe0d0d0ull,0xd0a0b0ull,0xa040e0ull,0x60a0e0ull,0x4000101ull,0x0ull,0x1010101ull,0xf0ecf8f8ull,0xe0d8f0f0ull,0xd0b0f0f0ull,0xa040e0e0ull,0x60a0e0e0ull,0x605010101ull,0x500010101ull,0x301010101ull,0x70fcf8f8f8ull,0xe0d0f0f0f0ull,0xd0a0f0f0f0ull,0xa040e0e0e0ull,0x60a0e0e0e0ull,0x20501010101ull,0xd1a3d7f0101ull,0x1b377d818181ull,0x3469f9f9f1f1ull,0x68d0f1f1f1f1ull,0xd0a0f0f0f0f0ull,0xa040e0e0e0e0ull,0x60a0e0e0e0e0ull,0x2010701010101ull,0x5020f01010101ull,0xa073f01818181ull,0x14287df9f1e1e1ull,0x2850f8f1f1e1e1ull,0x50a0f0f0f0e0e0ull,0xa040e0e0e0e0e0ull,0x40a0e0e0e0e0e0ull,0x1030701010101ull,0x2070f3d010101ull,0x40f3f7d818181ull,0x83c7df9e1c1c1ull,0x1078f8f1e1c1c1ull,0x20f0f0f0e0c0c0ull,0x40e0e0e0e0c0c0ull,0x80e0e0e0e0c0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x303ull,0x50001ull,0x30101ull,0x0ull,0xe0d0d0ull,0xc0a0b0ull,0xa040e0ull,0x4080c0ull,0x30101ull,0x9010101ull,0x0ull,0x3000000ull,0xe0d0f0f0ull,0xc0a0e0e0ull,0xa040e0e0ull,0x4080c0c0ull,0x1010101ull,0x502010101ull,0x301010101ull,0x3000000ull,0xe0d0f0f0f0ull,0xc0a0e0e0e0ull,0xa040e0e0e0ull,0x4080c0c0c0ull,0x20101010101ull,0x50a03010101ull,0x1b377bff8181ull,0x346bf9818181ull,0x68d0f1f1e1e1ull,0xd0a0e0e0e0e0ull,0xa040e0e0e0e0ull,0x4080c0c0c0c0ull,0x2010301010101ull,0x5020f01010101ull,0xa071f01818181ull,0x14087f81818181ull,0x2850f8f1e1c1c1ull,0x50a0f0e0e0c0c0ull,0xa040e0e0e0c0c0ull,0x4080c0c0c0c0c0ull,0x1030301010101ull,0x2070f03010101ull,0x40f1f7b818181ull,0x81c7ff9818181ull,0x1078f8f1c18181ull,0x20f0f0e0c08080ull,0x40e0e0e0c08080ull,0x80c0c0c0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x303ull,0x10207ull,0x30101ull,0x0ull,0x0ull,0xc0a0b0ull,0x8040e0ull,0x4080c0ull,0x30101ull,0x1070303ull,0x3000000ull,0x0ull,0x0ull,0xc0a0e0e0ull,0x8040c0c0ull,0x4080c0c0ull,0x1010101ull,0x102030303ull,0x301010101ull,0x3000000ull,0x0ull,0xc0a0e0e0e0ull,0x8040c0c0c0ull,0x4080c0c0c0ull,0x20101010101ull,0x50203030101ull,0xb1707010101ull,0x366bf7ff8181ull,0x68d4f1818181ull,0xd0a0e0e0c0c0ull,0xa040c0c0c0c0ull,0x4080c0c0c0c0ull,0x2010301010101ull,0x5020703010101ull,0xa071f01010101ull,0x14083f81818181ull,0x2810fc81818181ull,0x50a0f0e0c08080ull,0xa040e0c0c08080ull,0x4080c0c0c08080ull,0x1030301010101ull,0x2070703010101ull,0x40f1f07010101ull,0x81c3ff7818181ull,0x1038fcf1818181ull,0x20f0f0e0808080ull,0x40e0e0c0808080ull,0x80c0c0c0808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x10707ull,0x3050dull,0x0ull,0x0ull,0x0ull,0x8040e0ull,0x80c0ull,0x2030303ull,0x1070303ull,0x3050707ull,0x0ull,0x0ull,0x0ull,0x8040c0c0ull,0x808080ull,0x201030303ull,0x102030303ull,0x307070707ull,0x3000000ull,0x0ull,0x0ull,0x8040c0c0c0ull,0x80808080ull,0x20103030303ull,0x50203030303ull,0xb0707070303ull,0x162b8f818181ull,0x6cd6efff8181ull,0xd0a8e0808080ull,0xa040c0c08080ull,0x408080808080ull,0x2010303030101ull,0x5020703030101ull,0xa070f07030101ull,0x14083f81818181ull,0x2810fc81818181ull,0x50a0f880808080ull,0xa040e0c0808080ull,0x4080c080808080ull,0x1030303010101ull,0x2070703010101ull,0x40f0f07010101ull,0x81c3f8f818181ull,0x1038fcef818181ull,0x20f0f8e0808080ull,0x40e0e0c0808080ull,0x80c0c080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x50707ull,0x30d0dull,0x70b0bull,0x0ull,0x0ull,0x0ull,0x80c0ull,0x2030303ull,0x5070707ull,0x30d0707ull,0x70b0f0full,0x0ull,0x0ull,0x0ull,0x808080ull,0x201030303ull,0x502070707ull,0x307070707ull,0x70b0f0f0full,0x0ull,0x0ull,0x0ull,0x80808080ull,0x20103030303ull,0x50207070707ull,0xb0707070707ull,0x160b8f8f8787ull,0x2cd69f818181ull,0xd8acdeff8181ull,0xa050c0808080ull,0x408080808080ull,0x2010303030303ull,0x5020707070303ull,0xa070f07070303ull,0x140a1f8f878383ull,0x2810fe81818181ull,0x50a0f880818181ull,0xa040f080808080ull,0x4080c080808080ull,0x1030303030101ull,0x2070707030101ull,0x40f0f07030101ull,0x81e1f8f838181ull,0x1038fe9f818181ull,0x20f0f8de818181ull,0x40e0f0c0808080ull,0x80c0c080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0x50707ull,0xb0d0dull,0x70b0bull,0xf1717ull,0x0ull,0x0ull,0x0ull,0x6070707ull,0x5070707ull,0xb0d0f0full,0x70b0f0full,0xf171f1full,0x0ull,0x0ull,0x0ull,0x605070707ull,0x502070707ull,0xb070f0f0full,0x70b0f0f0full,0xe171f1f1full,0x0ull,0x0ull,0x0ull,0x60507070707ull,0x50207070707ull,0xb070f0f0f0full,0x160b8f8f8f8full,0x2c969f9f8f8full,0xd8acbe818181ull,0xb058bcfe8080ull,0x40a080808080ull,0x2050707070707ull,0x5020707070707ull,0xa070f0f0f0707ull,0x140a1f8f8f8787ull,0x2814be9f8f8787ull,0x50a0fc80818181ull,0xa040f080808080ull,0x4080e080808080ull,0x1070707070303ull,0x2070707070303ull,0x40f0f0f070303ull,0x81e1f8f878383ull,0x103cbe9f878383ull,0x20f0fcbe818181ull,0x40e0f0bc808080ull,0x80c0e080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0xb0d0dull,0x170b0bull,0xf1717ull,0x1f2f3full,0x0ull,0x0ull,0x6070707ull,0xd0f0f0full,0xb0d0f0full,0x171b1f1full,0xf171f1full,0x1eafbfbfull,0x0ull,0x0ull,0x605070707ull,0xd0a0f0f0full,0xb070f0f0full,0x171f1f1f1full,0xe171f1f1full,0x9c2ebfbfbfull,0x0ull,0x0ull,0x60507070707ull,0xd0a0f0f0f0full,0xb070f0f0f0full,0x161f1f9f9f9full,0x2c961f9f9f9full,0xd8ac3ebf9f9full,0xb0587c808080ull,0x60b078fc8080ull,0x2050707070707ull,0x50a0f0f0f0f0full,0xa070f0f0f0f0full,0x140a1f1f9f8f8full,0x2814be1f9f8f8full,0x50a8fc3e9f8f8full,0xa040f800808080ull,0x4080e000808080ull,0x1070707070707ull,0x20f0f0f0f0707ull,0x40f0f0f0f0707ull,0x81e1f1f8f8787ull,0x103cbe1f8f8787ull,0x20f8fc3e8f8787ull,0x40e0f87c808080ull,0x80c0e078808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x303ull,0x7c0207ull,0xf8f4fcull,0xf0e8e8ull,0xe8d0d0ull,0xd0a0b0ull,0xb050f0ull,0x60a0e0ull,0x6010101ull,0x5010101ull,0x78fdfdfdull,0xf0e8f8f8ull,0xe8d0f8f8ull,0xd0a0f0f0ull,0xb050f0f0ull,0x60a0e0e0ull,0x0ull,0x402010101ull,0x3877fdfdfdull,0x70ecf8f8f8ull,0xe8d8f8f8f8ull,0xd0a0f0f0f0ull,0xb050f0f0f0ull,0x60a0e0e0e0ull,0x1010101ull,0x50001010101ull,0x19347dfdf9f9ull,0x3068f8f8f8f8ull,0x68d0f8f8f8f8ull,0xd0a0f0f0f0f0ull,0xb050f0f0f0f0ull,0x60a0e0e0e0e0ull,0x201021f010101ull,0x5021e01010101ull,0xa173c7df9f1f1ull,0x142878f9f9f1f1ull,0x2850f8f8f8f0f0ull,0x50a0f0f0f0f0f0ull,0xa050f0f0f0f0f0ull,0x40a0e0e0e0e0e0ull,0x1010001010101ull,0x30001010101ull,0x1d3879f1e1e1ull,0x83878f9f1e1e1ull,0x1078f8f8f0e0e0ull,0x20f0f0f0f0e0e0ull,0x40f0f0f0f0e0e0ull,0x80e0e0e0e0e0e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x303ull,0x207ull,0xf8040cull,0xf0e8e8ull,0xe0d0d0ull,0xd0a0b0ull,0xa040e0ull,0x60a0e0ull,0x6010101ull,0x5010101ull,0x3010101ull,0xf0e8f8f8ull,0xe0d0f0f0ull,0xd0b0f0f0ull,0xa040e0e0ull,0x60a0e0e0ull,0x402010101ull,0x0ull,0x101010101ull,0x70e8f8f8f8ull,0xe0d0f0f0f0ull,0xd0a0f0f0f0ull,0xa040e0e0e0ull,0x60a0e0e0e0ull,0x101010101ull,0x50001010101ull,0x10101010101ull,0x3068f8f8f0f0ull,0x60d0f0f0f0f0ull,0xd0a0f0f0f0f0ull,0xa040e0e0e0e0ull,0x60a0e0e0e0e0ull,0x2010101010101ull,0x502053f010101ull,0xa073d01818181ull,0x142879f9f1e1e1ull,0x2850f0f0f0e0e0ull,0x50a0f0f0f0e0e0ull,0xa040e0e0e0e0e0ull,0x40a0e0e0e0e0e0ull,0x1010101010101ull,0x30101010101ull,0x50101818181ull,0x3871f1e1c1c1ull,0x1070f0f0e0c0c0ull,0x20f0f0f0e0c0c0ull,0x40e0e0e0e0c0c0ull,0x80e0e0e0e0c0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x303ull,0x10207ull,0x40cull,0xf00808ull,0xe0d0d0ull,0xc0a0b0ull,0xa040e0ull,0x4080c0ull,0x30101ull,0x5000101ull,0x3010101ull,0x0ull,0xe0d0f0f0ull,0xc0a0e0e0ull,0xa040e0e0ull,0x4080c0c0ull,0x3010101ull,0x107010101ull,0x0ull,0x300000000ull,0xe0d0f0f0f0ull,0xc0a0e0e0e0ull,0xa040e0e0e0ull,0x4080c0c0c0ull,0x101010101ull,0x50001010101ull,0x10101010101ull,0x300000000ull,0x60d0f0f0e0e0ull,0xc0a0e0e0e0e0ull,0xa040e0e0e0e0ull,0x4080c0c0c0c0ull,0x2010101010101ull,0x5020301010101ull,0xa070b7f818181ull,0x14087981818181ull,0x2850f0f0e0c0c0ull,0x50a0e0e0e0c0c0ull,0xa040e0e0e0c0c0ull,0x4080c0c0c0c0c0ull,0x1010101010101ull,0x30101010101ull,0x50101818181ull,0x80181818181ull,0x70e0e0c08080ull,0x20e0e0e0c08080ull,0x40e0e0e0c08080ull,0x80c0c0c0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x303ull,0x10207ull,0x3040cull,0x808ull,0xe01010ull,0xc0a0b0ull,0x8040e0ull,0x4080c0ull,0x30101ull,0x1070303ull,0x3010101ull,0x0ull,0x0ull,0xc0a0e0e0ull,0x8040c0c0ull,0x4080c0c0ull,0x3010101ull,0x107030303ull,0x300000000ull,0x0ull,0x0ull,0xc0a0e0e0e0ull,0x8040c0c0c0ull,0x4080c0c0c0ull,0x101010101ull,0x10203030101ull,0x10101010101ull,0x300000000ull,0x0ull,0xc0a0e0e0c0c0ull,0x8040c0c0c0c0ull,0x4080c0c0c0c0ull,0x2010101010101ull,0x5020303010101ull,0xa070701010101ull,0x140815ff818181ull,0x2810f080808080ull,0x50a0e0e0c08080ull,0xa040c0c0c08080ull,0x4080c0c0c08080ull,0x1010101010101ull,0x30101010101ull,0x50101010101ull,0x80181818181ull,0x108080808080ull,0xe0c0c0808080ull,0x40c0c0c0808080ull,0x80c0c0c0808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x10707ull,0x3050dull,0x70808ull,0x1010ull,0xc02030ull,0x8040e0ull,0x80c0ull,0x2030303ull,0x1070303ull,0x3050707ull,0x0ull,0x0ull,0x0ull,0x8040c0c0ull,0x808080ull,0x203030303ull,0x107030303ull,0x305070707ull,0x0ull,0x0ull,0x0ull,0x8040c0c0c0ull,0x80808080ull,0x20103030303ull,0x10203030303ull,0x30507070303ull,0x300000000ull,0x0ull,0x0ull,0x8040c0c08080ull,0x8080808080ull,0x2010303030101ull,0x5020303030101ull,0xa070707030101ull,0x14080f01010101ull,0x2810a8ff818181ull,0x50a0e080808080ull,0xa040c0c0808080ull,0x40808080808080ull,0x1030303010101ull,0x2030303010101ull,0x70303010101ull,0x80101010101ull,0x108081818181ull,0xa08080808080ull,0xc08080808080ull,0x80808080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x50707ull,0x30d0dull,0x70b0bull,0xf1010ull,0x2030ull,0x8040e0ull,0x80c0ull,0x2030303ull,0x5070707ull,0x30d0707ull,0x70b0f0full,0x0ull,0x0ull,0x0ull,0x808080ull,0x203030303ull,0x507070707ull,0x30d070707ull,0x70b0f0f0full,0x0ull,0x0ull,0x0ull,0x80808080ull,0x20103030303ull,0x50207070707ull,0x30707070707ull,0x60b0f0f0707ull,0x0ull,0x0ull,0x0ull,0x8080808080ull,0x2010303030303ull,0x5020707070303ull,0xa070707070303ull,0x140a0f0f070303ull,0x28109e81818181ull,0x50a0d0fe818181ull,0xa040c080808080ull,0x40808080808080ull,0x1030303030101ull,0x2070707030101ull,0x4070707030101ull,0xe0707030101ull,0x108081818181ull,0xa08080818181ull,0xc08080808080ull,0x80808080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0x50707ull,0xb0d0dull,0x70b0bull,0xf1717ull,0x1f2030ull,0x40e0ull,0x80c0ull,0x6070707ull,0x5070707ull,0xb0d0f0full,0x70b0f0full,0xf171f1full,0x0ull,0x0ull,0x0ull,0x607070707ull,0x507070707ull,0xb0d0f0f0full,0x70b0f0f0full,0xe171f1f1full,0x0ull,0x0ull,0x0ull,0x60507070707ull,0x50207070707ull,0xb070f0f0f0full,0x60b0f0f0f0full,0xc161f1f0f0full,0x0ull,0x0ull,0x0ull,0x2050707070707ull,0x5020707070707ull,0xa070f0f0f0707ull,0x140a0f0f0f0707ull,0x28149e9f8f8787ull,0x50a0bc80818181ull,0xa040a0fc808080ull,0x40808080808080ull,0x1070707070303ull,0x2070707070303ull,0x40f0f0f070303ull,0x80e0f0f070303ull,0x1c8e8f878383ull,0xa08080818181ull,0xc08080808080ull,0x80808080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0xb0d0dull,0x170b0bull,0xf1717ull,0x1f2f3full,0x3e40e0ull,0x80c0ull,0x6070707ull,0xd0f0f0full,0xb0d0f0full,0x170b1f1full,0xf171f1full,0x1eafbfbfull,0x0ull,0x0ull,0x607070707ull,0xd0f0f0f0full,0xb0d0f0f0full,0x171b1f1f1full,0xe171f1f1full,0x1caebfbfbfull,0x0ull,0x0ull,0x60507070707ull,0xd0a0f0f0f0full,0xb070f0f0f0full,0x161f1f1f1f1full,0xc161f1f1f1full,0x982cbebf9f9full,0x0ull,0x0ull,0x2050707070707ull,0x50a0f0f0f0f0full,0xa070f0f0f0f0full,0x140a1f1f1f0f0full,0x28141e9f9f8f8full,0x50a83cbe9f8f8full,0xa0407880808080ull,0x408040f8808080ull,0x1070707070707ull,0x20f0f0f0f0707ull,0x40f0f0f0f0707ull,0x81e1f1f0f0707ull,0x101c1e9f8f8787ull,0xb81c9e8f8787ull,0xc00080808080ull,0x80800080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x7d0207ull,0xfaf4fcull,0xf4e8e8ull,0xe8d0d0ull,0xd0a0b0ull,0xb050f0ull,0x60a0e0ull,0x3f3f3full,0x3c7a7f7full,0x78f5ffffull,0xf0e8fcfcull,0xe8d0f8f8ull,0xd0a0f0f0ull,0xb050f0f0ull,0x60a0e0e0ull,0x607010101ull,0x502010101ull,0x3875fdfdfdull,0x70e8f8f8f8ull,0xe8d0f8f8f8ull,0xd0a0f0f0f0ull,0xb050f0f0f0ull,0x60a0e0e0e0ull,0x0ull,0x40001010101ull,0x18357dfdfdfdull,0x3068f8f8f8f8ull,0x68d0f8f8f8f8ull,0xd0a0f0f0f0f0ull,0xb050f0f0f0f0ull,0x60a0e0e0e0e0ull,0x40707070707ull,0x5020707070707ull,0x8163d7df9f1f1ull,0x102878f8f8f0f0ull,0x2850f8f8f8f0f0ull,0x50a0f0f0f0f0f0ull,0xa050f0f0f0f0f0ull,0x40a0e0e0e0e0e0ull,0x1020101010101ull,0x2000101010101ull,0x1c3979f1e1e1ull,0x83878f8f0e0e0ull,0x1078f8f8f0e0e0ull,0x20f0f0f0f0e0e0ull,0x40f0f0f0f0e0e0ull,0x80e0e0e0e0e0e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x50207ull,0xfa040cull,0xf4e8e8ull,0xe8d0d0ull,0xd0a0b0ull,0xa040e0ull,0x60a0e0ull,0x30303ull,0x7a7f7full,0x78f4fefeull,0xf0e8fcfcull,0xe0d0f8f8ull,0xd0a0f0f0ull,0xa040e0e0ull,0x60a0e0e0ull,0x607010101ull,0x502010101ull,0x301010101ull,0x70e8f8f8f8ull,0xe0d0f0f0f0ull,0xd0a0f0f0f0ull,0xa040e0e0e0ull,0x60a0e0e0e0ull,0x1010101ull,0x0ull,0x10101010101ull,0x3068f8f8f8f8ull,0x60d0f0f0f0f0ull,0xd0a0f0f0f0f0ull,0xa040e0e0e0e0ull,0x60a0e0e0e0e0ull,0x50707070707ull,0x5000707070707ull,0x2010101010101ull,0x102878f8f0e0e0ull,0x2050f0f0f0e0e0ull,0x50a0f0f0f0e0e0ull,0xa040e0e0e0e0e0ull,0x40a0e0e0e0e0e0ull,0x1010101010101ull,0x50101010101ull,0x4000101818181ull,0x3870f0e0c0c0ull,0x1070f0f0e0c0c0ull,0x20f0f0f0e0c0c0ull,0x40e0e0e0e0c0c0ull,0x80e0e0e0e0c0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x50207ull,0xa040cull,0xf40808ull,0xe8d0d0ull,0xd0a0b0ull,0xa040e0ull,0x4080c0ull,0x30303ull,0x1020707ull,0xf5ffffull,0xf0e8fcfcull,0xe0d0f8f8ull,0xc0a0f0f0ull,0xa040e0e0ull,0x4080c0c0ull,0x3010101ull,0x502010101ull,0x301010101ull,0x0ull,0xe0d0f0f0f0ull,0xc0a0e0e0e0ull,0xa040e0e0e0ull,0x4080c0c0c0ull,0x301010101ull,0x10001010101ull,0x0ull,0x20000000000ull,0x60d0f0f0f0f0ull,0xc0a0e0e0e0e0ull,0xa040e0e0e0e0ull,0x4080c0c0c0c0ull,0x10101010101ull,0x5020707070707ull,0x2010101010101ull,0x20000000000ull,0x2050f0f0e0c0c0ull,0x40a0e0e0e0c0c0ull,0xa040e0e0e0c0c0ull,0x4080c0c0c0c0c0ull,0x1030101010101ull,0x2010101010101ull,0xa0101818181ull,0x8000080808080ull,0x70e0e0c08080ull,0x20e0e0e0c08080ull,0x40e0e0e0c08080ull,0x80c0c0c0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x50207ull,0xb040cull,0x140808ull,0xe81010ull,0xd0a0b0ull,0xa040e0ull,0x4080c0ull,0x30303ull,0x1070707ull,0x3050f0full,0xebffffull,0xe0d0f8f8ull,0xc0a0f0f0ull,0x8040e0e0ull,0x4080c0c0ull,0x3010101ull,0x107030303ull,0x301010101ull,0x0ull,0x0ull,0xc0a0e0e0e0ull,0x8040c0c0c0ull,0x4080c0c0c0ull,0x301010101ull,0x10703030303ull,0x0ull,0x0ull,0x0ull,0xc0a0e0e0e0e0ull,0x8040c0c0c0c0ull,0x4080c0c0c0c0ull,0x10101010101ull,0x1020303010101ull,0x2010101010101ull,0x20000000000ull,0x0ull,0x40a0e0e0c08080ull,0x8040c0c0c08080ull,0x4080c0c0c08080ull,0x1010101010101ull,0x30101010101ull,0x4010101010101ull,0x140181818181ull,0x10008080808080ull,0xe0c0c0808080ull,0x40c0c0c0808080ull,0x80c0c0c0808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x50707ull,0xb050dull,0x170808ull,0x281010ull,0xd02030ull,0xa040e0ull,0x4080c0ull,0x2030303ull,0x1070707ull,0x3050f0full,0x70b1f1full,0xd7ffffull,0xc0a0f0f0ull,0x8040e0e0ull,0x80c0c0ull,0x203030303ull,0x107030303ull,0x305070707ull,0x0ull,0x0ull,0x0ull,0x8040c0c0c0ull,0x80808080ull,0x20303030303ull,0x10703030303ull,0x30507070707ull,0x0ull,0x0ull,0x0ull,0x8040c0c0c0c0ull,0x8080808080ull,0x2010303030101ull,0x1020303030101ull,0x2050707030101ull,0x20000000000ull,0x0ull,0x0ull,0x8040c0c0808080ull,0x808080808080ull,0x1030303010101ull,0x2030303010101ull,0x70303010101ull,0x8000101010101ull,0x288081818181ull,0x20808080808080ull,0xc08080808080ull,0x80808080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x20303ull,0x50707ull,0xb0d0dull,0x170b0bull,0x2f1010ull,0x502030ull,0xa040e0ull,0x4080c0ull,0x2030303ull,0x5070707ull,0x30d0f0full,0x70b1f1full,0xf173f3full,0xafffffull,0x8040e0e0ull,0x80c0c0ull,0x203030303ull,0x507070707ull,0x30d070707ull,0x70b0f0f0full,0x0ull,0x0ull,0x0ull,0x80808080ull,0x20303030303ull,0x50707070707ull,0x30d07070707ull,0x60b0f0f0f0full,0x0ull,0x0ull,0x0ull,0x8080808080ull,0x2010303030303ull,0x5020707070303ull,0x2070707070303ull,0x40a0f0f070303ull,0x0ull,0x0ull,0x0ull,0x808080808080ull,0x1030303030101ull,0x2070707030101ull,0x4070707030101ull,0xe0707030101ull,0x10000001010101ull,0x508080818181ull,0x40808080808080ull,0x80c08080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0x50707ull,0xb0d0dull,0x170b0bull,0x2f1717ull,0x5f2030ull,0xa040e0ull,0x4080c0ull,0x6070707ull,0x5070707ull,0xb0d0f0full,0x70b1f1full,0xf173f3full,0x1e2f7f7full,0x5efefeull,0x80c0c0ull,0x607070707ull,0x507070707ull,0xb0d0f0f0full,0x70b0f0f0full,0xe171f1f1full,0x0ull,0x0ull,0x0ull,0x60707070707ull,0x50707070707ull,0xb0d0f0f0f0full,0x60b0f0f0f0full,0xc161f1f1f1full,0x0ull,0x0ull,0x0ull,0x2050707070707ull,0x5020707070707ull,0xa070f0f0f0707ull,0x40a0f0f0f0707ull,0x8141e1f0f0707ull,0x0ull,0x0ull,0x0ull,0x1070707070303ull,0x2070707070303ull,0x40f0f0f070303ull,0x80e0f0f070303ull,0x1c0e0f070303ull,0x20008080818181ull,0xa08080808080ull,0x80808080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0xb0d0dull,0x170b0bull,0x2f1717ull,0x5f2f3full,0xbe40e0ull,0x4080c0ull,0x6070707ull,0xd0f0f0full,0xb0d0f0full,0x170b1f1full,0xf173f3full,0x1eafffffull,0x3c5efefeull,0xbcfcfcull,0x607070707ull,0xd0f0f0f0full,0xb0d0f0f0full,0x170b1f1f1full,0xe171f1f1full,0x1caebfbfbfull,0x0ull,0x0ull,0x60707070707ull,0xd0f0f0f0f0full,0xb0d0f0f0f0full,0x161b1f1f1f1full,0xc161f1f1f1full,0x18acbebfbfbfull,0x0ull,0x0ull,0x2050707070707ull,0x50a0f0f0f0f0full,0xa070f0f0f0f0full,0x140a1f1f1f0f0full,0x8141e1f1f0f0full,0x1028bcbe9f8f8full,0x0ull,0x0ull,0x1070707070707ull,0x20f0f0f0f0707ull,0x40f0f0f0f0707ull,0x81e1f1f0f0707ull,0x101c1e1f0f0707ull,0x389c9e8f8787ull,0x40008080808080ull,0x80408080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x3e3f3full,0x7d7f7full,0xfbfdfdull,0xf6eaeaull,0xecd4d4ull,0xd8a8b8ull,0xb050f0ull,0x60a0e0ull,0x23f3f3full,0x3d7f7f7full,0x7afdffffull,0xf4eafefeull,0xe8d4fcfcull,0xd0a8f8f8ull,0xb050f0f0ull,0x60a0e0e0ull,0x1f3f3f3full,0x1c3f7f7f7full,0x387dffffffull,0x70e8fcfefeull,0xe8d0f8fcfcull,0xd0a0f0f8f8ull,0xb050f0f0f0ull,0x60a0e0e0e0ull,0x101010101ull,0x50101010101ull,0x183d7dfdfdfdull,0x3068f8f8f8f8ull,0x68d0f8f8f8f8ull,0xd0a0f0f0f0f0ull,0xb050f0f0f0f0ull,0x60a0e0e0e0e0ull,0x0ull,0x4020707070707ull,0x8173d7dfdfdfdull,0x102878f8f8f8f8ull,0x2850f8f8f8f8f8ull,0x50a0f0f0f0f0f0ull,0xa050f0f0f0f0f0ull,0x40a0e0e0e0e0e0ull,0x70707070303ull,0x70707070303ull,0x1d3979f1e1e1ull,0x83878f8f0e0e0ull,0x1078f8f8f0e0e0ull,0x20f0f0f0f0e0e0ull,0x40f0f0f0f0e0e0ull,0x80e0e0e0e0e0e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0x7d7f7full,0xfbfdfdull,0xf6eaeaull,0xecd4d4ull,0xd8a8b8ull,0xb050f0ull,0x60a0e0ull,0x2070707ull,0x57f7f7full,0x7afdffffull,0xf4eafefeull,0xe8d4fcfcull,0xd0a8f8f8ull,0xa050f0f0ull,0x60a0e0e0ull,0x3030707ull,0x3f7f7f7full,0x387cffffffull,0x70e8fcfefeull,0xe0d0f8fcfcull,0xd0a0f0f8f8ull,0xa040e0f0f0ull,0x60a0e0e0e0ull,0x101010101ull,0x50101010101ull,0x10101010101ull,0x3068f8f8f8f8ull,0x60d0f0f0f0f0ull,0xd0a0f0f0f0f0ull,0xa040e0e0e0e0ull,0x60a0e0e0e0e0ull,0x4020707070707ull,0x0ull,0x30101010101ull,0x102878f8f8f8f8ull,0x2050f0f0f0f0f0ull,0x50a0f0f0f0f0f0ull,0xa040e0e0e0e0e0ull,0x40a0e0e0e0e0e0ull,0x1070707070303ull,0x70707070303ull,0x30101010101ull,0x3870f0e0c0c0ull,0x1070f0f0e0c0c0ull,0x20f0f0f0e0c0c0ull,0x40e0e0e0e0c0c0ull,0x80e0e0e0e0c0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0a0full,0xfbf5fdull,0xf6eaeaull,0xecd4d4ull,0xd8a8b8ull,0xb050f0ull,0x60a0e0ull,0x2070707ull,0x50a0f0full,0xaf5ffffull,0xf4eafefeull,0xe8d4fcfcull,0xd0a8f8f8ull,0xa050f0f0ull,0x40a0e0e0ull,0x3030707ull,0x102070f0full,0x75ffffffull,0x70e8fcfefeull,0xe0d0f8fcfcull,0xc0a0f0f8f8ull,0xa040e0f0f0ull,0x4080c0e0e0ull,0x301010101ull,0x50101010101ull,0x10101010101ull,0x0ull,0x60d0f0f0f0f0ull,0xc0a0e0e0e0e0ull,0xa040e0e0e0e0ull,0x4080c0c0c0c0ull,0x30101010101ull,0x70707070707ull,0x0ull,0x0ull,0x2050f0f0f0f0f0ull,0x40a0e0e0e0e0e0ull,0xa040e0e0e0e0e0ull,0x4080c0c0c0c0c0ull,0x1010101010101ull,0x70707070303ull,0x30101010101ull,0x0ull,0x70e0e0c08080ull,0x20e0e0e0c08080ull,0x40e0e0e0c08080ull,0x80c0c0c0c08080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0x1b151dull,0xf7ebebull,0xecd4d4ull,0xd8a8b8ull,0xb050f0ull,0x60a0e0ull,0x2070707ull,0x50f0f0full,0xb151f1full,0x14ebffffull,0xe8d4fcfcull,0xd0a8f8f8ull,0xa050f0f0ull,0x40a0e0e0ull,0x3030707ull,0x107070f0full,0x3050f1f1full,0xebffffffull,0xe0d0f8fcfcull,0xc0a0f0f8f8ull,0x8040e0f0f0ull,0x4080c0e0e0ull,0x301010101ull,0x10703030303ull,0x10101010101ull,0x0ull,0x0ull,0xc0a0e0e0e0e0ull,0x8040c0c0c0c0ull,0x4080c0c0c0c0ull,0x30101010101ull,0x1070303030303ull,0x0ull,0x0ull,0x0ull,0x40a0e0e0e0e0e0ull,0x8040c0c0c0c0c0ull,0x4080c0c0c0c0c0ull,0x1010101010101ull,0x30101010101ull,0x30101010101ull,0x0ull,0x0ull,0xe0c0c0808080ull,0x40c0c0c0808080ull,0x80c0c0c0808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0x1b151dull,0x372b2bull,0xefd7d7ull,0xd8a8b8ull,0xb050f0ull,0x60a0e0ull,0x2070707ull,0x50f0f0full,0xb151f1full,0x172b3f3full,0x28d7ffffull,0xd0a8f8f8ull,0xa050f0f0ull,0x40a0e0e0ull,0x203030707ull,0x107070f0full,0x3050f1f1full,0x70b1f3f3full,0xd7ffffffull,0xc0a0f0f8f8ull,0x8040e0f0f0ull,0x80c0e0e0ull,0x20303030303ull,0x10703030303ull,0x30507070707ull,0x0ull,0x0ull,0x0ull,0x8040c0c0c0c0ull,0x8080808080ull,0x2030303030303ull,0x1070303030303ull,0x2050707070707ull,0x0ull,0x0ull,0x0ull,0x8040c0c0c0c0c0ull,0x808080808080ull,0x1030303010101ull,0x2030303010101ull,0x70303010101ull,0x0ull,0x0ull,0x0ull,0xc08080808080ull,0x80808080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0x1b1d1dull,0x372b2bull,0x6f5757ull,0xdfafbfull,0xb050f0ull,0x60a0e0ull,0x2070707ull,0x50f0f0full,0xb1d1f1full,0x172b3f3full,0x2f577f7full,0x50afffffull,0xa050f0f0ull,0x40a0e0e0ull,0x203030707ull,0x507070f0full,0x30d0f1f1full,0x70b1f3f3full,0xe173f7f7full,0xaeffffffull,0x8040e0f0f0ull,0x80c0e0e0ull,0x20303030303ull,0x50707070707ull,0x30d07070707ull,0x60b0f0f0f0full,0x0ull,0x0ull,0x0ull,0x8080808080ull,0x2030303030303ull,0x5070707070707ull,0x20d0707070707ull,0x40a0f0f0f0f0full,0x0ull,0x0ull,0x0ull,0x808080808080ull,0x1030303030101ull,0x2070707030101ull,0x4070707030101ull,0xe0707030101ull,0x0ull,0x0ull,0x0ull,0x80808080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0x1b1d1dull,0x372b2bull,0x6f5757ull,0xdfafbfull,0xbe5efeull,0x60a0e0ull,0x6070707ull,0x50f0f0full,0xb1d1f1full,0x172b3f3full,0x2f577f7full,0x5eafffffull,0xa05efefeull,0x40a0e0e0ull,0x607070707ull,0x507070f0full,0xb0d0f1f1full,0x70b1f3f3full,0xe173f7f7full,0x1c2effffffull,0x5cfefefeull,0x80c0e0e0ull,0x60707070707ull,0x50707070707ull,0xb0d0f0f0f0full,0x60b0f0f0f0full,0xc161f1f1f1full,0x0ull,0x0ull,0x0ull,0x2070707070707ull,0x5070707070707ull,0xa0d0f0f0f0f0full,0x40a0f0f0f0f0full,0x8141e1f1f1f1full,0x0ull,0x0ull,0x0ull,0x1070707070303ull,0x2070707070303ull,0x40f0f0f070303ull,0x80e0f0f070303ull,0x1c0e0f070303ull,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x60707ull,0xd0f0full,0x1b1d1dull,0x372b2bull,0x6f5757ull,0xdfafbfull,0xbe5efeull,0x7cbcfcull,0x6070707ull,0xd0f0f0full,0xb1d1f1full,0x172b3f3full,0x2f577f7full,0x5eafffffull,0xbc5efefeull,0x40bcfcfcull,0x607070707ull,0xd0f0f0f0full,0xb0d0f1f1full,0x170b1f3f3full,0xe173f7f7full,0x1caeffffffull,0x385cfefefeull,0xb8fcfcfcull,0x60707070707ull,0xd0f0f0f0f0full,0xb0d0f0f0f0full,0x160b1f1f1f1full,0xc161f1f1f1full,0x18acbebfbfbfull,0x0ull,0x0ull,0x2070707070707ull,0x50f0f0f0f0f0full,0xa0d0f0f0f0f0full,0x140a1f1f1f1f1full,0x8141e1f1f1f1full,0x10a8bcbebfbfbfull,0x0ull,0x0ull,0x1070707070707ull,0x20f0f0f0f0707ull,0x40f0f0f0f0707ull,0x81e1f1f0f0707ull,0x101c1e1f0f0707ull,0xb89c9e8f8787ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x3e3f3full,0x7d7f7full,0xfbfdfdull,0xf7ebebull,0xeed6d6ull,0xdcacbcull,0xb858f8ull,0x70b0f0ull,0x1e3f3f3full,0x3d7f7f7full,0x7bfdffffull,0xf6ebffffull,0xecd6fefeull,0xd8acfcfcull,0xb058f8f8ull,0x60b0f0f0ull,0x21f3f3f3full,0x1d3f7f7f7full,0x3a7dffffffull,0x74eaffffffull,0xe8d4fefefeull,0xd0a8fcfcfcull,0xb050f8f8f8ull,0x60a0f0f0f0ull,0xf1f3f3f3full,0xd1f3f7f7f7full,0x183d7fffffffull,0x3068fcffffffull,0x68d0f8fcfefeull,0xd0a0f0f8fcfcull,0xb050f0f0f8f8ull,0x60a0e0e0f0f0ull,0x70707070707ull,0x5020707070707ull,0x9153d7dfdfdfdull,0x102878f8f8f8f8ull,0x2850f8f8f8f8f8ull,0x50a0f0f0f0f0f0ull,0xa050f0f0f0f0f0ull,0x40a0e0e0e0e0e0ull,0x0ull,0x70707070303ull,0x51d3d7dfdfdfdull,0x83878f8f8f8f8ull,0x1078f8f8f8f8f8ull,0x20f0f0f0f0f0f0ull,0x40f0f0f0f0f0f0ull,0x80e0e0e0e0e0e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0xe0f0full,0x7d7f7full,0xfbfdfdull,0xf7ebebull,0xeed6d6ull,0xdcacbcull,0xb858f8ull,0x70b0f0ull,0x60f0f0full,0x3d7f7f7full,0x7bfdffffull,0xf6ebffffull,0xecd6fefeull,0xd8acfcfcull,0xb058f8f8ull,0x60b0f0f0ull,0x2070f0f0full,0x53f7f7f7full,0x3a7dffffffull,0x74eaffffffull,0xe8d4fefefeull,0xd0a8fcfcfcull,0xa050f8f8f8ull,0x60a0f0f0f0ull,0x303070f0full,0x1f3f7f7f7full,0x183c7fffffffull,0x3068fcffffffull,0x60d0f8fcfefeull,0xd0a0f0f8fcfcull,0xa040e0f0f8f8ull,0x60a0e0e0f0f0ull,0x70707070707ull,0x5020707070707ull,0x2010101010101ull,0x102878f8f8f8f8ull,0x2050f0f0f0f0f0ull,0x50a0f0f0f0f0f0ull,0xa040e0e0e0e0e0ull,0x40a0e0e0e0e0e0ull,0x70707070303ull,0x0ull,0x30101010101ull,0x83878f8f8f8f8ull,0x1070f0f0f0f0f0ull,0x20f0f0f0f0f0f0ull,0x40e0e0e0e0e0e0ull,0x80e0e0e0e0e0e0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0xe0f0full,0x1d1a1full,0xfbf5fdull,0xf7ebebull,0xeed6d6ull,0xdcacbcull,0xb858f8ull,0x70b0f0ull,0x60f0f0full,0xd1a1f1full,0x7bf5ffffull,0xf6ebffffull,0xecd6fefeull,0xd8acfcfcull,0xb058f8f8ull,0x60b0f0f0ull,0x2070f0f0full,0x50a1f1f1full,0xa75ffffffull,0x74eaffffffull,0xe8d4fefefeull,0xd0a8fcfcfcull,0xa050f8f8f8ull,0x40a0f0f0f0ull,0x303070f0full,0x107070f1f1full,0x357fffffffull,0x3068fcffffffull,0x60d0f8fcfefeull,0xc0a0f0f8fcfcull,0xa040e0f0f8f8ull,0x4080c0e0f0f0ull,0x30101010101ull,0x5070707070707ull,0x2010101010101ull,0x0ull,0x2050f0f0f0f0f0ull,0x40a0e0e0e0e0e0ull,0xa040e0e0e0e0e0ull,0x4080c0c0c0c0c0ull,0x1010101010101ull,0xf0f0f0f0707ull,0x0ull,0x0ull,0x1070f0f0f0f0f0ull,0x20e0e0e0e0e0e0ull,0x40e0e0e0e0e0e0ull,0x80c0c0c0c0c0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0xe0f0full,0x1d1f1full,0x3b353dull,0xf7ebebull,0xeed6d6ull,0xdcacbcull,0xb858f8ull,0x70b0f0ull,0x60f0f0full,0xd1f1f1full,0x1b353f3full,0xf7ebffffull,0xecd6fefeull,0xd8acfcfcull,0xb058f8f8ull,0x60b0f0f0ull,0x2070f0f0full,0x50f1f1f1full,0xb153f3f3full,0x14ebffffffull,0xe8d4fefefeull,0xd0a8fcfcfcull,0xa050f8f8f8ull,0x40a0f0f0f0ull,0x303070f0full,0x107070f1f1full,0x3050f1f3f3full,0x6bffffffffull,0x60d0f8fcfefeull,0xc0a0f0f8fcfcull,0x8040e0f0f8f8ull,0x4080c0e0f0f0ull,0x30101010101ull,0x1070303030303ull,0x2010101010101ull,0x0ull,0x0ull,0x40a0e0e0e0e0e0ull,0x8040c0c0c0c0c0ull,0x4080c0c0c0c0c0ull,0x1030101010101ull,0x2030303030303ull,0x0ull,0x0ull,0x0ull,0x20e0e0e0e0e0e0ull,0x40c0c0c0c0c0c0ull,0x80c0c0c0c0c0c0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0xe0f0full,0x1d1f1full,0x3b353dull,0x776b6bull,0xefd7d7ull,0xdcacbcull,0xb858f8ull,0x70b0f0ull,0x60f0f0full,0xd1f1f1full,0x1b353f3full,0x376b7f7full,0xefd7ffffull,0xd8acfcfcull,0xb058f8f8ull,0x60b0f0f0ull,0x2070f0f0full,0x50f1f1f1full,0xb153f3f3full,0x172b7f7f7full,0x28d7ffffffull,0xd0a8fcfcfcull,0xa050f8f8f8ull,0x40a0f0f0f0ull,0x20303070f0full,0x107070f1f1full,0x3050f1f3f3full,0x60b1f3f7f7full,0xd6ffffffffull,0xc0a0f0f8fcfcull,0x8040e0f0f8f8ull,0x80c0e0f0f0ull,0x2030303030303ull,0x1070303030303ull,0x2050707070707ull,0x0ull,0x0ull,0x0ull,0x8040c0c0c0c0c0ull,0x808080808080ull,0x1030303030303ull,0x6030303030303ull,0x4070707070707ull,0x0ull,0x0ull,0x0ull,0x40c0c0c0c0c0c0ull,0x80c08080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0xe0f0full,0x1d1f1full,0x3b3d3dull,0x776b6bull,0xefd7d7ull,0xdfafbfull,0xb858f8ull,0x70b0f0ull,0x60f0f0full,0xd1f1f1full,0x1b3d3f3full,0x376b7f7full,0x6fd7ffffull,0xdeafffffull,0xb058f8f8ull,0x60b0f0f0ull,0x2070f0f0full,0x50f1f1f1full,0xb1d3f3f3full,0x172b7f7f7full,0x2e57ffffffull,0x50aeffffffull,0xa050f8f8f8ull,0x40a0f0f0f0ull,0x20303070f0full,0x507070f1f1full,0x30d0f1f3f3full,0x60b1f3f7f7full,0xc163fffffffull,0xacfeffffffull,0x8040e0f0f8f8ull,0x80c0e0f0f0ull,0x2030303030303ull,0x5070707070707ull,0x20d0707070707ull,0x40a0f0f0f0f0full,0x0ull,0x0ull,0x0ull,0x808080808080ull,0x1030303030303ull,0x6070707070707ull,0x4070707070707ull,0x80e0f0f0f0f0full,0x0ull,0x0ull,0x0ull,0x80808080808080ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0xe0f0full,0x1d1f1full,0x3b3d3dull,0x776b6bull,0xefd7d7ull,0xdfafbfull,0xbe5efeull,0x70b0f0ull,0x60f0f0full,0xd1f1f1full,0x1b3d3f3full,0x376b7f7full,0x6fd7ffffull,0xdeafffffull,0xbc5efefeull,0x60b0f0f0ull,0x6070f0f0full,0x50f1f1f1full,0xb1d3f3f3full,0x172b7f7f7full,0x2e57ffffffull,0x5caeffffffull,0xa05cfefefeull,0x40a0f0f0f0ull,0x60707070f0full,0x507070f1f1full,0xb0d0f1f3f3full,0x60b1f3f7f7full,0xc163fffffffull,0x182cfeffffffull,0x58fcfefefeull,0x80c0e0f0f0ull,0x2070707070707ull,0x5070707070707ull,0xa0d0f0f0f0f0full,0x40a0f0f0f0f0full,0x8141e1f1f1f1full,0x0ull,0x0ull,0x0ull,0x1070707070707ull,0x6070707070707ull,0x40f0f0f0f0f0full,0x80e0f0f0f0f0full,0x101c1e1f1f1f1full,0x0ull,0x0ull,0x0ull}, - {0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0x0ull,0xe0f0full,0x1d1f1full,0x3b3d3dull,0x776b6bull,0xefd7d7ull,0xdfafbfull,0xbe5efeull,0x7cbcfcull,0x60f0f0full,0xd1f1f1full,0x1b3d3f3full,0x376b7f7full,0x6fd7ffffull,0xdeafffffull,0xbc5efefeull,0x78bcfcfcull,0x6070f0f0full,0xd0f1f1f1full,0xb1d3f3f3full,0x172b7f7f7full,0x2e57ffffffull,0x5caeffffffull,0xb85cfefefeull,0x40b8fcfcfcull,0x60707070f0full,0xd0f0f0f1f1full,0xb0d0f1f3f3full,0x160b1f3f7f7full,0xc163fffffffull,0x18acfeffffffull,0xb058fcfefefeull,0xb0f8fcfcfcull,0x2070707070707ull,0x50f0f0f0f0f0full,0xa0d0f0f0f0f0full,0x140a1f1f1f1f1full,0x8141e1f1f1f1full,0x90a8bcbebfbfbfull,0x0ull,0x0ull,0x1070707070707ull,0x60f0f0f0f0f0full,0x40f0f0f0f0f0full,0x81e1f1f1f1f1full,0x101c1e1f1f1f1full,0xa0b8bcbebfbfbfull,0x0ull,0x0ull} - - - } - }; - - inline bool isDraw(const int winSide, const int side, const int kw, const int kb, const int pawnQueenPos) { - return winSide == WHITE ? KPK_WHITE_PAWN[side][kw][kb] & (1ULL << pawnQueenPos) : KPK_BLACK_PAWN[side][kw][kb] - & (1ULL << pawnQueenPos); - } -} diff --git a/src/db/gaviota/GTB.cpp b/src/db/gaviota/GTB.cpp index 568e137c..d563d5e0 100644 --- a/src/db/gaviota/GTB.cpp +++ b/src/db/gaviota/GTB.cpp @@ -180,12 +180,12 @@ int GTB::getDtmWdl(const int stm, const int doPrint, const _Tchessboard &chessboard, unsigned *pliestomate, - const bool dtm) const { + const bool dtm, const uchar RIGHT_CASTLE) const { unsigned info = tb_UNKNOWN; /* default, no tbvalue */ GTBchessboard gtbChessboard; - gtbChessboard.fromChessboard(chessboard); + gtbChessboard.fromChessboard(chessboard, RIGHT_CASTLE); if (dtm) { int tb_available = tb_probe_soft(stm, tb_NOSQUARE, gtbChessboard.tb_castling, gtbChessboard.ws, gtbChessboard.bs, @@ -197,7 +197,7 @@ int GTB::getDtmWdl(const int stm, if (tb_available) { if (doPrint != 0) { - const int stm1 = (doPrint == 1) ? stm : (stm ^ 1); + const int stm1 = (doPrint == 1) ? stm : X(stm); if (info == tb_DRAW) { cout << "Draw"; } else if (info == tb_WMATE && stm1 == tb_WHITE_TO_MOVE) { @@ -213,7 +213,7 @@ int GTB::getDtmWdl(const int stm, } cout << endl; } - ASSERT(info != tb_UNKNOWN) + assert(info != tb_UNKNOWN); return convertToSyzygy(stm, info); } return INT_MAX; @@ -227,7 +227,7 @@ int GTB::getDtmWdl(const int stm, if (tb_available) { if (doPrint != 0) { - const int stm1 = (doPrint == 1) ? stm : (stm ^ 1); + const int stm1 = (doPrint == 1) ? stm : X(stm); switch (info) { case tb_WMATE : if (stm1 == tb_WHITE_TO_MOVE) cout << "Loss" << endl; @@ -245,7 +245,7 @@ int GTB::getDtmWdl(const int stm, break; } } - ASSERT(info != tb_UNKNOWN) + assert(info != tb_UNKNOWN); return convertToSyzygy(stm, info); } if (doPrint != 0) cout << "none" << endl; diff --git a/src/db/gaviota/GTB.h b/src/db/gaviota/GTB.h index 0b2bebae..2434d95a 100644 --- a/src/db/gaviota/GTB.h +++ b/src/db/gaviota/GTB.h @@ -18,25 +18,22 @@ #pragma once -#include "../../lib/gtb-probe.h" +#include "gtb/gtb-probe.h" #include "../../namespaces/bits.h" #include "../../ChessBoard.h" #include "../../util/Singleton.h" -#define GTB_WHITE 0 -#define GTB_BLACK 1 #define GTB_STM(a) ((a)^1) struct GTBchessboard { - uchar rightCastle; unsigned int tb_castling; unsigned int ws[17]; /* list of squares for white */ unsigned int bs[17]; /* list of squares for black */ unsigned char wp[17]; /* what white pieces are on those squares */ unsigned char bp[17]; /* what black pieces are on those squares */ - void fromChessboard(const _Tchessboard &chessboard) { + void fromChessboard(const _Tchessboard &chessboard, const uchar rightCastle) { static const int DECODE_PIECE[13] = {tb_PAWN, tb_PAWN, tb_ROOK, tb_ROOK, tb_BISHOP, tb_BISHOP, tb_KNIGHT, tb_KNIGHT, tb_KING, tb_KING, tb_QUEEN, @@ -58,7 +55,6 @@ struct GTBchessboard { int count = 0; - rightCastle = chessboard[RIGHT_CASTLE_IDX]; //white for (int piece = 1; piece < 12; piece += 2) { for (u64 b = chessboard[piece]; b; RESET_LSB(b)) { @@ -120,7 +116,7 @@ class GTB : public Singleton { bool isInstalledPieces(const int p) const; int getDtmWdl(const int side, const int doPrint, const _Tchessboard &chessboard, unsigned *pliestomate, - const bool dtm) const; + const bool dtm, const uchar RIGHT_CASTLE) const; private: GTB(); diff --git a/src/db/gaviota/gtb/compression/lzma/Alloc.c b/src/db/gaviota/gtb/compression/lzma/Alloc.c new file mode 100755 index 00000000..b04d715f --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Alloc.c @@ -0,0 +1,127 @@ +/* Alloc.c -- Memory allocation functions +2008-09-24 +Igor Pavlov +Public domain */ + +#if _WIN32 || _WIN64 +#include +#endif +#include + +#include "Alloc.h" + +/* #define _SZ_ALLOC_DEBUG */ + +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef _SZ_ALLOC_DEBUG +#include +int g_allocCount = 0; +int g_allocCountMid = 0; +int g_allocCountBig = 0; +#endif + +void *MyAlloc(size_t size) +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + { + void *p = malloc(size); + fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p); + return p; + } + #else + return malloc(size); + #endif +} + +void MyFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address); + #endif + free(address); +} + +#if _WIN32 || _WIN64 + +void *MidAlloc(size_t size) +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); + #endif + return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void MidFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid); + #endif + if (address == 0) + return; + VirtualFree(address, 0, MEM_RELEASE); +} + +#ifndef MEM_LARGE_PAGES +#undef _7ZIP_LARGE_PAGES +#endif + +#ifdef _7ZIP_LARGE_PAGES +SIZE_T g_LargePageSize = 0; +typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); +#endif + +void SetLargePageSize() +{ + #ifdef _7ZIP_LARGE_PAGES + SIZE_T size = 0; + GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) + GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); + if (largePageMinimum == 0) + return; + size = largePageMinimum(); + if (size == 0 || (size & (size - 1)) != 0) + return; + g_LargePageSize = size; + #endif +} + + +void *BigAlloc(size_t size) +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); + #endif + + #ifdef _7ZIP_LARGE_PAGES + if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18)) + { + void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)), + MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + if (res != 0) + return res; + } + #endif + return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void BigFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); + #endif + + if (address == 0) + return; + VirtualFree(address, 0, MEM_RELEASE); +} + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/Alloc.h b/src/db/gaviota/gtb/compression/lzma/Alloc.h new file mode 100755 index 00000000..8b9f4eb7 --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Alloc.h @@ -0,0 +1,32 @@ +/* Alloc.h -- Memory allocation functions +2008-03-13 +Igor Pavlov +Public domain */ + +#ifndef __COMMON_ALLOC_H +#define __COMMON_ALLOC_H + +#include + +void *MyAlloc(size_t size); +void MyFree(void *address); + +#if _WIN32 || _WIN64 || _WIN64 + +void SetLargePageSize(); + +void *MidAlloc(size_t size); +void MidFree(void *address); +void *BigAlloc(size_t size); +void BigFree(void *address); + +#else + +#define MidAlloc(size) MyAlloc(size) +#define MidFree(address) MyFree(address) +#define BigAlloc(size) MyAlloc(size) +#define BigFree(address) MyFree(address) + +#endif + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/Bra.h b/src/db/gaviota/gtb/compression/lzma/Bra.h new file mode 100755 index 00000000..45e231e8 --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Bra.h @@ -0,0 +1,60 @@ +/* Bra.h -- Branch converters for executables +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __BRA_H +#define __BRA_H + +#include "Types.h" + +/* +These functions convert relative addresses to absolute addresses +in CALL instructions to increase the compression ratio. + + In: + data - data buffer + size - size of data + ip - current virtual Instruction Pinter (IP) value + state - state variable for x86 converter + encoding - 0 (for decoding), 1 (for encoding) + + Out: + state - state variable for x86 converter + + Returns: + The number of processed bytes. If you call these functions with multiple calls, + you must start next call with first byte after block of processed bytes. + + Type Endian Alignment LookAhead + + x86 little 1 4 + ARMT little 2 2 + ARM little 4 0 + PPC big 4 0 + SPARC big 4 0 + IA64 little 16 0 + + size must be >= Alignment + LookAhead, if it's not last block. + If (size < Alignment + LookAhead), converter returns 0. + + Example: + + UInt32 ip = 0; + for () + { + ; size must be >= Alignment + LookAhead, if it's not last block + SizeT processed = Convert(data, size, ip, 1); + data += processed; + size -= processed; + ip += processed; + } +*/ + +#define x86_Convert_Init(state) { state = 0; } +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/Bra86.c b/src/db/gaviota/gtb/compression/lzma/Bra86.c new file mode 100755 index 00000000..7debb565 --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Bra86.c @@ -0,0 +1,85 @@ +/* Bra86.c -- Converter for x86 code (BCJ) +2008-10-04 : Igor Pavlov : Public domain */ + +#include "Bra.h" + +#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) + +const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; +const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; + +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) +{ + SizeT bufferPos = 0, prevPosT; + UInt32 prevMask = *state & 0x7; + if (size < 5) + return 0; + ip += 5; + prevPosT = (SizeT)0 - 1; + + for (;;) + { + Byte *p = data + bufferPos; + Byte *limit = data + size - 4; + for (; p < limit; p++) + if ((*p & 0xFE) == 0xE8) + break; + bufferPos = (SizeT)(p - data); + if (p >= limit) + break; + prevPosT = bufferPos - prevPosT; + if (prevPosT > 3) + prevMask = 0; + else + { + prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; + if (prevMask != 0) + { + Byte b = p[4 - kMaskToBitNumber[prevMask]]; + if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) + { + prevPosT = bufferPos; + prevMask = ((prevMask << 1) & 0x7) | 1; + bufferPos++; + continue; + } + } + } + prevPosT = bufferPos; + + if (Test86MSByte(p[4])) + { + UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); + UInt32 dest; + for (;;) + { + Byte b; + int index; + if (encoding) + dest = (ip + (UInt32)bufferPos) + src; + else + dest = src - (ip + (UInt32)bufferPos); + if (prevMask == 0) + break; + index = kMaskToBitNumber[prevMask] * 8; + b = (Byte)(dest >> (24 - index)); + if (!Test86MSByte(b)) + break; + src = dest ^ (((UInt32)1 << (32 - index)) - (UInt32)1); + } + p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); + p[3] = (Byte)(dest >> 16); + p[2] = (Byte)(dest >> 8); + p[1] = (Byte)dest; + bufferPos += 5; + } + else + { + prevMask = ((prevMask << 1) & 0x7) | 1; + bufferPos++; + } + } + prevPosT = bufferPos - prevPosT; + *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); + return bufferPos; +} diff --git a/src/db/gaviota/gtb/compression/lzma/LzFind.c b/src/db/gaviota/gtb/compression/lzma/LzFind.c new file mode 100755 index 00000000..54a4adae --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/LzFind.c @@ -0,0 +1,758 @@ +/* LzFind.c -- Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ + +#include + +#include "LzFind.h" +#include "LzHash.h" + +#define kEmptyHashValue 0 +#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) +#define kNormalizeStepMin (1u << 10) /* it must be power of 2 */ /*MAB 1u */ +#define kNormalizeMask (~(kNormalizeStepMin - 1)) +#define kMaxHistorySize ((UInt32)3 << 30) + +#define kStartMaxLen 3 + +static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) +{ + if (!p->directInput) + { + alloc->Free(alloc, p->bufferBase); + p->bufferBase = 0; + } +} + +/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ + +static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) +{ + UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; + if (p->directInput) + { + p->blockSize = blockSize; + return 1; + } + if (p->bufferBase == 0 || p->blockSize != blockSize) + { + LzInWindow_Free(p, alloc); + p->blockSize = blockSize; + p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); + } + return (p->bufferBase != 0); +} + +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } + +/*MAB: static added, index replaced by idx to avoid shadowing a global variable */ +static +Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 idx) { return p->buffer[idx]; } + +/*MAB: static added */ +static +UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } + +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +{ + p->posLimit -= subValue; + p->pos -= subValue; + p->streamPos -= subValue; +} + +static void MatchFinder_ReadBlock(CMatchFinder *p) +{ + if (p->streamEndWasReached || p->result != SZ_OK) + return; + for (;;) + { + Byte *dest = p->buffer + (p->streamPos - p->pos); + size_t size = (size_t)(p->bufferBase + p->blockSize - dest); + if (size == 0) + return; + p->result = p->stream->Read(p->stream, dest, &size); + if (p->result != SZ_OK) + return; + if (size == 0) + { + p->streamEndWasReached = 1; + return; + } + p->streamPos += (UInt32)size; + if (p->streamPos - p->pos > p->keepSizeAfter) + return; + } +} + +void MatchFinder_MoveBlock(CMatchFinder *p) +{ + memmove(p->bufferBase, + p->buffer - p->keepSizeBefore, + (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); + p->buffer = p->bufferBase + p->keepSizeBefore; +} + +int MatchFinder_NeedMove(CMatchFinder *p) +{ + /* if (p->streamEndWasReached) return 0; */ + return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); +} + +void MatchFinder_ReadIfRequired(CMatchFinder *p) +{ + if (p->streamEndWasReached) + return; + if (p->keepSizeAfter >= p->streamPos - p->pos) + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) +{ + if (MatchFinder_NeedMove(p)) + MatchFinder_MoveBlock(p); + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_SetDefaultSettings(CMatchFinder *p) +{ + p->cutValue = 32; + p->btMode = 1; + p->numHashBytes = 4; + /* p->skipModeBits = 0; */ + p->directInput = 0; + p->bigHash = 0; +} + +#define kCrcPoly 0xEDB88320 + +void MatchFinder_Construct(CMatchFinder *p) +{ + UInt32 i; + p->bufferBase = 0; + p->directInput = 0; + p->hash = 0; + MatchFinder_SetDefaultSettings(p); + + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + p->crc[i] = r; + } +} + +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->hash); + p->hash = 0; +} + +void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) +{ + MatchFinder_FreeThisClassMemory(p, alloc); + LzInWindow_Free(p, alloc); +} + +static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) +{ + size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + if (sizeInBytes / sizeof(CLzRef) != num) + return 0; + return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); +} + +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAlloc *alloc) +{ + UInt32 sizeReserv; + if (historySize > kMaxHistorySize) + { + MatchFinder_Free(p, alloc); + return 0; + } + sizeReserv = historySize >> 1; + if (historySize > ((UInt32)2 << 30)) + sizeReserv = historySize >> 2; + sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); + + p->keepSizeBefore = historySize + keepAddBufferBefore + 1; + p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; + /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ + if (LzInWindow_Create(p, sizeReserv, alloc)) + { + UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1; + UInt32 hs; + p->matchMaxLen = matchMaxLen; + { + p->fixedHashSize = 0; + if (p->numHashBytes == 2) + hs = (1 << 16) - 1; + else + { + hs = historySize - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + /* hs >>= p->skipModeBits; */ + hs |= 0xFFFF; /* don't change it! It's required for Deflate */ + if (hs > (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + } + } + p->hashMask = hs; + hs++; + if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; + if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; + if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; + hs += p->fixedHashSize; + } + + { + UInt32 prevSize = p->hashSizeSum + p->numSons; + UInt32 newSize; + p->historySize = historySize; + p->hashSizeSum = hs; + p->cyclicBufferSize = newCyclicBufferSize; + p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); + newSize = p->hashSizeSum + p->numSons; + if (p->hash != 0 && prevSize == newSize) + return 1; + MatchFinder_FreeThisClassMemory(p, alloc); + p->hash = AllocRefs(newSize, alloc); + if (p->hash != 0) + { + p->son = p->hash + p->hashSizeSum; + return 1; + } + } + } + MatchFinder_Free(p, alloc); + return 0; +} + +static void MatchFinder_SetLimits(CMatchFinder *p) +{ + UInt32 limit = kMaxValForNormalize - p->pos; + UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; + if (limit2 < limit) + limit = limit2; + limit2 = p->streamPos - p->pos; + if (limit2 <= p->keepSizeAfter) + { + if (limit2 > 0) + limit2 = 1; + } + else + limit2 -= p->keepSizeAfter; + if (limit2 < limit) + limit = limit2; + { + UInt32 lenLimit = p->streamPos - p->pos; + if (lenLimit > p->matchMaxLen) + lenLimit = p->matchMaxLen; + p->lenLimit = lenLimit; + } + p->posLimit = p->pos + limit; +} + +void MatchFinder_Init(CMatchFinder *p) +{ + UInt32 i; + for (i = 0; i < p->hashSizeSum; i++) + p->hash[i] = kEmptyHashValue; + p->cyclicBufferPos = 0; + p->buffer = p->bufferBase; + p->pos = p->streamPos = p->cyclicBufferSize; + p->result = SZ_OK; + p->streamEndWasReached = 0; + MatchFinder_ReadBlock(p); + MatchFinder_SetLimits(p); +} + +static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) +{ + return (p->pos - p->historySize - 1) & kNormalizeMask; +} + +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) +{ + UInt32 i; + for (i = 0; i < numItems; i++) + { + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } +} + +static void MatchFinder_Normalize(CMatchFinder *p) +{ + UInt32 subValue = MatchFinder_GetSubValue(p); + MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); + MatchFinder_ReduceOffsets(p, subValue); +} + +static void MatchFinder_CheckLimits(CMatchFinder *p) +{ + if (p->pos == kMaxValForNormalize) + MatchFinder_Normalize(p); + + if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) + MatchFinder_CheckAndMoveAndRead(p); + if (p->cyclicBufferPos == p->cyclicBufferSize) + p->cyclicBufferPos = 0; + MatchFinder_SetLimits(p); +} + +static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + son[_cyclicBufferPos] = curMatch; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + return distances; + { + const Byte *pb = cur - delta; + curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + if (pb[maxLen] == cur[maxLen] && *pb == *cur) + { + UInt32 len = 0; + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + return distances; + } + } + } + } +} + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return distances; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return distances; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) +{ + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + { + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +#define MOVE_POS \ + ++p->cyclicBufferPos; \ + p->buffer++; \ + if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); + +#define MOVE_POS_RET MOVE_POS return offset; + +static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } + +#define GET_MATCHES_HEADER2(minLen, ret_op) \ + UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ + lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ + cur = p->buffer; + +#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) +#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) + +#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue + +#define GET_MATCHES_FOOTER(offset, maxLen) \ + offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ + distances + offset, maxLen) - distances); MOVE_POS_RET; + +#define SKIP_FOOTER \ + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; + +static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 1) +} + +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 2) +} + +static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, delta2, maxLen, offset; + GET_MATCHES_HEADER(3) + + HASH3_CALC; + + delta2 = p->pos - p->hash[hash2Value]; + curMatch = p->hash[kFix3HashSize + hashValue]; + + p->hash[hash2Value] = + p->hash[kFix3HashSize + hashValue] = p->pos; + + + maxLen = 2; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - (ptrdiff_t)delta2] != cur[maxLen]) /*MAB second casts (ptrdiff_t)*/ + break; + distances[0] = maxLen; + distances[1] = delta2 - 1; + offset = 2; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + delta2 = p->pos - p->hash[ hash2Value]; + delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; + curMatch = p->hash[kFix4HashSize + hashValue]; + + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + + maxLen = 1; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = delta2 - 1; + offset = 2; + } + if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + { + maxLen = 3; + distances[offset + 1] = delta3 - 1; + offset += 2; + delta2 = delta3; + } + if (offset != 0) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - (ptrdiff_t)delta2] != cur[maxLen]) /*MAB casts second (ptrdiff_t)*/ + break; + distances[offset - 2] = maxLen; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + if (maxLen < 3) + maxLen = 3; + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + delta2 = p->pos - p->hash[ hash2Value]; + delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; + curMatch = p->hash[kFix4HashSize + hashValue]; + + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + + maxLen = 1; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = delta2 - 1; + offset = 2; + } + if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + { + maxLen = 3; + distances[offset + 1] = delta3 - 1; + offset += 2; + delta2 = delta3; + } + if (offset != 0) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - (ptrdiff_t)delta2] != cur[maxLen]) /*MAB casts second (ptrdiff_t) */ + break; + + distances[offset - 2] = maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET; + } + } + if (maxLen < 3) + maxLen = 3; + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances + offset, maxLen) - (distances)); + MOVE_POS_RET +} + +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances, 2) - (distances)); + MOVE_POS_RET +} + +static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value; + SKIP_HEADER(3) + HASH3_CALC; + curMatch = p->hash[kFix3HashSize + hashValue]; + p->hash[hash2Value] = + p->hash[kFix3HashSize + hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value, hash3Value; + SKIP_HEADER(4) + HASH4_CALC; + curMatch = p->hash[kFix4HashSize + hashValue]; + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = p->pos; + p->hash[kFix4HashSize + hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value, hash3Value; + SKIP_HEADER(4) + HASH4_CALC; + curMatch = p->hash[kFix4HashSize + hashValue]; + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) +{ + vTable->Init = (Mf_Init_Func)MatchFinder_Init; + vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; + vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; + if (!p->btMode) + { + vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; + } + else if (p->numHashBytes == 2) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; + } + else if (p->numHashBytes == 3) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; + } + else + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; + } +} diff --git a/src/db/gaviota/gtb/compression/lzma/LzFind.h b/src/db/gaviota/gtb/compression/lzma/LzFind.h new file mode 100755 index 00000000..5b9cebfd --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/LzFind.h @@ -0,0 +1,107 @@ +/* LzFind.h -- Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZFIND_H +#define __LZFIND_H + +#include "Types.h" + +typedef UInt32 CLzRef; + +typedef struct _CMatchFinder +{ + Byte *buffer; + UInt32 pos; + UInt32 posLimit; + UInt32 streamPos; + UInt32 lenLimit; + + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + + UInt32 matchMaxLen; + CLzRef *hash; + CLzRef *son; + UInt32 hashMask; + UInt32 cutValue; + + Byte *bufferBase; + ISeqInStream *stream; + int streamEndWasReached; + + UInt32 blockSize; + UInt32 keepSizeBefore; + UInt32 keepSizeAfter; + + UInt32 numHashBytes; + int directInput; + int btMode; + /* int skipModeBits; */ + int bigHash; + UInt32 historySize; + UInt32 fixedHashSize; + UInt32 hashSizeSum; + UInt32 numSons; + SRes result; + UInt32 crc[256]; +} CMatchFinder; + +#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) +#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) + +#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) + +int MatchFinder_NeedMove(CMatchFinder *p); +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); +void MatchFinder_MoveBlock(CMatchFinder *p); +void MatchFinder_ReadIfRequired(CMatchFinder *p); + +void MatchFinder_Construct(CMatchFinder *p); + +/* Conditions: + historySize <= 3 GB + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +*/ +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAlloc *alloc); +void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, + UInt32 *distances, UInt32 maxLen); + +/* +Conditions: + Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. + Mf_GetPointerToCurrentPos_Func's result must be used only before any other function +*/ + +typedef void (*Mf_Init_Func)(void *object); +typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); +typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); +typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); +typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); +typedef void (*Mf_Skip_Func)(void *object, UInt32); + +typedef struct _IMatchFinder +{ + Mf_Init_Func Init; + Mf_GetIndexByte_Func GetIndexByte; + Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; + Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; + Mf_GetMatches_Func GetMatches; + Mf_Skip_Func Skip; +} IMatchFinder; + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); + +void MatchFinder_Init(CMatchFinder *p); +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/LzFindMt.h b/src/db/gaviota/gtb/compression/lzma/LzFindMt.h new file mode 100755 index 00000000..2c7e462d --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/LzFindMt.h @@ -0,0 +1,97 @@ +/* LzFindMt.h -- multithreaded Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZFINDMT_H +#define __LZFINDMT_H + +#include "Threads.h" +#include "LzFind.h" + +#define kMtHashBlockSize (1 << 13) +#define kMtHashNumBlocks (1 << 3) +#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1) + +#define kMtBtBlockSize (1 << 14) +#define kMtBtNumBlocks (1 << 6) +#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1) + +typedef struct _CMtSync +{ + Bool wasCreated; + Bool needStart; + Bool exit; + Bool stopWriting; + + CThread thread; + CAutoResetEvent canStart; + CAutoResetEvent wasStarted; + CAutoResetEvent wasStopped; + CSemaphore freeSemaphore; + CSemaphore filledSemaphore; + Bool csWasInitialized; + Bool csWasEntered; + CCriticalSection cs; + UInt32 numProcessedBlocks; +} CMtSync; + +typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances); + +/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */ +#define kMtCacheLineDummy 128 + +typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, + UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); + +typedef struct _CMatchFinderMt +{ + /* LZ */ + const Byte *pointerToCurPos; + UInt32 *btBuf; + UInt32 btBufPos; + UInt32 btBufPosLimit; + UInt32 lzPos; + UInt32 btNumAvailBytes; + + UInt32 *hash; + UInt32 fixedHashSize; + UInt32 historySize; + const UInt32 *crc; + + Mf_Mix_Matches MixMatchesFunc; + + /* LZ + BT */ + CMtSync btSync; + Byte btDummy[kMtCacheLineDummy]; + + /* BT */ + UInt32 *hashBuf; + UInt32 hashBufPos; + UInt32 hashBufPosLimit; + UInt32 hashNumAvail; + + CLzRef *son; + UInt32 matchMaxLen; + UInt32 numHashBytes; + UInt32 pos; + Byte *buffer; + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be historySize + 1 */ + UInt32 cutValue; + + /* BT + Hash */ + CMtSync hashSync; + /* Byte hashDummy[kMtCacheLineDummy]; */ + + /* Hash */ + Mf_GetHeads GetHeadsFunc; + CMatchFinder *MatchFinder; +} CMatchFinderMt; + +void MatchFinderMt_Construct(CMatchFinderMt *p); +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc); +SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc); +void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); +void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/LzHash.h b/src/db/gaviota/gtb/compression/lzma/LzHash.h new file mode 100755 index 00000000..9f4173e7 --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/LzHash.h @@ -0,0 +1,54 @@ +/* LzHash.h -- HASH functions for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZHASH_H +#define __LZHASH_H + +#define kHash2Size (1 << 10) +#define kHash3Size (1 << 16) +#define kHash4Size (1 << 20) + +#define kFix3HashSize (kHash2Size) +#define kFix4HashSize (kHash2Size + kHash3Size) +#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) + +#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); + +#define HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } + +#define HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } + +#define HASH5_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ + hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ + hash4Value &= (kHash4Size - 1); } + +/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ +#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; + + +#define MT_HASH2_CALC \ + hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); + +#define MT_HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } + +#define MT_HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/Lzma86Dec.c b/src/db/gaviota/gtb/compression/lzma/Lzma86Dec.c new file mode 100755 index 00000000..63a17b86 --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Lzma86Dec.c @@ -0,0 +1,63 @@ +/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder +2008-04-07 +Igor Pavlov +Public domain */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include "Lzma86Dec.h" +#include "Alloc.h" +#include "Bra.h" +#include "LzmaDec.h" + +#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE) +#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) + +static void *SzAlloc(void *p, size_t size) { return MyAlloc(size); } +static void SzFree(void *p, void *address) { MyFree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) +{ + unsigned i; + if (srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + *unpackSize = 0; + for (i = 0; i < sizeof(UInt64); i++) + *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); + return SZ_OK; +} + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) +{ + SRes res; + int useFilter; + SizeT inSizePure; + ELzmaStatus status; + + if (*srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + + useFilter = src[0]; + + if (useFilter > 1) + { + *destLen = 0; + return SZ_ERROR_UNSUPPORTED; + } + + inSizePure = *srcLen - LZMA86_HEADER_SIZE; + res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, + src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); + *srcLen = inSizePure + LZMA86_HEADER_SIZE; + if (res != SZ_OK) + return res; + if (useFilter == 1) + { + UInt32 x86State; + x86_Convert_Init(x86State); + x86_Convert(dest, *destLen, 0, &x86State, 0); + } + return SZ_OK; +} +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/src/db/gaviota/gtb/compression/lzma/Lzma86Dec.h b/src/db/gaviota/gtb/compression/lzma/Lzma86Dec.h new file mode 100755 index 00000000..331ffa7f --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Lzma86Dec.h @@ -0,0 +1,45 @@ +/* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder +2008-08-05 +Igor Pavlov +Public domain */ + +#ifndef __LZMA86DEC_H +#define __LZMA86DEC_H + +#include "Types.h" + +/* +Lzma86_GetUnpackSize: + In: + src - input data + srcLen - input data size + Out: + unpackSize - size of uncompressed stream + Return code: + SZ_OK - OK + SZ_ERROR_INPUT_EOF - Error in headers +*/ + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); + +/* +Lzma86_Decode: + In: + dest - output data + destLen - output data size + src - input data + srcLen - input data size + Out: + destLen - processed output size + srcLen - processed input size + Return code: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - unsupported file + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer +*/ + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/Lzma86Enc.c b/src/db/gaviota/gtb/compression/lzma/Lzma86Enc.c new file mode 100755 index 00000000..464996ac --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Lzma86Enc.c @@ -0,0 +1,116 @@ +/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder +2008-08-05 +Igor Pavlov +Public domain */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include + +#include "Lzma86Enc.h" + +#include "Alloc.h" +#include "Bra.h" +#include "LzmaEnc.h" + +#define SZE_OUT_OVERFLOW SZE_DATA_ERROR + +static void *SzAlloc(void *p, size_t size) { return MyAlloc(size); } +static void SzFree(void *p, void *address) { MyFree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE) +#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) + +int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode) +{ + size_t outSize2 = *destLen; + Byte *filteredStream; + Bool useFilter; + int mainResult = SZ_ERROR_OUTPUT_EOF; + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + + *destLen = 0; + if (outSize2 < LZMA86_HEADER_SIZE) + return SZ_ERROR_OUTPUT_EOF; + + { + int i; + UInt64 t = srcLen; + for (i = 0; i < 8; i++, t >>= 8) + dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; + } + + filteredStream = 0; + useFilter = (filterMode != SZ_FILTER_NO); + if (useFilter) + { + if (srcLen != 0) + { + filteredStream = (Byte *)MyAlloc(srcLen); + if (filteredStream == 0) + return SZ_ERROR_MEM; + memcpy(filteredStream, src, srcLen); + } + { + UInt32 x86State; + x86_Convert_Init(x86State); + x86_Convert(filteredStream, srcLen, 0, &x86State, 1); + } + } + + { + size_t minSize = 0; + Bool bestIsFiltered = False; + + /* passes for SZ_FILTER_AUTO: + 0 - BCJ + LZMA + 1 - LZMA + 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. + */ + int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; + + int i; + for (i = 0; i < numPasses; i++) + { + size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; + size_t outPropsSize = 5; + SRes curRes; + Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); + if (curModeIsFiltered && !bestIsFiltered) + break; + if (useFilter && i == 0) + curModeIsFiltered = True; + + curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, + curModeIsFiltered ? filteredStream : src, srcLen, + &props, dest + 1, &outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); + + if (curRes != SZ_ERROR_OUTPUT_EOF) + { + if (curRes != SZ_OK) + { + mainResult = curRes; + break; + } + if (outSizeProcessed <= minSize || mainResult != SZ_OK) + { + minSize = outSizeProcessed; + bestIsFiltered = curModeIsFiltered; + mainResult = SZ_OK; + } + } + } + dest[0] = (unsigned char) (bestIsFiltered ? 1 : 0); /*MAB: Cast to silence compiler */ + *destLen = LZMA86_HEADER_SIZE + minSize; + } + if (useFilter) + MyFree(filteredStream); + return mainResult; +} +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/src/db/gaviota/gtb/compression/lzma/Lzma86Enc.h b/src/db/gaviota/gtb/compression/lzma/Lzma86Enc.h new file mode 100755 index 00000000..c2da28bc --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Lzma86Enc.h @@ -0,0 +1,72 @@ +/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder +2008-08-05 +Igor Pavlov +Public domain */ + +#ifndef __LZMA86ENC_H +#define __LZMA86ENC_H + +#include "Types.h" + +/* +It's an example for LZMA + x86 Filter use. +You can use .lzma86 extension, if you write that stream to file. +.lzma86 header adds one additional byte to standard .lzma header. +.lzma86 header (14 bytes): + Offset Size Description + 0 1 = 0 - no filter, + = 1 - x86 filter + 1 1 lc, lp and pb in encoded form + 2 4 dictSize (little endian) + 6 8 uncompressed size (little endian) + + +Lzma86_Encode +------------- +level - compression level: 0 <= level <= 9, the default value for "level" is 5. + + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes, for level = 5. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + For better compression ratio dictSize must be >= inSize. + +filterMode: + SZ_FILTER_NO - no Filter + SZ_FILTER_YES - x86 Filter + SZ_FILTER_AUTO - it tries both alternatives to select best. + Encoder will use 2 or 3 passes: + 2 passes when FILTER_NO provides better compression. + 3 passes when FILTER_YES provides better compression. + +Lzma86Encode allocates Data with MyAlloc functions. +RAM Requirements for compressing: + RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize + filterMode FilterBlockSize + SZ_FILTER_NO 0 + SZ_FILTER_YES inSize + SZ_FILTER_AUTO inSize + + +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +enum ESzFilterMode +{ + SZ_FILTER_NO, + SZ_FILTER_YES, + SZ_FILTER_AUTO +}; + +SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode); + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/LzmaDec.c b/src/db/gaviota/gtb/compression/lzma/LzmaDec.c new file mode 100755 index 00000000..d85f53dc --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/LzmaDec.c @@ -0,0 +1,1012 @@ +/* LzmaDec.c -- LZMA Decoder +2008-11-06 : Igor Pavlov : Public domain */ + +#include "LzmaDec.h" + +#include + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_INIT_SIZE 5 + +#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ + { UPDATE_0(p); i = (i + i); A0; } else \ + { UPDATE_1(p); i = (i + i) + 1; A1; } +#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) + +#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } +#define TREE_DECODE(probs, limit, i) \ + { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + +/* #define _LZMA_SIZE_OPT */ + +#ifdef _LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ + { i = 1; \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + i -= 0x40; } +#endif + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK range -= bound; code -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ + { UPDATE_0_CHECK; i = (i + i); A0; } else \ + { UPDATE_1_CHECK; i = (i + i) + 1; A1; } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ + { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 +/*MAB casts next... */ +#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + ((unsigned)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +static const Byte kLiteralNextStates[kNumStates * 2] = +{ + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, + 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 +}; + +#define LZMA_DIC_MIN (1 << 12) + +/* First LZMA-symbol is always decoded. +And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization +Out: + Result: + SZ_OK - OK + SZ_ERROR_DATA - Error + p->remainLen: + < kMatchSpecLenStart : normal remain + = kMatchSpecLenStart : finished + = kMatchSpecLenStart + 1 : Flush marker + = kMatchSpecLenStart + 2 : State Init Marker +*/ + +static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + CLzmaProb *probs = p->probs; + + unsigned state = p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; + unsigned lc = p->prop.lc; + + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; + + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; + + do + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = processedPos & pbMask; + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + unsigned symbol; + UPDATE_0(prob); + prob = probs + Literal; + if (checkDicSize != 0 || processedPos != 0) + prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + (UInt32) ( /*MAB casts */ + (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))) ) + ; + if (state < kNumLitStates) + { + symbol = 1; + do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + unsigned offs = 0x100; + symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + dic[dicPos++] = (Byte)symbol; + processedPos++; + + state = kLiteralNextStates[state]; + /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ + continue; + } + else + { + UPDATE_1(prob); + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + state += kNumStates; + prob = probs + LenCoder; + } + else + { + UPDATE_1(prob); + if (checkDicSize == 0 && processedPos == 0) + return SZ_ERROR_DATA; + prob = probs + IsRepG0 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + UPDATE_0(prob); + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + UPDATE_1(prob); + } + else + { + UInt32 distance; + UPDATE_1(prob); + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep1; + } + else + { + UPDATE_1(prob); + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep2; + } + else + { + UPDATE_1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + { + /*MAB: limit changed to limit__ because it was hiding a variable limit */ + unsigned limit__, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit__ = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit__ = (1 << kLenNumMidBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit__ = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, limit__, len); + len += offset; + } + + if (state >= kNumStates) + { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance); + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + int numDirectBits = (int)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos + distance - posSlot - 1; + { + UInt32 mask = 1; + unsigned i = 1; + do + { + GET_BIT2(prob + i, i, ; , distance |= mask); + mask <<= 1; + } + while (--numDirectBits != 0); + } + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ + distance = (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { + code -= range; + distance |= 1; + } + */ + } + while (--numDirectBits != 0); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + GET_BIT2(prob + i, i, ; , distance |= 1); + GET_BIT2(prob + i, i, ; , distance |= 2); + GET_BIT2(prob + i, i, ; , distance |= 4); + GET_BIT2(prob + i, i, ; , distance |= 8); + } + if (distance == (UInt32)0xFFFFFFFF) + { + len += kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + if (checkDicSize == 0) + { + if (distance >= processedPos) + return SZ_ERROR_DATA; + } + else if (distance >= checkDicSize) + return SZ_ERROR_DATA; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + /* state = kLiteralNextStates[state]; */ + } + + len += kMatchMinLen; + + if (limit == dicPos) + return SZ_ERROR_DATA; + { + SizeT rem = limit - dicPos; + unsigned curLen = ((rem < len) ? (unsigned)rem : len); + SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); + + processedPos += curLen; + + len -= curLen; + if (pos + curLen <= dicBufSize) + { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += curLen; + do + *(dest) = (Byte)*(dest + src); + while (++dest != lim); + } + else + { + do + { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) + pos = 0; + } + while (--curLen != 0); + } + } + } + } + while (dicPos < limit && buf < bufLimit); + NORMALIZE; + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = len; + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = state; + + return SZ_OK; +} + +static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +{ + if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) + { + Byte *dic = p->dic; + SizeT dicPos = p->dicPos; + SizeT dicBufSize = p->dicBufSize; + unsigned len = p->remainLen; + UInt32 rep0 = p->reps[0]; + if (limit - dicPos < len) + len = (unsigned)(limit - dicPos); + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += len; + p->remainLen -= len; + while (len-- != 0) + { + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + } + p->dicPos = dicPos; + } +} + +static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + do + { + SizeT limit2 = limit; + if (p->checkDicSize == 0) + { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit2 = p->dicPos + rem; + } + RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); + if (p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + LzmaDec_WriteRem(p, limit); + } + while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); + + if (p->remainLen > kMatchSpecLenStart) + { + p->remainLen = kMatchSpecLenStart; + } + return 0; +} + +typedef enum ELzmaDummy +{ + DUMMY_ERROR, /* unexpected end of input stream */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) +{ + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = buf + inSize; + CLzmaProb *probs = p->probs; + unsigned state = p->state; + ELzmaDummy res; + + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = (p->processedPos) & ((1u << p->prop.pb) - 1u); /*MAB 1u */ + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += (LZMA_LIT_SIZE * + ( (unsigned) /*MAB casts */ + (((p->processedPos) & ((1u << (p->prop.lp)) - 1u)) << p->prop.lc) + + (unsigned) /*MAB casts */ + (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[p->dicPos - p->reps[0] + + ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK; + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK; + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + NORMALIZE_CHECK; + return DUMMY_REP; + } + else + { + UPDATE_1_CHECK; + } + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumMidBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len); + len += offset; + } + + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = (int)((posSlot >> 1) - 1); /*MAB casts */ + + /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE_CHECK + range >>= 1; + code -= range & (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } + while (--numDirectBits != 0); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + do + { + GET_BIT_CHECK(prob + i, i); + } + while (--numDirectBits != 0); + } + } + } + } + } + NORMALIZE_CHECK; + return res; +} + + +static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) +{ + p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); + p->range = 0xFFFFFFFF; + p->needFlush = 0; +} + +/*MAB: static added because it is not used externally */ +static +void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +{ + p->needFlush = 1; + p->remainLen = 0; + p->tempBufSize = 0; + + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->needInitState = 1; + } + if (initState) + p->needInitState = 1; +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); +} + +static void LzmaDec_InitStateReal(CLzmaDec *p) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); + UInt32 i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + p->needInitState = 0; +} + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + (*srcLen) = 0; + LzmaDec_WriteRem(p, dicLimit); + + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->remainLen != kMatchSpecLenStart) + { + int checkEndMarkNow; + + if (p->needFlush != 0) + { + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) + p->tempBuf[p->tempBufSize++] = *src++; + if (p->tempBufSize < RC_INIT_SIZE) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (p->tempBuf[0] != 0) + return SZ_ERROR_DATA; + + LzmaDec_InitRc(p, p->tempBuf); + p->tempBufSize = 0; + } + + checkEndMarkNow = 0; + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) + { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + checkEndMarkNow = 1; + } + + if (p->needInitState) + LzmaDec_InitStateReal(p); + + if (p->tempBufSize == 0) + { + SizeT processed; + const Byte *bufLimit; + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, src, inSize); + if (dummyRes == DUMMY_ERROR) + { + memcpy(p->tempBuf, src, inSize); + p->tempBufSize = (unsigned)inSize; + (*srcLen) += inSize; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + bufLimit = src; + } + else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + p->buf = src; + if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) + return SZ_ERROR_DATA; + processed = (SizeT)(p->buf - src); + (*srcLen) += processed; + src += processed; + inSize -= processed; + } + else + { + unsigned rem = p->tempBufSize, lookAhead = 0; + while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) + p->tempBuf[rem++] = src[lookAhead++]; + p->tempBufSize = rem; + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); + if (dummyRes == DUMMY_ERROR) + { + (*srcLen) += lookAhead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + } + p->buf = p->tempBuf; + if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) + return SZ_ERROR_DATA; + lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); + (*srcLen) += lookAhead; + src += lookAhead; + inSize -= lookAhead; + p->tempBufSize = 0; + } + } + if (p->code == 0) + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; +} + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) + { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->probs); + p->probs = 0; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->dic); + p->dic = 0; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +{ + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; + + p->lc = d % 9; + d /= 9; + p->pb = d / 5; + p->lp = d % 5; + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +{ + UInt32 numProbs = (UInt32) (LzmaProps_GetNumProbs(propNew)); /*MAB casts */ + if (p->probs == 0 || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); + p->numProbs = numProbs; + if (p->probs == 0) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + dicBufSize = propNew.dicSize; + if (p->dic == 0 || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); + if (p->dic == 0) + { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzmaDec p; + SRes res; + SizeT inSize = *srcLen; + SizeT outSize = *destLen; + *srcLen = *destLen = 0; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + + LzmaDec_Construct(&p); + res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); + if (res != 0) + return res; + p.dic = dest; + p.dicBufSize = outSize; + + LzmaDec_Init(&p); + + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + (*destLen) = p.dicPos; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/src/db/gaviota/gtb/compression/lzma/LzmaDec.h b/src/db/gaviota/gtb/compression/lzma/LzmaDec.h new file mode 100755 index 00000000..cde8f269 --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/LzmaDec.h @@ -0,0 +1,223 @@ +/* LzmaDec.h -- LZMA Decoder +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZMADEC_H +#define __LZMADEC_H + +#include "Types.h" + +/* #define _LZMA_PROB32 */ +/* _LZMA_PROB32 can increase the speed on some CPUs, + but memory usage for CLzmaDec::probs will be doubled in that case */ + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaProps +{ + unsigned lc, lp, pb; + UInt32 dicSize; +} CLzmaProps; + +/* LzmaProps_Decode - decodes properties +Returns: + SZ_OK + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); + + +/* ---------- LZMA Decoder state ---------- */ + +/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + +typedef struct CLzmaDec +{ + CLzmaProps prop; + CLzmaProb *probs; + Byte *dic; + const Byte *buf; + UInt32 range, code; + SizeT dicPos; + SizeT dicBufSize; + UInt32 processedPos; + UInt32 checkDicSize; + unsigned state; + UInt32 reps[4]; + unsigned remainLen; + int needFlush; + int needInitState; + UInt32 numProbs; + unsigned tempBufSize; + Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +} CLzmaDec; + +#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } + +void LzmaDec_Init(CLzmaDec *p); + +/* There are two types of LZMA streams: + 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. + 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + +typedef enum ELzmaFinishMode +{ + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ +} ELzmaFinishMode; + +/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + +typedef enum ELzmaStatus +{ + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ +} ELzmaStatus; + +/* ELzmaStatus is used only as output value for function call */ + + +/* ---------- Interfaces ---------- */ + +/* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + + +/* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + +LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); + +SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); + +/* ---------- Dictionary Interface ---------- */ + +/* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + + STEPS: + LzmaDec_Constr() + LzmaDec_Allocate() + for (each new stream) + { + LzmaDec_Init() + while (it needs more decompression) + { + LzmaDec_DecodeToDic() + use data from CLzmaDec::dic and update CLzmaDec::dicPos + } + } + LzmaDec_Free() +*/ + +/* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: + It has meaning only if the decoding reaches output limit (dicLimit). + LZMA_FINISH_ANY - Decode just dicLimit bytes. + LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error +*/ + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc); + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/LzmaEnc.c b/src/db/gaviota/gtb/compression/lzma/LzmaEnc.c new file mode 100755 index 00000000..aee2591c --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/LzmaEnc.c @@ -0,0 +1,2331 @@ +/* LzmaEnc.c -- LZMA Encoder +2009-02-02 : Igor Pavlov : Public domain */ + +#include + +/* #define SHOW_STAT */ +/* #define SHOW_STAT2 */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#if defined(SHOW_STAT) || defined(SHOW_STAT2) +#include +#endif + +#include "LzmaEnc.h" + +#include "LzFind.h" +#ifdef COMPRESS_MF_MT +#include "LzFindMt.h" +#endif + +#ifdef SHOW_STAT +static int ttt = 0; +#endif + +#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) + +#define kBlockSize (9 << 10) +#define kUnpackBlockSize (1 << 18) +#define kMatchArraySize (1 << 21) +#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) + +#define kNumMaxDirectBits (31) + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 +#define kProbInitValue (kBitModelTotal >> 1) + +#define kNumMoveReducingBits 4 +#define kNumBitPriceShiftBits 4 +#define kBitPrice (1 << kNumBitPriceShiftBits) + +void LzmaEncProps_Init(CLzmaEncProps *p) +{ + p->level = 5; + p->dictSize = p->mc = 0; + p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->writeEndMark = 0; +} + +void LzmaEncProps_Normalize(CLzmaEncProps *p) +{ + int level = p->level; + if (level < 0) level = 5; + p->level = level; + if (p->dictSize == 0) p->dictSize = (UInt32) ((level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)))); /*MAB casts UInt32 */ + if (p->lc < 0) p->lc = 3; + if (p->lp < 0) p->lp = 0; + if (p->pb < 0) p->pb = 2; + if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); + if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); + if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); + if (p->numHashBytes < 0) p->numHashBytes = 4; + if (p->mc == 0) p->mc = (UInt32) ((16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1)); /*MAB casts UInt32 */ + if (p->numThreads < 0) + p->numThreads = + #ifdef COMPRESS_MF_MT + ((p->btMode && p->algo) ? 2 : 1); + #else + 1; + #endif +} + +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +{ + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + return props.dictSize; +} + +/* #define LZMA_LOG_BSR */ +/* Define it for Intel's CPU */ + + +#ifdef LZMA_LOG_BSR + +#define kDicLogSizeMaxCompress 30 + +/*MAB: i changed to i__ to avoid possible hiding of a variable */ +#define BSR2_RET(pos, res) { unsigned long i__; _BitScanReverse(&i__, (pos)); res = (i__ + i__) + ((pos >> (i__ - 1)) & 1); } + +UInt32 GetPosSlot1(UInt32 pos) +{ + UInt32 res; + BSR2_RET(pos, res); + return res; +} +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } + +#else + +#define kNumLogBits (9 + (int)sizeof(size_t) / 2) +#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) + +/*MAB: static added */ +static +void LzmaEnc_FastPosInit(Byte *g_FastPos) +{ + int c = 2, slotFast; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + + for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) + { + UInt32 k = (UInt32) ((1 << ((slotFast >> 1) - 1))); /*MAB casts */ + UInt32 j; + for (j = 0; j < k; j++, c++) + g_FastPos[c] = (Byte)slotFast; + } +} + +/*MAB: i changed to i__ to avoid hiding a variable */ +#define BSR2_RET(pos, res) { UInt32 i__ = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ + res = p->g_FastPos[pos >> i__] + (i__ * 2); } + +/* +#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ + p->g_FastPos[pos >> 6] + 12 : \ + p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } +*/ + +#define GetPosSlot1(pos) p->g_FastPos[pos] +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } + +#endif + + +#define LZMA_NUM_REPS 4 + +typedef unsigned CState; + +typedef struct _COptimal +{ + UInt32 price; + + CState state; + int prev1IsChar; + int prev2; + + UInt32 posPrev2; + UInt32 backPrev2; + + UInt32 posPrev; + UInt32 backPrev; + UInt32 backs[LZMA_NUM_REPS]; +} COptimal; + +#define kNumOpts (1 << 12) + +#define kNumLenToPosStates 4 +#define kNumPosSlotBits 6 +#define kDicLogSizeMin 0 +#define kDicLogSizeMax 32 +#define kDistTableSizeMax (kDicLogSizeMax * 2) + + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) +#define kAlignMask (kAlignTableSize - 1) + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) + +#define kNumFullDistances (1 << (kEndPosModelIndex / 2)) + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + +#define LZMA_PB_MAX 4 +#define LZMA_LC_MAX 8 +#define LZMA_LP_MAX 4 + +#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) + + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define LZMA_MATCH_LEN_MIN 2 +#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) + +#define kNumStates 12 + +typedef struct CLenEnc +{ + CLzmaProb choice; + CLzmaProb choice2; + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; + CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; + CLzmaProb high[kLenNumHighSymbols]; +} CLenEnc; + +typedef struct CLenPriceEnc +{ + CLenEnc p; + UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; + UInt32 tableSize; + UInt32 counters[LZMA_NUM_PB_STATES_MAX]; +} CLenPriceEnc; + +typedef struct _CRangeEnc +{ + UInt32 range; + Byte cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStream *outStream; + UInt64 processed; + SRes res; +} CRangeEnc; + +typedef struct _CSeqInStreamBuf +{ + ISeqInStream funcTable; + const Byte *data; + SizeT rem; +} CSeqInStreamBuf; + +static SRes MyRead(void *pp, void *data, size_t *size) +{ + size_t curSize = *size; + CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp; + if (p->rem < curSize) + curSize = p->rem; + memcpy(data, p->data, curSize); + p->rem -= curSize; + p->data += curSize; + *size = curSize; + return SZ_OK; +} + +typedef struct CSaveState +{ + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; +} CSaveState; + +typedef struct _CLzmaEnc +{ + IMatchFinder matchFinder; + void *matchFinderObj; + + #ifdef COMPRESS_MF_MT + Bool mtMode; + CMatchFinderMt matchFinderMt; + #endif + + CMatchFinder matchFinderBase; + + #ifdef COMPRESS_MF_MT + Byte pad[128]; + #endif + + UInt32 optimumEndIndex; + UInt32 optimumCurrentIndex; + + UInt32 longestMatchLength; + UInt32 numPairs; + UInt32 numAvail; + COptimal opt[kNumOpts]; + + #ifndef LZMA_LOG_BSR + Byte g_FastPos[1 << kNumLogBits]; + #endif + + UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; + UInt32 numFastBytes; + UInt32 additionalOffset; + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; + + UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; + UInt32 alignPrices[kAlignTableSize]; + UInt32 alignPriceCount; + + UInt32 distTableSize; + + unsigned lc, lp, pb; + unsigned lpMask, pbMask; + + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + unsigned lclp; + + Bool fastMode; + + CRangeEnc rc; + + Bool writeEndMark; + UInt64 nowPos64; + UInt32 matchPriceCount; + Bool finished; + Bool multiThread; + + SRes result; + UInt32 dictSize; + UInt32 matchFinderCycles; + + ISeqInStream *inStream; + CSeqInStreamBuf seqBufInStream; + + CSaveState saveState; +} CLzmaEnc; + + +#if defined(USE_UNUSED_CODE) +/*MAB: static added */ +static +void LzmaEnc_SaveState(CLzmaEncHandle pp) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CSaveState *dest = &p->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); +} + +/*MAB: static added */ +static void LzmaEnc_RestoreState(CLzmaEncHandle pp) +{ + CLzmaEnc *dest = (CLzmaEnc *)pp; + const CSaveState *p = &dest->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); +} +#endif + +SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + + if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || + props.dictSize > (1u << kDicLogSizeMaxCompress) || props.dictSize > (1u << 30)) /*MAB: 1u to silence warnings */ + return SZ_ERROR_PARAM; + p->dictSize = props.dictSize; + p->matchFinderCycles = props.mc; + { + unsigned fb = (unsigned) props.fb; /*MAB casts */ + if (fb < 5) + fb = 5; + if (fb > LZMA_MATCH_LEN_MAX) + fb = LZMA_MATCH_LEN_MAX; + p->numFastBytes = fb; + } + p->lc = (unsigned) props.lc; + p->lp = (unsigned) props.lp; + p->pb = (unsigned) props.pb; + p->fastMode = (props.algo == 0); + p->matchFinderBase.btMode = props.btMode; + { + UInt32 numHashBytes = 4; + if (props.btMode) + { + if (props.numHashBytes < 2) + numHashBytes = 2; + else if (props.numHashBytes < 4) + numHashBytes = (UInt32) props.numHashBytes; /*MAB casts */ + } + p->matchFinderBase.numHashBytes = numHashBytes; + } + + p->matchFinderBase.cutValue = props.mc; + + p->writeEndMark = (Bool) props.writeEndMark; /*MAB casts */ + + #ifdef COMPRESS_MF_MT + /* + if (newMultiThread != _multiThread) + { + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + */ + p->multiThread = (props.numThreads > 1); + #endif + + return SZ_OK; +} + +static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +#define IsCharState(s) ((s) < 7) + +#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) + +#define kInfinityPrice (1 << 30) + +static void RangeEnc_Construct(CRangeEnc *p) +{ + p->outStream = 0; + p->bufBase = 0; +} + +#define RangeEnc_GetProcessed(p) ((p)->processed + (UInt64) ((p)->buf - (p)->bufBase) + (p)->cacheSize) /*MAB casts */ + +#define RC_BUF_SIZE (1 << 16) +static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) +{ + if (p->bufBase == 0) + { + p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); + if (p->bufBase == 0) + return 0; + p->bufLim = p->bufBase + RC_BUF_SIZE; + } + return 1; +} + +static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->bufBase); + p->bufBase = 0; +} + +static void RangeEnc_Init(CRangeEnc *p) +{ + /* Stream.Init(); */ + p->low = 0; + p->range = 0xFFFFFFFF; + p->cacheSize = 1; + p->cache = 0; + + p->buf = p->bufBase; + + p->processed = 0; + p->res = SZ_OK; +} + +static void RangeEnc_FlushStream(CRangeEnc *p) +{ + size_t num; + if (p->res != SZ_OK) + return; + num = (size_t)(p->buf - p->bufBase); /*MAB casts */ + if (num != p->outStream->Write(p->outStream, p->bufBase, num)) + p->res = SZ_ERROR_WRITE; + p->processed += num; + p->buf = p->bufBase; +} + +static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +{ + if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) + { + Byte temp = p->cache; + do + { + Byte *buf = p->buf; + *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + temp = 0xFF; + } + while (--p->cacheSize != 0); + p->cache = (Byte)((UInt32)p->low >> 24); + } + p->cacheSize++; + p->low = (UInt32)p->low << 8; +} + +static void RangeEnc_FlushData(CRangeEnc *p) +{ + int i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); +} + +static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) +{ + do + { + p->range >>= 1; + p->low += p->range & (0 - ((value >> --numBits) & 1)); + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } + } + while (numBits != 0); +} + +static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) +{ + UInt32 ttt = *prob; + UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; + if (symbol == 0) + { + p->range = newBound; + ttt += (kBitModelTotal - ttt) >> kNumMoveBits; + } + else + { + p->low += newBound; + p->range -= newBound; + ttt -= ttt >> kNumMoveBits; + } + *prob = (CLzmaProb)ttt; + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } +} + +static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) +{ + symbol |= 0x100; + do + { + RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); +} + +static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) +{ + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); +} + +/*MAB: static added */ +static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +{ + UInt32 i; + for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) + { + const int kCyclesBits = kNumBitPriceShiftBits; + UInt32 w = i; + UInt32 bitCount = 0; + int j; + for (j = 0; j < kCyclesBits; j++) + { + w = w * w; + bitCount <<= 1; + while (w >= ((UInt32)1 << 16)) + { + w >>= 1; + bitCount++; + } + } + ProbPrices[i >> kNumMoveReducingBits] = (/*MAB: cast to silence*/(UInt32)(kNumBitModelTotalBits << kCyclesBits) - /*MAB: cast to silence*/(UInt32)15 - bitCount); + } +} + + +#define GET_PRICE(prob, symbol) \ + p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICEa(prob, symbol) \ + ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= 0x100; + do + { + price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); + return price; +} + +static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); + return price; +} + + +static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0;) + { + UInt32 bit; + i--; + bit = (symbol >> i) & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + } +} + +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = 0; i < numBitLevels; i++) + { + UInt32 bit = symbol & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + symbol >>= 1; + } +} + +static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= (1u << numBitLevels); /*MAB 1u */ + while (symbol != 1) + { + price += GET_PRICEa(probs[symbol >> 1], symbol & 1); + symbol >>= 1; + } + return price; +} + +static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += GET_PRICEa(probs[m], bit); + m = (m << 1) | bit; + } + return price; +} + + +static void LenEnc_Init(CLenEnc *p) +{ + unsigned i; + p->choice = p->choice2 = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) + p->low[i] = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) + p->mid[i] = kProbInitValue; + for (i = 0; i < kLenNumHighSymbols; i++) + p->high[i] = kProbInitValue; +} + +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) +{ + if (symbol < kLenNumLowSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice, 0); + RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice, 1); + if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice2, 0); + RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice2, 1); + RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); + } + } +} + +static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) +{ + UInt32 a0 = GET_PRICE_0a(p->choice); + UInt32 a1 = GET_PRICE_1a(p->choice); + UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); + UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); + UInt32 i = 0; + for (i = 0; i < kLenNumLowSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); + } + for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); + } + for (; i < numSymbols; i++) + prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); +} + +static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) +{ + LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); + p->counters[posState] = p->tableSize; +} + +static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) +{ + UInt32 posState; + for (posState = 0; posState < numPosStates; posState++) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + +static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) +{ + LenEnc_Encode(&p->p, rc, symbol, posState); + if (updatePrice) + if (--p->counters[posState] == 0) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + + + + +static void MovePos(CLzmaEnc *p, UInt32 num) +{ + #ifdef SHOW_STAT + ttt += num; + printf("\n MovePos %d", num); + #endif + if (num != 0) + { + p->additionalOffset += num; + p->matchFinder.Skip(p->matchFinderObj, num); + } +} + +static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) +{ + UInt32 lenRes = 0, numPairs; + p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); + #ifdef SHOW_STAT + printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); + ttt++; + { + UInt32 i; + for (i = 0; i < numPairs; i += 2) + printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); + } + #endif + if (numPairs > 0) + { + lenRes = p->matches[numPairs - 2]; + if (lenRes == p->numFastBytes) + { + const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + UInt32 distance = p->matches[numPairs - 1] + 1; + UInt32 numAvail = p->numAvail; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + { + const Byte *pby2 = pby - distance; + for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); + } + } + } + p->additionalOffset++; + *numDistancePairsRes = numPairs; + return lenRes; +} + + +#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; +#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; +#define IsShortRep(p) ((p)->backPrev == 0) + +static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) +{ + return + GET_PRICE_0(p->isRepG0[state]) + + GET_PRICE_0(p->isRep0Long[state][posState]); +} + +static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) +{ + UInt32 price; + if (repIndex == 0) + { + price = GET_PRICE_0(p->isRepG0[state]); + price += GET_PRICE_1(p->isRep0Long[state][posState]); + } + else + { + price = GET_PRICE_1(p->isRepG0[state]); + if (repIndex == 1) + price += GET_PRICE_0(p->isRepG1[state]); + else + { + price += GET_PRICE_1(p->isRepG1[state]); + price += GET_PRICE(p->isRepG2[state], repIndex - 2); + } + } + return price; +} + +static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) +{ + return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + + GetPureRepPrice(p, repIndex, state, posState); +} + +static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) +{ + UInt32 posMem = p->opt[cur].posPrev; + UInt32 backMem = p->opt[cur].backPrev; + p->optimumEndIndex = cur; + do + { + if (p->opt[cur].prev1IsChar) + { + MakeAsChar(&p->opt[posMem]) + p->opt[posMem].posPrev = posMem - 1; + if (p->opt[cur].prev2) + { + p->opt[posMem - 1].prev1IsChar = False; + p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; + p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; + } + } + { + UInt32 posPrev = posMem; + UInt32 backCur = backMem; + + backMem = p->opt[posPrev].backPrev; + posMem = p->opt[posPrev].posPrev; + + p->opt[posPrev].backPrev = backCur; + p->opt[posPrev].posPrev = cur; + cur = posPrev; + } + } + while (cur != 0); + *backRes = p->opt[0].backPrev; + p->optimumCurrentIndex = p->opt[0].posPrev; + return p->optimumCurrentIndex; +} + +#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + (UInt32) ((prevByte) >> (8 - p->lc))) * 0x300) /*MAB cast UInt32 */ + +static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) +{ + UInt32 numAvail, mainLen, repMaxIndex, i, lenEnd, len, cur; + /*MAB: Changed numPairs_, posState_ avoid hiding a variable later */ + UInt32 numPairs_, posState_; + /*MAB: Changed matchPrice_, repMatchPrice_ avoid hiding a variable later */ + UInt32 matchPrice_, repMatchPrice_, + normalMatchPrice; + UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; + UInt32 *matches; + /*MAB: Changed from data to avoid hiding a variable later */ + const Byte *data_; + /*MAB: Changed from matchByte to avoid hiding a variable later */ + Byte curByte_, matchByte_; + if (p->optimumEndIndex != p->optimumCurrentIndex) + { + const COptimal *opt = &p->opt[p->optimumCurrentIndex]; + UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; + *backRes = opt->backPrev; + p->optimumCurrentIndex = opt->posPrev; + return lenRes; + } + p->optimumCurrentIndex = p->optimumEndIndex = 0; + + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs_); + else + { + mainLen = p->longestMatchLength; + numPairs_ = p->numPairs; + } + + numAvail = p->numAvail; + if (numAvail < 2) + { + *backRes = (UInt32)(-1); + return 1; + } + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + + data_ = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + repMaxIndex = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 lenTest; + const Byte *data2; + reps[i] = p->reps[i]; + data2 = data_ - (reps[i] + 1); + if (data_[0] != data2[0] || data_[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (lenTest = 2; lenTest < numAvail && data_[lenTest] == data2[lenTest]; lenTest++); + repLens[i] = lenTest; + if (lenTest > repLens[repMaxIndex]) + repMaxIndex = i; + } + if (repLens[repMaxIndex] >= p->numFastBytes) + { + UInt32 lenRes; + *backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + MovePos(p, lenRes - 1); + return lenRes; + } + + matches = p->matches; + if (mainLen >= p->numFastBytes) + { + *backRes = matches[numPairs_ - 1] + LZMA_NUM_REPS; + MovePos(p, mainLen - 1); + return mainLen; + } + curByte_ = *data_; + matchByte_ = *(data_ - (reps[0] + 1)); + + if (mainLen < 2 && curByte_ != matchByte_ && repLens[repMaxIndex] < 2) + { + *backRes = (UInt32)-1; + return 1; + } + + p->opt[0].state = (CState)p->state; + + posState_ = (position & p->pbMask); + + { + const CLzmaProb *probs = LIT_PROBS(position, *(data_ - 1)); + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState_]) + + (!IsCharState(p->state) ? + LitEnc_GetPriceMatched(probs, curByte_, matchByte_, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte_, p->ProbPrices)); + } + + MakeAsChar(&p->opt[1]); + + matchPrice_ = GET_PRICE_1(p->isMatch[p->state][posState_]); + repMatchPrice_ = matchPrice_ + GET_PRICE_1(p->isRep[p->state]); + + if (matchByte_ == curByte_) + { + UInt32 shortRepPrice = repMatchPrice_ + GetRepLen1Price(p, p->state, posState_); + if (shortRepPrice < p->opt[1].price) + { + p->opt[1].price = shortRepPrice; + MakeAsShortRep(&p->opt[1]); + } + } + lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); + + if (lenEnd < 2) + { + *backRes = p->opt[1].backPrev; + return 1; + } + + p->opt[1].posPrev = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + p->opt[0].backs[i] = reps[i]; + + len = lenEnd; + do + p->opt[len--].price = kInfinityPrice; + while (len >= 2); + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 repLen = repLens[i]; + UInt32 price; + if (repLen < 2) + continue; + price = repMatchPrice_ + GetPureRepPrice(p, i, p->state, posState_); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState_][repLen - 2]; + COptimal *opt = &p->opt[repLen]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = i; + opt->prev1IsChar = False; + } + } + while (--repLen >= 2); + } + + normalMatchPrice = matchPrice_ + GET_PRICE_0(p->isRep[p->state]); + + len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); + if (len <= mainLen) + { + UInt32 offs = 0; + while (len > matches[offs]) + offs += 2; + for (; ; len++) + { + COptimal *opt; + UInt32 distance = matches[offs + 1]; + + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState_][len - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(len); + if (distance < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][distance]; + else + { + UInt32 slot; + GetPosSlot2(distance, slot); + curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; + } + opt = &p->opt[len]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = distance + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + if (len == matches[offs]) + { + offs += 2; + if (offs == numPairs_) + break; + } + } + } + + cur = 0; + + #ifdef SHOW_STAT2 + if (position >= 0) + { + unsigned i__; + printf("\n pos = %4X", position); + for (i__ = cur; i__ <= lenEnd; i__++) + printf("\nprice[%4X] = %d", position - cur + i__, p->opt[i__].price); + } + #endif + + for (;;) + { + UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; + UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; + Bool nextIsChar; + Byte curByte, matchByte; + const Byte *data; + COptimal *curOpt; + COptimal *nextOpt; + + cur++; + if (cur == lenEnd) + return Backward(p, backRes, cur); + + newLen = ReadMatchDistances(p, &numPairs); + if (newLen >= p->numFastBytes) + { + p->numPairs = numPairs; + p->longestMatchLength = newLen; + return Backward(p, backRes, cur); + } + position++; + curOpt = &p->opt[cur]; + posPrev = curOpt->posPrev; + if (curOpt->prev1IsChar) + { + posPrev--; + if (curOpt->prev2) + { + state = p->opt[curOpt->posPrev2].state; + if (curOpt->backPrev2 < LZMA_NUM_REPS) + state = (UInt32) kRepNextStates[state]; /*MAB casts */ + else + state = (UInt32) kMatchNextStates[state]; /*MAB casts */ + } + else + state = p->opt[posPrev].state; + state = (UInt32) kLiteralNextStates[state]; /*MAB casts */ + } + else + state = p->opt[posPrev].state; + if (posPrev == cur - 1) + { + if (IsShortRep(curOpt)) + state = (UInt32) kShortRepNextStates[state]; /*MAB casts */ + else + state = (UInt32) kLiteralNextStates[state]; /*MAB casts */ + } + else + { + UInt32 pos; + const COptimal *prevOpt; + if (curOpt->prev1IsChar && curOpt->prev2) + { + posPrev = curOpt->posPrev2; + pos = curOpt->backPrev2; + state = (UInt32) kRepNextStates[state]; /*MAB casts */ + } + else + { + pos = curOpt->backPrev; + if (pos < LZMA_NUM_REPS) + state = (UInt32) kRepNextStates[state]; /*MAB casts */ + else + state = (UInt32) kMatchNextStates[state]; /*MAB casts */ + } + prevOpt = &p->opt[posPrev]; + if (pos < LZMA_NUM_REPS) + { + /*MAB: i changed to i__ to avoid hiding a variable */ + UInt32 i__; + reps[0] = prevOpt->backs[pos]; + for (i__ = 1; i__ <= pos; i__++) + reps[i__] = prevOpt->backs[i__ - 1]; + for (; i__ < LZMA_NUM_REPS; i__++) + reps[i__] = prevOpt->backs[i__]; + } + else + { + /*MAB: i changed to i__ to avoid hiding a variable */ + UInt32 i__; + reps[0] = (pos - LZMA_NUM_REPS); + for (i__ = 1; i__ < LZMA_NUM_REPS; i__++) + reps[i__] = prevOpt->backs[i__ - 1]; + } + } + curOpt->state = (CState)state; + + curOpt->backs[0] = reps[0]; + curOpt->backs[1] = reps[1]; + curOpt->backs[2] = reps[2]; + curOpt->backs[3] = reps[3]; + + curPrice = curOpt->price; + nextIsChar = False; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + curByte = *data; + matchByte = *(data - (reps[0] + 1)); + + posState = (position & p->pbMask); + + curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + curAnd1Price += + (!IsCharState(state) ? + LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + } + + nextOpt = &p->opt[cur + 1]; + + if (curAnd1Price < nextOpt->price) + { + nextOpt->price = curAnd1Price; + nextOpt->posPrev = cur; + MakeAsChar(nextOpt); + nextIsChar = True; + } + + matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); + + if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); + if (shortRepPrice <= nextOpt->price) + { + nextOpt->price = shortRepPrice; + nextOpt->posPrev = cur; + MakeAsShortRep(nextOpt); + nextIsChar = True; + } + } + numAvailFull = p->numAvail; + { + UInt32 temp = kNumOpts - 1 - cur; + if (temp < numAvailFull) + numAvailFull = temp; + } + + if (numAvailFull < 2) + continue; + numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); + + if (!nextIsChar && matchByte != curByte) /* speed optimization */ + { + /* try Literal + rep0 */ + UInt32 temp; + UInt32 lenTest2; + const Byte *data2 = data - (reps[0] + 1); + UInt32 limit = p->numFastBytes + 1; + if (limit > numAvailFull) + limit = numAvailFull; + + for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); + lenTest2 = temp - 1; + if (lenTest2 >= 2) + { + UInt32 state2 = (UInt32) kLiteralNextStates[state]; /*MAB casts */ + UInt32 posStateNext = (position + 1) & p->pbMask; + UInt32 nextRepMatchPrice = curAnd1Price + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = False; + } + } + } + } + + startLen = 2; /* speed optimization */ + { + UInt32 repIndex; + for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) + { + UInt32 lenTest; + UInt32 lenTestTemp; + UInt32 price; + const Byte *data2 = data - (reps[repIndex] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); + while (lenEnd < cur + lenTest) + p->opt[++lenEnd].price = kInfinityPrice; + lenTestTemp = lenTest; + price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; + COptimal *opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = repIndex; + opt->prev1IsChar = False; + } + } + while (--lenTest >= 2); + lenTest = lenTestTemp; + + if (repIndex == 0) + startLen = lenTest + 1; + + /* if (_maxMode) */ + { + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailFull) + limit = numAvailFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = (UInt32) kRepNextStates[state]; /*MAB casts */ + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = + price + p->repLenEnc.prices[posState][lenTest - 2] + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = (UInt32) kLiteralNextStates[state2]; /*MAB casts */ + posStateNext = (position + lenTest + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + lenTest + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = repIndex; + } + } + } + } + } + } + /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ + if (newLen > numAvail) + { + newLen = numAvail; + for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); + matches[numPairs] = newLen; + numPairs += 2; + } + if (newLen >= startLen) + { + /*MAB: normalMatchPrice changed to normalMatchPrice__ not to hide a variable later */ + UInt32 normalMatchPrice__ = matchPrice + GET_PRICE_0(p->isRep[state]); + UInt32 offs, curBack, posSlot; + UInt32 lenTest; + while (lenEnd < cur + newLen) + p->opt[++lenEnd].price = kInfinityPrice; + + offs = 0; + while (startLen > matches[offs]) + offs += 2; + curBack = matches[offs + 1]; + GetPosSlot2(curBack, posSlot); + for (lenTest = /*2*/ startLen; ; lenTest++) + { + /*MAB: curAndLenPrice changed to curAndLenPrice__ not to hide a variable later */ + UInt32 curAndLenPrice__ = normalMatchPrice__ + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(lenTest); + /*MAB: opt changed to opt__ not to hide a variable later */ + COptimal *opt__; + if (curBack < kNumFullDistances) + curAndLenPrice__ += p->distancesPrices[lenToPosState][curBack]; + else + curAndLenPrice__ += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; + + opt__ = &p->opt[cur + lenTest]; + if (curAndLenPrice__ < opt__->price) + { + opt__->price = curAndLenPrice__; + opt__->posPrev = cur; + opt__->backPrev = curBack + LZMA_NUM_REPS; + opt__->prev1IsChar = False; + } + + if (/*_maxMode && */lenTest == matches[offs]) + { + /* Try Match + Literal + Rep0 */ + const Byte *data2 = data - (curBack + 1); + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailFull) + limit = numAvailFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = (UInt32) kMatchNextStates[state]; /*MAB casts */ + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = curAndLenPrice__ + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = (UInt32) kLiteralNextStates[state2]; /*MAB casts */ + posStateNext = (posStateNext + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + UInt32 curAndLenPrice; + COptimal *opt; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = curBack + LZMA_NUM_REPS; + } + } + } + offs += 2; + if (offs == numPairs) + break; + curBack = matches[offs + 1]; + if (curBack >= kNumFullDistances) + GetPosSlot2(curBack, posSlot); + } + } + } + } +} + +#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) + +static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) +{ + UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; + const Byte *data; + const UInt32 *matches; + + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs); + else + { + mainLen = p->longestMatchLength; + numPairs = p->numPairs; + } + + numAvail = p->numAvail; + *backRes = (UInt32)-1; + if (numAvail < 2) + return 1; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + + repLen = repIndex = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 len; + const Byte *data2 = data - (p->reps[i] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (len = 2; len < numAvail && data[len] == data2[len]; len++); + if (len >= p->numFastBytes) + { + *backRes = i; + MovePos(p, len - 1); + return len; + } + if (len > repLen) + { + repIndex = i; + repLen = len; + } + } + + matches = p->matches; + if (mainLen >= p->numFastBytes) + { + *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; + MovePos(p, mainLen - 1); + return mainLen; + } + + mainDist = 0; /* for GCC */ + if (mainLen >= 2) + { + mainDist = matches[numPairs - 1]; + while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) + { + if (!ChangePair(matches[numPairs - 3], mainDist)) + break; + numPairs -= 2; + mainLen = matches[numPairs - 2]; + mainDist = matches[numPairs - 1]; + } + if (mainLen == 2 && mainDist >= 0x80) + mainLen = 1; + } + + if (repLen >= 2 && ( + (repLen + 1 >= mainLen) || + (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || + (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) + { + *backRes = repIndex; + MovePos(p, repLen - 1); + return repLen; + } + + if (mainLen < 2 || numAvail <= 2) + return 1; + + p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); + if (p->longestMatchLength >= 2) + { + UInt32 newDistance = matches[p->numPairs - 1]; + if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || + (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || + (p->longestMatchLength > mainLen + 1) || + (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) + return 1; + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 len, limit; + const Byte *data2 = data - (p->reps[i] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + limit = mainLen - 1; + for (len = 2; len < limit && data[len] == data2[len]; len++); + if (len >= limit) + return 1; + } + *backRes = mainDist + LZMA_NUM_REPS; + MovePos(p, mainLen - 2); + return mainLen; +} + +static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) +{ + UInt32 len; + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = (UInt32) kMatchNextStates[p->state]; /*MAB casts */ + len = LZMA_MATCH_LEN_MIN; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); + RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); +} + +static SRes CheckErrors(CLzmaEnc *p) +{ + if (p->result != SZ_OK) + return p->result; + if (p->rc.res != SZ_OK) + p->result = SZ_ERROR_WRITE; + if (p->matchFinderBase.result != SZ_OK) + p->result = SZ_ERROR_READ; + if (p->result != SZ_OK) + p->finished = True; + return p->result; +} + +static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +{ + /* ReleaseMFStream(); */ + p->finished = True; + if (p->writeEndMark) + WriteEndMarker(p, nowPos & p->pbMask); + RangeEnc_FlushData(&p->rc); + RangeEnc_FlushStream(&p->rc); + return CheckErrors(p); +} + +static void FillAlignPrices(CLzmaEnc *p) +{ + UInt32 i; + for (i = 0; i < kAlignTableSize; i++) + p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); + p->alignPriceCount = 0; +} + +static void FillDistancesPrices(CLzmaEnc *p) +{ + UInt32 tempPrices[kNumFullDistances]; + /*MAB: i changed to j to avoid warnings later of hiding i */ + UInt32 j, lenToPosState; + for (j = kStartPosModelIndex; j < kNumFullDistances; j++) + { + UInt32 posSlot = GetPosSlot1(j); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + tempPrices[j] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, (int)footerBits, j - base, p->ProbPrices); /*MAB casts */ + } + + for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 posSlot; + const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; + UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; + for (posSlot = 0; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); + for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + + { + UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; + /*MAB: i changed to i__ to avoid hiding a variable */ + UInt32 i__; + for (i__ = 0; i__ < kStartPosModelIndex; i__++) + distancesPrices[i__] = posSlotPrices[i__]; + for (; i__ < kNumFullDistances; i__++) + distancesPrices[i__] = posSlotPrices[GetPosSlot1(i__)] + tempPrices[i__]; + } + } + p->matchPriceCount = 0; +} + +/*MAB: static added */ +static void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&p->matchFinderBase); + #ifdef COMPRESS_MF_MT + MatchFinderMt_Construct(&p->matchFinderMt); + p->matchFinderMt.MatchFinder = &p->matchFinderBase; + #endif + + { + CLzmaEncProps props; + LzmaEncProps_Init(&props); + LzmaEnc_SetProps(p, &props); + } + + #ifndef LZMA_LOG_BSR + LzmaEnc_FastPosInit(p->g_FastPos); + #endif + + LzmaEnc_InitPriceTables(p->ProbPrices); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) +{ + void *p; + p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); + if (p != 0) + LzmaEnc_Construct((CLzmaEnc *)p); + return p; +} + +/*MAB: static added */ +static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->litProbs); + alloc->Free(alloc, p->saveState.litProbs); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +/*MAB: static added */ +static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + #ifdef COMPRESS_MF_MT + MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); + #endif + MatchFinder_Free(&p->matchFinderBase, allocBig); + LzmaEnc_FreeLits(p, alloc); + RangeEnc_Free(&p->rc, alloc); +} + +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); + alloc->Free(alloc, p); +} + +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) +{ + UInt32 nowPos32, startPos32; + if (p->inStream != 0) + { + p->matchFinderBase.stream = p->inStream; + p->matchFinder.Init(p->matchFinderObj); + p->inStream = 0; + } + + if (p->finished) + return p->result; + RINOK(CheckErrors(p)); + + nowPos32 = (UInt32)p->nowPos64; + startPos32 = nowPos32; + + if (p->nowPos64 == 0) + { + UInt32 numPairs; + Byte curByte; + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + return Flush(p, nowPos32); + ReadMatchDistances(p, &numPairs); + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); + p->state = (UInt32) kLiteralNextStates[p->state]; /*MAB casts */ + curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, (Int32)(0 - p->additionalOffset)); /*MAB casts */ + LitEnc_Encode(&p->rc, p->litProbs, curByte); + p->additionalOffset--; + nowPos32++; + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) + for (;;) + { + UInt32 pos, len, posState; + + if (p->fastMode) + len = GetOptimumFast(p, &pos); + else + len = GetOptimum(p, nowPos32, &pos); + + #ifdef SHOW_STAT2 + printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); + #endif + + posState = nowPos32 & p->pbMask; + if (len == 1 && pos == (UInt32)-1) + { + Byte curByte; + CLzmaProb *probs; + const Byte *data; + + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + curByte = *data; + probs = LIT_PROBS(nowPos32, *(data - 1)); + if (IsCharState(p->state)) + LitEnc_Encode(&p->rc, probs, curByte); + else + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); + p->state = (UInt32) kLiteralNextStates[p->state]; /*MAB casts */ + } + else + { + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + if (pos < LZMA_NUM_REPS) + { + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); + if (pos == 0) + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); + RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); + } + else + { + UInt32 distance = p->reps[pos]; + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); + if (pos == 1) + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); + else + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); + if (pos == 3) + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + } + p->reps[1] = p->reps[0]; + p->reps[0] = distance; + } + if (len == 1) + p->state = (UInt32) kShortRepNextStates[p->state]; /*MAB casts */ + else + { + LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + p->state = (UInt32) kRepNextStates[p->state]; /*MAB casts */ + } + } + else + { + UInt32 posSlot; + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = (UInt32) kMatchNextStates[p->state]; /*MAB casts */ + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + pos -= LZMA_NUM_REPS; + GetPosSlot(pos, posSlot); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); + + if (posSlot >= kStartPosModelIndex) + { + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + UInt32 posReduced = pos - base; + + if (posSlot < kEndPosModelIndex) + RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, (int)footerBits, posReduced); /*MAB casts */ + else + { + RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, (int)footerBits - kNumAlignBits); /*MAB casts */ + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); + p->alignPriceCount++; + } + } + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + p->reps[1] = p->reps[0]; + p->reps[0] = pos; + p->matchPriceCount++; + } + } + p->additionalOffset -= len; + nowPos32 += len; + if (p->additionalOffset == 0) + { + UInt32 processed; + if (!p->fastMode) + { + if (p->matchPriceCount >= (1 << 7)) + FillDistancesPrices(p); + if (p->alignPriceCount >= kAlignTableSize) + FillAlignPrices(p); + } + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + break; + processed = nowPos32 - startPos32; + + if (useLimits) + { + if (processed + kNumOpts + 300 >= maxUnpackSize || + RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) + break; + } + else if (processed >= (1 << 15)) + { + p->nowPos64 += nowPos32 - startPos32; + return CheckErrors(p); + } + } + } + p->nowPos64 += nowPos32 - startPos32; + return Flush(p, nowPos32); +} + +#define kBigHashDicLimit ((UInt32)1 << 24) + +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 beforeSize = kNumOpts; + #ifdef COMPRESS_MF_MT + Bool btMode; /*MAB: this line wrap inside the compilation ifdef, btMode not used without it */ + #endif + + if (!RangeEnc_Alloc(&p->rc, alloc)) + return SZ_ERROR_MEM; + + #ifdef COMPRESS_MF_MT + btMode = (p->matchFinderBase.btMode != 0); /*MAB: this line moved inside the compilation ifdef, btMode not used without it */ + + p->mtMode = (p->multiThread && !p->fastMode && btMode); + #endif + + { + unsigned lclp = p->lc + p->lp; + if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) + { + LzmaEnc_FreeLits(p, alloc); + p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300u << lclp) * sizeof(CLzmaProb)); /*MAB 0x300 vs 0x300u*/ + p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300u << lclp) * sizeof(CLzmaProb)); /*MAB 0x300 vs 0x300u*/ + if (p->litProbs == 0 || p->saveState.litProbs == 0) + { + LzmaEnc_FreeLits(p, alloc); + return SZ_ERROR_MEM; + } + p->lclp = lclp; + } + } + + p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); + + if (beforeSize + p->dictSize < keepWindowSize) + beforeSize = keepWindowSize - p->dictSize; + + #ifdef COMPRESS_MF_MT + if (p->mtMode) + { + RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); + p->matchFinderObj = &p->matchFinderMt; + MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); + } + else + #endif + { + if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) + return SZ_ERROR_MEM; + p->matchFinderObj = &p->matchFinderBase; + MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); + } + return SZ_OK; +} + +/*MAB: static added */ +static void LzmaEnc_Init(CLzmaEnc *p) +{ + UInt32 i; + p->state = 0; + for (i = 0 ; i < LZMA_NUM_REPS; i++) + p->reps[i] = 0; + + RangeEnc_Init(&p->rc); + + + for (i = 0; i < kNumStates; i++) + { + UInt32 j; + for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) + { + p->isMatch[i][j] = kProbInitValue; + p->isRep0Long[i][j] = kProbInitValue; + } + p->isRep[i] = kProbInitValue; + p->isRepG0[i] = kProbInitValue; + p->isRepG1[i] = kProbInitValue; + p->isRepG2[i] = kProbInitValue; + } + + { + UInt32 num = (UInt32) (0x300 << (p->lp + p->lc)); /*MAB casts */ + for (i = 0; i < num; i++) + p->litProbs[i] = kProbInitValue; + } + + { + for (i = 0; i < kNumLenToPosStates; i++) + { + CLzmaProb *probs = p->posSlotEncoder[i]; + UInt32 j; + for (j = 0; j < (1 << kNumPosSlotBits); j++) + probs[j] = kProbInitValue; + } + } + { + for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + p->posEncoders[i] = kProbInitValue; + } + + LenEnc_Init(&p->lenEnc.p); + LenEnc_Init(&p->repLenEnc.p); + + for (i = 0; i < (1 << kNumAlignBits); i++) + p->posAlignEncoder[i] = kProbInitValue; + + p->optimumEndIndex = 0; + p->optimumCurrentIndex = 0; + p->additionalOffset = 0; + + p->pbMask = (1u << p->pb) - 1u; /*MAB 1u */ + p->lpMask = (1u << p->lp) - 1u; /*MAB 1u */ +} + +/*MAB: static added */ +static void LzmaEnc_InitPrices(CLzmaEnc *p) +{ + if (!p->fastMode) + { + FillDistancesPrices(p); + FillAlignPrices(p); + } + + p->lenEnc.tableSize = + p->repLenEnc.tableSize = + p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; + LenPriceEnc_UpdateTables(&p->lenEnc, 1u << p->pb, p->ProbPrices); /*MAB 1u */ + LenPriceEnc_UpdateTables(&p->repLenEnc, 1u << p->pb, p->ProbPrices); /*MAB 1u */ +} + +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 i; + for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) + if (p->dictSize <= ((UInt32)1 << i)) + break; + p->distTableSize = i * 2; + + p->finished = False; + p->result = SZ_OK; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + p->nowPos64 = 0; + return SZ_OK; +} + +static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + p->rc.outStream = outStream; + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +} + +#if defined(USE_UNUSED_CODE) +/*MAB: static added */ +static SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, + ISeqInStream *inStream, UInt32 keepWindowSize, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} +#endif + +static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +{ + p->seqBufInStream.funcTable.Read = MyRead; + p->seqBufInStream.data = src; + p->seqBufInStream.rem = srcLen; +} + +#if defined(USE_UNUSED_CODE) +/*MAB: static added */ +static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + LzmaEnc_SetInputBuf(p, src, srcLen); + p->inStream = &p->seqBufInStream.funcTable; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} +#endif + +/*MAB: static added */ +static void LzmaEnc_Finish(CLzmaEncHandle pp) +{ + #ifdef COMPRESS_MF_MT + CLzmaEnc *p = (CLzmaEnc *)pp; + if (p->mtMode) + MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #endif +} + +typedef struct _CSeqOutStreamBuf +{ + ISeqOutStream funcTable; + Byte *data; + SizeT rem; + Bool overflow; +} CSeqOutStreamBuf; + +static size_t MyWrite(void *pp, const void *data, size_t size) +{ + CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; + if (p->rem < size) + { + size = p->rem; + p->overflow = True; + } + memcpy(p->data, data, size); + p->rem -= size; + p->data += size; + return size; +} + +#if defined(USE_UNUSED_CODE) +/*MAB: static added */ +static UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +} + +/*MAB: static added */ +static +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +} + +/*MAB: static added */ +static +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + UInt64 nowPos64; + SRes res; + CSeqOutStreamBuf outStream; + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = False; + p->finished = False; + p->result = SZ_OK; + + if (reInit) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + nowPos64 = p->nowPos64; + RangeEnc_Init(&p->rc); + p->rc.outStream = &outStream.funcTable; + + res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + + return res; +} +#endif + +SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + SRes res = SZ_OK; + + #ifdef COMPRESS_MF_MT + Byte allocaDummy[0x300]; + int i = 0; + for (i = 0; i < 16; i++) + allocaDummy[i] = (Byte)i; + #endif + + RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig)); + + for (;;) + { + res = LzmaEnc_CodeOneBlock(p, False, 0, 0); + if (res != SZ_OK || p->finished != 0) + break; + if (progress != 0) + { + res = progress->Progress(progress, p->nowPos64, (UInt64) RangeEnc_GetProcessed(&p->rc)); /*MAB casts */ + if (res != SZ_OK) + { + res = SZ_ERROR_PROGRESS; + break; + } + } + } + LzmaEnc_Finish(pp); + return res; +} + +SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + int i; + UInt32 dictSize = p->dictSize; + if (*size < LZMA_PROPS_SIZE) + return SZ_ERROR_PARAM; + *size = LZMA_PROPS_SIZE; + props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); + + for (i = 11; i <= 30; i++) + { + if (dictSize <= ((UInt32)2 << i)) + { + dictSize = (UInt32)(2 << i); /*MAB casts */ + break; + } + if (dictSize <= ((UInt32)3 << i)) + { + dictSize = (UInt32)(3 << i); /*MAB casts */ + break; + } + } + + for (i = 0; i < 4; i++) + props[1 + i] = (Byte)(dictSize >> (8 * i)); + return SZ_OK; +} + +SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + SRes res; + CLzmaEnc *p = (CLzmaEnc *)pp; + + CSeqOutStreamBuf outStream; + + LzmaEnc_SetInputBuf(p, src, srcLen); + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = writeEndMark; + res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable, + progress, alloc, allocBig); + + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + return res; +} + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); + SRes res; + if (p == 0) + return SZ_ERROR_MEM; + + res = LzmaEnc_SetProps(p, props); + if (res == SZ_OK) + { + res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); + if (res == SZ_OK) + res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, + writeEndMark, progress, alloc, allocBig); + } + + LzmaEnc_Destroy(p, alloc, allocBig); + return res; +} +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/src/db/gaviota/gtb/compression/lzma/LzmaEnc.h b/src/db/gaviota/gtb/compression/lzma/LzmaEnc.h new file mode 100755 index 00000000..bfbc7d2b --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/LzmaEnc.h @@ -0,0 +1,72 @@ +/* LzmaEnc.h -- LZMA Encoder +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZMAENC_H +#define __LZMAENC_H + +#include "Types.h" + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaEncProps +{ + int level; /* 0 <= level <= 9 */ + UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version + (1 << 12) <= dictSize <= (1 << 30) for 64-bit version + default = (1 << 24) */ + int lc; /* 0 <= lc <= 8, default = 3 */ + int lp; /* 0 <= lp <= 4, default = 0 */ + int pb; /* 0 <= pb <= 4, default = 2 */ + int algo; /* 0 - fast, 1 - normal, default = 1 */ + int fb; /* 5 <= fb <= 273, default = 32 */ + int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ + int numHashBytes; /* 2, 3 or 4, default = 4 */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ + int numThreads; /* 1 or 2, default = 2 */ +} CLzmaEncProps; + +void LzmaEncProps_Init(CLzmaEncProps *p); +void LzmaEncProps_Normalize(CLzmaEncProps *p); +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); + + +/* ---------- CLzmaEncHandle Interface ---------- */ + +/* LzmaEnc_* functions can return the following exit codes: +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - Write callback error. + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +typedef void * CLzmaEncHandle; + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +/* ---------- One Call Interface ---------- */ + +/* LzmaEncode +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +#endif diff --git a/src/db/gaviota/gtb/compression/lzma/Types.h b/src/db/gaviota/gtb/compression/lzma/Types.h new file mode 100755 index 00000000..baac1284 --- /dev/null +++ b/src/db/gaviota/gtb/compression/lzma/Types.h @@ -0,0 +1,208 @@ +/* Types.h -- Basic types +2008-11-23 : Igor Pavlov : Public domain */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#include + +#if _WIN32 || _WIN64 +#include +#endif + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + +#if _WIN32 || _WIN64 +typedef DWORD WRes; +#else +typedef int WRes; +#endif + +#ifndef RINOK +#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +#ifdef _LZMA_UINT32_IS_ULONG +typedef long Int32; +typedef unsigned long UInt32; +#else +typedef int Int32; +typedef unsigned int UInt32; +#endif + +#ifdef _SZ_NO_INT_64 + +/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. + NOTES: Some code will work incorrectly in that case! */ + +typedef long Int64; +typedef unsigned long UInt64; + +#else + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +#endif + +#endif + +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +typedef size_t SizeT; +#endif + +typedef int Bool; +#define True 1 +#define False 0 + + +#ifdef _MSC_VER + +#if _MSC_VER >= 1300 +#define MY_NO_INLINE __declspec(noinline) +#else +#define MY_NO_INLINE +#endif + +#define MY_CDECL __cdecl +#define MY_STD_CALL __stdcall +#define MY_FAST_CALL MY_NO_INLINE __fastcall + +#else + +#define MY_CDECL +#define MY_STD_CALL +#define MY_FAST_CALL + +#endif + + +/* The following interfaces use first parameter as pointer to structure */ + +typedef struct ISeqInStream +{ + SRes (*Read)(void *p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +} ISeqInStream; + +/* it can return SZ_ERROR_INPUT_EOF */ +SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); +SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); + +typedef struct ISeqOutStream +{ + size_t (*Write)(void *p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +} ISeqOutStream; + +typedef enum ESzSeek +{ + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + +typedef struct ISeekInStream +{ + SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +} ISeekInStream; + +typedef struct ILookInStream +{ + SRes (*Look)(void *p, void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) > input(*size)) is not allowed + (output(*size) < input(*size)) is allowed */ + SRes (*Skip)(void *p, size_t offset); + /* offset must be <= output(*size) of Look */ + + SRes (*Read)(void *p, void *buf, size_t *size); + /* reads directly (without buffer). It's same as ISeqInStream::Read */ + SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +} ILookInStream; + +SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); + +/* reads via ILookInStream::Read */ +SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); + +#define LookToRead_BUF_SIZE (1 << 14) + +typedef struct CLookToRead +{ + ILookInStream s; + ISeekInStream *realStream; + size_t pos; + size_t size; + Byte buf[LookToRead_BUF_SIZE]; +} CLookToRead; + +void LookToRead_CreateVTable(CLookToRead *p, int lookahead); +void LookToRead_Init(CLookToRead *p); + +typedef struct CSecToLook +{ + ISeqInStream s; + ILookInStream *realStream; +} CSecToLook; + +void SecToLook_CreateVTable(CSecToLook *p); + +typedef struct CSecToRead +{ + ISeqInStream s; + ILookInStream *realStream; +} CSecToRead; + +void SecToRead_CreateVTable(CSecToRead *p); + +typedef struct ICompressProgress +{ + SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +} ICompressProgress; + +typedef struct ISzAlloc +{ + void *(*Alloc)(void *p, size_t size); + void (*Free)(void *p, void *address); /* address can be 0 */ +} ISzAlloc; + +#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) +#define IAlloc_Free(p, a) (p)->Free((p), a) + +#endif diff --git a/src/db/gaviota/gtb/compression/wrap.c b/src/db/gaviota/gtb/compression/wrap.c new file mode 100644 index 00000000..1462d037 --- /dev/null +++ b/src/db/gaviota/gtb/compression/wrap.c @@ -0,0 +1,338 @@ +/* wrap.c */ + +/* +This Software is distributed with the following X11 License, +sometimes also known as MIT license. + +Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "wrap.h" + +#if defined(LZMA86) +#include "./lzma/Lzma86Enc.h" +#include "./lzma/Lzma86Dec.h" +#endif + +#if defined(ZLIB) +#include "zlib.h" +#endif + +#if defined(HUFFMAN) +#include "hzip.h" +#endif + +#if defined(LIBLZF) +#include "lzf.h" +#endif + +#if defined(LIBBZIP2) +#include "bzlib.h" +#endif + +#if !defined(NDEBUG) +#define NDEBUG +#endif +#ifdef DEBUG +#undef NDEBUG +#endif +#include "assert.h" + +/* external, so the compiler can be silenced */ +size_t TB_DUMMY_unused; + +/***********************************************************************************************************/ + +#if defined(ZLIB) +extern int +zlib_encode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + enum COMPRESSION_LEVELS {ZLIB_MAXIMUM_COMPRESSION = 9}; + int outcome; + unsigned long zz = (unsigned long)out_max; + outcome = compress2 (out_start, &zz, in_start, in_len, ZLIB_MAXIMUM_COMPRESSION); + *pout_len = (size_t) zz; + return outcome == Z_OK; +} + +extern int +zlib_decode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + int outcome; + unsigned long nn = (unsigned long) out_max /* *pout_len */; + outcome = uncompress (out_start, &nn, in_start, (unsigned long)in_len); + *pout_len = (size_t)nn; + return outcome == Z_OK; +} +#endif + +/***********************************************************************************************************/ + +#if defined(LIBLZF) +extern int +lzf_encode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + size_t x = lzf_compress (in_start, (unsigned)in_len, out_start, (unsigned)(in_len-1) /* ensures best compression */); + TB_DUMMY_unused = out_max; + if (x != 0) + *pout_len = (size_t) x; + return x != 0; +} + +extern int +lzf_decode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + *pout_len = (size_t)lzf_decompress (in_start, (unsigned)in_len, out_start, (unsigned)out_max); + return *pout_len != 0; +} +#endif + +/***********************************************************************************************************/ + +#if defined(LZMA86) +extern int +lzma_encode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + int level = 5; /* 5 => default compression level */ + unsigned int memory = 4096; /* dictionary size */ + int filter = SZ_FILTER_NO; /* => 0, use LZMA, do not try to optimize with x86 filter */ + size_t zz = out_max; /* maximum memory allowed, receives back the actual size */ + int x = Lzma86_Encode(out_start, &zz, in_start, in_len, level, memory, filter); + *pout_len = zz; + return x == 0; +} + +extern int +lzma_decode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + size_t nn = out_max; + int x = Lzma86_Decode(out_start, &nn, in_start, &in_len); + *pout_len = nn; + return x == SZ_OK; +} +#endif + +/***********************************************************************************************************/ + +#if defined (LIBBZIP2) + +extern int +bzip2_encode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + int blockSize100k = 9; + int verbosity = 0; + int workFactor = 30; + size_t destlen = out_max; + + int x = BZ2_bzBuffToBuffCompress( (char*)out_start, &destlen, (char*)in_start, in_len, + blockSize100k, verbosity, workFactor); + *pout_len = destlen; + return x == BZ_OK; +} + +extern int +bzip2_decode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + int small = 1; + int verbosity = 0; + size_t destlen = n; + + int x = BZ2_bzBuffToBuffDecompress( (char*)out_start, &destlen, (char*)in_start, in_len, + small, verbosity); + *pout_len = destlen; + return x == BZ_OK; +} + +#endif + +/***********************************************************************************************************/ + +extern int +justcopy_encode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + size_t i; + const unsigned char *in = in_start; + unsigned char *out = out_start; + + if (in_len > out_max) + return 0; + + for (i = 0; i < in_len; i++) { + *out++ = *in++; + } + *pout_len = in_len; + return 1; +} + +extern int +justcopy_decode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + size_t i; + const unsigned char *in = in_start; + unsigned char *out = out_start; + + if (in_len > out_max) + return 0; + + for (i = 0; i < in_len; i++) { + *out++ = *in++; + } + *pout_len = in_len; + return 1; +} + +/***********************************************************************************************************/ + +#define RLE_ESC 253 +#define RLE_TER 254 +#define RLE_MAX 252 +#define TRUE 1 +#define FALSE 0 + +extern int +rle_encode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + const unsigned char *p; + const unsigned char *in = in_start; + const unsigned char *in_end = in + in_len; + unsigned char *out = out_start; + int ok = TRUE; + int ch; + ptrdiff_t out_len; + + while (in < in_end) + { + if (*in == RLE_ESC) { + + *out++ = RLE_ESC; + *out++ = RLE_ESC; + in++; + + } else { + + ch = *in; + + if ( (in_end-in) >= 3 /* enough space for a run */ + && ch == in[1] && ch == in[2] && ch == in[3] /* enough length */) { + + p = in; + while (p < in_end && *p == ch && (p-in) < RLE_MAX) { + p++; + } + + *out++ = RLE_ESC; + assert (RLE_MAX < 256); + *out++ = (unsigned char)(p - in); + *out++ = (unsigned char)ch; + in = p; + + } else { + *out++ = *in++; + } + } + } + + if (ok) { + /* *out++ = RLE_ESC; *out++ = RLE_TER; */ + out_len = out - out_start; + *pout_len = (size_t)out_len; + ok = (size_t)out_len <= out_max; + } + + return ok; +} + +extern int +rle_decode +(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max) +{ + const unsigned char *in = in_start; + const unsigned char *in_end = in + in_len; + unsigned char *out = out_start; + unsigned char *out_end = out + *pout_len; + int ok = TRUE; + int ch; + int n; + ptrdiff_t out_len; + + while (in < in_end) + { + if (in >= in_end) { ok = FALSE; break;} + if (out >= out_end) { ok = FALSE; break;} + + if (*in == RLE_ESC) { + ++in; if (in >= in_end) { ok = FALSE; break;} + + if (*in == RLE_ESC) { + *out++ = *in++; + } /*else if (*in == RLE_TER) {ok = TRUE;break;} */ else { + + /* rle */ + n = *in++; if (in >= in_end) { ok = FALSE; break;} + ch = *in++; + while (n-->0) { if (out >= out_end) { ok = FALSE; break;} + *out++ = (unsigned char)ch; + } + } + } else { + *out++ = *in++; + } + } + + out_len = out - out_start; + + if (ok) + *pout_len = (size_t)out_len; + + ok = ok && (out_max >= (size_t)out_len); + + return ok; +} + + + + + + + + + + + + + + + + diff --git a/src/db/gaviota/gtb/compression/wrap.h b/src/db/gaviota/gtb/compression/wrap.h new file mode 100644 index 00000000..38500a7d --- /dev/null +++ b/src/db/gaviota/gtb/compression/wrap.h @@ -0,0 +1,70 @@ +/* wrap.h */ + +/* + X11 License: + + Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + +#if !defined(H_WRAP) +#define H_WRAP + +#define LZMA86 +/*#define ZLIB*/ +/*#define HUFFMAN*/ +/*#define LIBLZF*/ +/*#define LIBBZIP2*/ + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +#include + +#if defined(ZLIB) +extern int zlib_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +extern int zlib_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +#endif + +#if defined(LLIBLZF) +extern int lzf_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +extern int lzf_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +#endif + +#if defined(LZMA86) +extern int lzma_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +extern int lzma_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +#endif + +#if defined (LIBBZIP2) +extern int bzip2_encode(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +extern int bzip2_decode(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +#endif + +extern int rle_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +extern int rle_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); + +extern int justcopy_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); +extern int justcopy_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max); + + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ +#endif diff --git a/src/db/gaviota/gtb/gtb-att.c b/src/db/gaviota/gtb/gtb-att.c new file mode 100644 index 00000000..62001648 --- /dev/null +++ b/src/db/gaviota/gtb/gtb-att.c @@ -0,0 +1,390 @@ +/* +This Software is distributed with the following X11 License, +sometimes also known as MIT license. + +Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include "gtb-att.h" + +#if 0 + +#include "mtypes.h" +#include "bool_t.h" +#include "maindef.h" + +#else + +/* mtypes.h */ + +typedef unsigned int SQUARE; +typedef unsigned char SQ_CONTENT; + +/* bool_t.h */ + +#if !defined(bool_t) +typedef int bool_t; +#endif + +#if !defined(TRUE) +#define TRUE ((bool_t)1) +#endif + +#if !defined(FALSE) +#define FALSE ((bool_t)0) +#endif + +/* maindef.h */ + +#define NOPIECE 0u +#define PAWN 1u +#define KNIGHT 2u +#define BISHOP 3u +#define ROOK 4u +#define QUEEN 5u +#define KING 6u +#define PIECE_MASK (KING|PAWN|KNIGHT|BISHOP|ROOK|QUEEN) + +/*Whites*/ +#define wK (KING | WHITES) +#define wP (PAWN | WHITES) +#define wN (KNIGHT | WHITES) +#define wB (BISHOP | WHITES) +#define wR (ROOK | WHITES) +#define wQ (QUEEN | WHITES) + +/*Blacks*/ +#define bK (KING | BLACKS) +#define bP (PAWN | BLACKS) +#define bN (KNIGHT | BLACKS) +#define bB (BISHOP | BLACKS) +#define bR (ROOK | BLACKS) +#define bQ (QUEEN | BLACKS) + +/*Bits that define color */ + +#define WHITES (1u<<6) +#define BLACKS (1u<<7) + +/*squares*/ +enum SQUARES { + A1,B1,C1,D1,E1,F1,G1,H1, + A2,B2,C2,D2,E2,F2,G2,H2, + A3,B3,C3,D3,E3,F3,G3,H3, + A4,B4,C4,D4,E4,F4,G4,H4, + A5,B5,C5,D5,E5,F5,G5,H5, + A6,B6,C6,D6,E6,F6,G6,H6, + A7,B7,C7,D7,E7,F7,G7,H7, + A8,B8,C8,D8,E8,F8,G8,H8, + NOSQUARE, + ERRSQUARE = 128 +}; +#endif + +/*----------------------------------------------------------------------*/ + +#ifndef NDEBUG +#define NDEBUG +#endif +#ifdef DEBUG +#undef NDEBUG +#endif +#include "assert.h" + +/*----------------------------------------------------------------------*/ + +/* global variables */ +uint64_t Reach [7] [64]; + +/* static variables */ +static unsigned char attmap [64] [64]; +static unsigned int attmsk [256]; + +/* static functions */ +static unsigned int mapx88 (unsigned int x); + +/* macros */ +#define BB_ISBITON(bb,bit) (0 != (((bb)>>(bit)) & U64(1))) + +#define map88(x) ( (x) + ((x)&070) ) +#define unmap88(x) ( ( (x) + ((x)& 07) ) >> 1 ) + +/*----------------------------------------------------------------------*/ + +static unsigned int +mapx88 (unsigned int x) +{ + return ((x & 070) << 1) | (x & 07); +} + + +void +attack_maps_init(void) +{ + int i; + unsigned int m, from, to; + unsigned int to88, fr88; + int diff; + + uint64_t rook, bishop, queen, knight, king; + + if (!reach_was_initialized()) { + printf ("Wrong initialization order of data\n"); + exit(EXIT_FAILURE); + } + + for (i = 0; i < 256; ++i) { + attmsk [i] = 0; + } + attmsk[wP] = 1 << 0; + attmsk[bP] = 1 << 1; + + attmsk[KNIGHT] = 1 << 2; + attmsk[wN] = 1 << 2; + attmsk[bN] = 1 << 2; + + attmsk[BISHOP] = 1 << 3; + attmsk[wB] = 1 << 3; + attmsk[bB] = 1 << 3; + + attmsk[ROOK ] = 1 << 4; + attmsk[wR] = 1 << 4; + attmsk[bR] = 1 << 4; + + attmsk[QUEEN ] = 1 << 5; + attmsk[wQ] = 1 << 5; + attmsk[bQ] = 1 << 5; + + attmsk[KING ] = 1 << 6; + attmsk[wK] = 1 << 6; + attmsk[bK] = 1 << 6; + + for (to = 0; to < 64; ++to) { + for (from = 0; from < 64; ++from) { + m = 0; + rook = Reach [ROOK] [from]; + bishop = Reach [BISHOP] [from]; + queen = Reach [QUEEN] [from]; + knight = Reach [KNIGHT] [from]; + king = Reach [KING] [from]; + + if (BB_ISBITON (knight, to)) { + m |= attmsk[wN]; + } + if (BB_ISBITON (king, to)) { + m |= attmsk[wK]; + } + if (BB_ISBITON (rook, to)) { + m |= attmsk[wR]; + } + if (BB_ISBITON (bishop, to)) { + m |= attmsk[wB]; + } + if (BB_ISBITON (queen, to)) { + m |= attmsk[wQ]; + } + + to88 = mapx88(to); + fr88 = mapx88(from); + diff = (int)to88 - (int)fr88; + + if (diff == 17 || diff == 15) { + m |= attmsk[wP]; + } + if (diff == -17 || diff == -15) { + m |= attmsk[bP]; + } + + attmap [to] [from] = (unsigned char) m; + } + } + +} + +bool_t +possible_attack(unsigned int from, unsigned int to, unsigned int piece) +{ + + assert (piece < 256); + assert (from < 64 && to < 64); + assert (reach_was_initialized()); + assert (attmsk [piece] != 0 || 0==fprintf(stderr, "PIECE=%d\n",piece) ); /* means piece has been considered */ + + return 0 != (attmap [to] [from] & attmsk [piece]); +} + +/* +| +| REACH ROUTINES +| +\*----------------------------------------------*/ + + +enum Key {REACH_INITIALIZED_KEY = 0x1313}; +static int reach_initialized_key = 0; + +bool_t +reach_was_initialized (void) +{ + return reach_initialized_key == REACH_INITIALIZED_KEY; +} + +void +reach_init (void) +{ + SQUARE buflist[64+1], *list; + SQ_CONTENT pc; + int stp_a [] = {15, -15 }; + int stp_b [] = {17, -17 }; + int STEP_A, STEP_B; + unsigned int side; + unsigned int index; + SQUARE sq, us; + + int s; + + for (pc = KNIGHT; pc < (KING+1); pc++) { + for (sq = 0; sq < 64; sq++) { + uint64_t bb = U64(0x0); + tolist_rev (U64(0x0), pc, sq, buflist); + for (list = buflist; *list != NOSQUARE; list++) { + bb |= U64(1) << *list; + } + Reach [pc] [sq] = bb; + } + } + + for (side = 0; side < 2; side++) { + index = 1u ^ side; + STEP_A = stp_a[side]; + STEP_B = stp_b[side]; + for (sq = 0; sq < 64; sq++) { + + int sq88 = (int)map88(sq); + uint64_t bb = U64(0x0); + + list = buflist; + + + s = sq88 + STEP_A; + if (0 == (s & 0x88)) { + us = (SQUARE)unmap88(s); + *list++ = us; + } + s = sq88 + STEP_B; + if (0 == (s & 0x88)) { + us = (SQUARE)unmap88(s); + *list++ = us; + } + *list = NOSQUARE; + + for (list = buflist; *list != NOSQUARE; list++) { + bb |= U64(1) << *list; + } + Reach [index] [sq] = bb; + } + } + reach_initialized_key = REACH_INITIALIZED_KEY; +} + +/*--------------------------------------------------------------------------------*/ + +static const int bstep[] = { 17, 15, -15, -17, 0}; +static const int rstep[] = { 1, 16, -1, -16, 0}; +static const int nstep[] = { 18, 33, 31, 14, -18, -33, -31, -14, 0}; +static const int kstep[] = { 1, 17, 16, 15, -1, -17, -16, -15, 0}; + +static const +int *psteparr[] = {NULL, NULL, /* NOPIECE & PAWN */ + nstep, bstep, rstep, kstep, kstep /* same for Q & K*/ + }; +static const +int pslider[] = {FALSE, FALSE, + FALSE, TRUE, TRUE, TRUE, FALSE + }; + +void +tolist_rev (uint64_t occ, SQ_CONTENT input_piece, SQUARE sq, SQUARE *list) +/* reversible moves from pieces. Output is a list of squares */ +{ + int direction; + unsigned int pc; + int s; + int from; + int step; + const int *steparr; + bool_t slider; + SQUARE us; + + assert (sq < 64); + + /* i.e. no pawn allowed as input */ + assert (input_piece == KNIGHT || input_piece == BISHOP || + input_piece == ROOK || input_piece == QUEEN || + input_piece == KING); + + from = (int)map88(sq); + + pc = input_piece & (PAWN|KNIGHT|BISHOP|ROOK|QUEEN|KING); + + steparr = psteparr [pc]; + slider = pslider [pc]; + + if (slider) { + + for (direction = 0; steparr[direction] != 0; direction++) { + step = steparr[direction]; + s = from + step; + while (0 == (s & 0x88)) { + us = (SQUARE)unmap88(s); + if (0 != (0x1u & (unsigned int)(occ >> us))) + break; + *list++ = us; + s += step; + } + } + + } else { + + for (direction = 0; steparr[direction] != 0; direction++) { + step = steparr[direction]; + s = from + step; + if (0 == (s & 0x88)) { + us = (SQUARE)unmap88(s); + if (0 == (0x1u & (unsigned int)(occ >> us))) { + *list++ = us; + } + } + } + } + + *list = NOSQUARE; + + return; +} + + + diff --git a/src/db/gaviota/gtb/gtb-att.h b/src/db/gaviota/gtb/gtb-att.h new file mode 100644 index 00000000..d3538c94 --- /dev/null +++ b/src/db/gaviota/gtb/gtb-att.h @@ -0,0 +1,43 @@ +/* +This Software is distributed with the following X11 License, +sometimes also known as MIT license. + +Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + +#if !defined(H_PROBATT) +#define H_PROBATT +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +#include "sysport/sysport.h" + +extern uint64_t Reach [7] [64]; + +extern void attack_maps_init (void); +extern int /*bool*/ possible_attack(unsigned int from, unsigned int to, unsigned int piece); +extern void reach_init (void); +extern int /*bool*/ reach_was_initialized (void); +extern void tolist_rev (uint64_t occ, unsigned char input_piece, unsigned int sq, unsigned int *list); + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ +#endif diff --git a/src/db/gaviota/gtb/gtb-dec.c b/src/db/gaviota/gtb/gtb-dec.c new file mode 100644 index 00000000..997426e3 --- /dev/null +++ b/src/db/gaviota/gtb/gtb-dec.c @@ -0,0 +1,143 @@ +/* +This Software is distributed with the following X11 License, +sometimes also known as MIT license. + +Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + +/*--------------------------------------------------------------------------*\ +| +| Compressing wrapper functions +| +*---------------------------------------------------------------------------*/ +#define MAXBLOCK (1 << 16) + +#include +#include "gtb-dec.h" +#ifdef HUFFMAN +#include "hzip.h" +#endif +#include "compression/wrap.h" + +typedef int bool_t; + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0; +#endif + +/*static unsigned char intermediate_block[MAXBLOCK] ;*/ + +static int DECODE_SCHEME = CP4; +static int CP_SCHEME = CP4; + +static int f_decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp); + +extern void +set_decoding_scheme(int x) +{ + DECODE_SCHEME = x; + CP_SCHEME = x; +} + +extern int decoding_scheme(void) +{ + return DECODE_SCHEME; +} + +extern int +decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp) +{ + return f_decode (z, bz, n, bp); +} + +/*======================== WRAPPERS ========================*/ + +static int +f_decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp) +{ +/* bp buffer provided +| bz buffer "zipped", compressed +| n len of buffer provided +| z len of buffer zipped +\*---------------------------------------------------------------*/ + +/* + unsigned char *ib = intermediate_block; + unsigned int m; + return huff_decode (bz, z, ib, &m, MAXBLOCK) && rle_decode (ib, m, bp, &n, MAXBLOCK); +*/ +#if defined(HUFFMAN) + if (CP_SCHEME == CP1) { + + /* HUFFMAN */ + return huff_decode (bz, z, bp, &n, MAXBLOCK); + + } else +#endif +#if defined(LIBLZF) + if (CP_SCHEME == CP2) { + + /* LZF */ + return lzf_decode (bz, z, bp, &n, MAXBLOCK); + + } else +#endif +#if defined (ZLIB) + if (CP_SCHEME == CP3) { + + /* ZLIB */ + return zlib_decode (bz, z, bp, &n, MAXBLOCK); + + } else +#endif + if (CP_SCHEME == CP4) { + + /* LZMA86 */ + return lzma_decode (bz, z, bp, &n, n); /* maximum needs to be the exact number that it will produce */ + + } else if (CP_SCHEME == CP7) { + + /* RLE */ + return rle_decode (bz, z, bp, &n, MAXBLOCK); + + #if defined (LIBBZIP2) + } else if (CP_SCHEME == CP8) { + + /* BZIP2 */ + return bzip2_decode (bz, z, bp, &n, MAXBLOCK); + #endif + + } else if (CP_SCHEME == CP9) { + + return justcopy_decode (bz, z, bp, &n, MAXBLOCK); + + } else { + + return FALSE; + } +} + diff --git a/src/db/gaviota/gtb/gtb-dec.h b/src/db/gaviota/gtb/gtb-dec.h new file mode 100644 index 00000000..82ac3472 --- /dev/null +++ b/src/db/gaviota/gtb/gtb-dec.h @@ -0,0 +1,50 @@ +/* +This Software is distributed with the following X11 License, +sometimes also known as MIT license. + +Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* gtb-dec.h */ +#if !defined(H_DECOD) +#define H_DECOD + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +#include + +enum Compression {CP0, CP1, CP2, CP3, CP4, CP5, CP6, CP7, CP8, CP9, CP_END}; + +extern void set_decoding_scheme(int x); + +extern int decoding_scheme(void); + +extern int decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp); + +/* +This function should be included with the TB compressor +extern int encode (size_t n, unsigned char *bp, size_t *z, unsigned char *bz); +*/ + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ +#endif diff --git a/src/db/gaviota/gtb/gtb-probe.c b/src/db/gaviota/gtb/gtb-probe.c new file mode 100644 index 00000000..f21ac4fa --- /dev/null +++ b/src/db/gaviota/gtb/gtb-probe.c @@ -0,0 +1,8447 @@ +/* +This Software is distributed with the following X11 License, +sometimes also known as MIT license. + +Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + + +/* NBBOTF will remove the internal bitbase on the fly */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + +#ifdef NBBOTF + #ifdef WDL_PROBE + #undef WDL_PROBE + #endif +#else +#define WDL_PROBE +#endif + +/*-- Intended to be modified to make public --> Supporting functions the TB generator ---------------------*/ + +#ifdef GTB_SHARE +#define SHARED_forbuilding +#endif + +/*---------------------------------------------------------------------------------------------------------*/ +#include +#include +#include + +#include "gtb-probe.h" + +#if defined(SHARED_forbuilding) +#include "gtb-prob2.h" +#else +#define mySHARED static +typedef unsigned char SQ_CONTENT; +typedef unsigned int SQUARE; +#endif + +#include "sysport/sysport.h" +#include "gtb-att.h" +#include "gtb-types.h" + +/*---------------------------------------------------------------------------------------------------------*/ +/*#include "posit_t.h"*/ + +#define MAX_LISTSIZE 17 +#if 0 + typedef unsigned sq_t; +typedef unsigned char pc_t; +typedef uint32_t mv_t; +#endif + +struct posit { + sq_t ws[MAX_LISTSIZE]; + sq_t bs[MAX_LISTSIZE]; + pc_t wp[MAX_LISTSIZE]; + pc_t bp[MAX_LISTSIZE]; + sq_t ep; + unsigned int stm; + unsigned int cas; +}; +typedef struct posit posit_t; + +#if 0 +typedef long int tbkey_t; +#endif + +/*---------------------------------------------------------------------------------------------------------*/ +/*#include "bool_t.h"*/ + +#if !defined(H_BOOL) +typedef int bool_t; +#endif + +#if !defined(TRUE) +#define TRUE ((bool_t)1) +#endif + +#if !defined(FALSE) +#define FALSE ((bool_t)0) +#endif + +/*--------- private if external building code is not present ----------------------------------------------*/ + +#if !defined(SHARED_forbuilding) + +#define MAX_EGKEYS 145 +#define SLOTSIZE 1 +#define NOINDEX ((index_t)(-1)) + +#if 0 + typedef unsigned short int dtm_t; +typedef size_t index_t; +/*typedef int index_t;*/ +#endif + +enum Loading_status { + STATUS_ABSENT = 0, + STATUS_STATICRAM = 1, + STATUS_MALLOC = 2, + STATUS_FILE = 3, + STATUS_REJECT = 4 +}; + +struct endgamekey { + int id; + const char *str; + index_t maxindex; + index_t slice_n; + + void (*itopc)(index_t, SQUARE *, SQUARE *); + + bool_t (*pctoi)(const SQUARE *, const SQUARE *, index_t *); + + dtm_t *egt_w; + dtm_t *egt_b; + FILE *fd; + int status; + int pathn; +}; + +#endif + +/*----------------------------------------------------------------------------------------------------------*/ + +/* array for better moves */ +#ifdef GTB_SHARE +mySHARED int bettarr [2] [8] [8]; +#endif + +/*------------ ENUMS ----------------------------------------------------------*/ + +enum Mask_values { + RESMASK = tb_RESMASK, + INFOMASK = tb_INFOMASK, + PLYSHIFT = tb_PLYSHIFT +}; + +enum Info_values { + iDRAW = tb_DRAW, + iWMATE = tb_WMATE, + iBMATE = tb_BMATE, + iFORBID = tb_FORBID, + + iDRAWt = tb_DRAW | 4, + iWMATEt = tb_WMATE | 4, + iBMATEt = tb_BMATE | 4, + iUNKNOWN = tb_UNKNOWN, + + iUNKNBIT = (1 << 2) +}; + +/*-------------------------- inherited from a previous maindef.h -----------*/ + +#define WHITES (1u<<6) +#define BLACKS (1u<<7) + +#define NOPIECE 0u +#define PAWN 1u +#define KNIGHT 2u +#define BISHOP 3u +#define ROOK 4u +#define QUEEN 5u +#define KING 6u + +#define WH 0 +#define BL 1 +#define Opp(x) ((x)^1) +#define wK (KING | WHITES) + +/*------------------- + SQUARES + -------------------*/ + +/* from 1-63 different squares posibles */ + +/*squares*/ +enum SQUARES { + A1, B1, C1, D1, E1, F1, G1, H1, + A2, B2, C2, D2, E2, F2, G2, H2, + A3, B3, C3, D3, E3, F3, G3, H3, + A4, B4, C4, D4, E4, F4, G4, H4, + A5, B5, C5, D5, E5, F5, G5, H5, + A6, B6, C6, D6, E6, F6, G6, H6, + A7, B7, C7, D7, E7, F7, G7, H7, + A8, B8, C8, D8, E8, F8, G8, H8, + NOSQUARE, + ERRSQUARE = 128 +}; + +/*------------------- end of inherited from a previous maindef.h -----------*/ + +#if !defined(NDEBUG) +#define NDEBUG +#endif +#ifdef DEBUG +#undef NDEBUG +#endif + +#include "assert.h" + +/*------------------- general DEFINES--------------------------- -----------*/ + +#define gtbNOSIDE ((unsigned)-1) +#define gtbNOINDEX ((index_t)-1) + +/*************************************************\ +| +| COMPRESSION SCHEMES +| +\*************************************************/ + +#include "gtb-dec.h" + +static const char *const Extension[] = { + ".gtb.cp0", ".gtb.cp1", ".gtb.cp2", ".gtb.cp3", ".gtb.cp4", ".gtb.cp5", ".gtb.cp6", ".gtb.cp7", ".gtb.cp8", + ".gtb.cp9" +}; + +/*************************************************\ +| +| MOVES +| +\*************************************************/ + +enum move_kind { + NORMAL_MOVE = 0, + CASTLE_MOVE, + PASSNT_MOVE, + PROMOT_MOVE +}; + +enum move_content { + NOMOVE = 0 +}; + +#define MV_TYPE(mv) ( (BYTE) ((mv) >>6 & 3 ) ) +#define MV_TO(mv) ( (SQUARE) ((mv) >>8 & 63) ) +#define MV_PT(mv) ( (SQ_CONTENT) ((mv) >>(3+16) &7 ) ) +#define MV_TK(mv) ( (SQ_CONTENT) ((mv) >>(6+16) &7 ) ) +#define MV_FROM(mv) ( (SQUARE) ((mv) & 63) ) + +/* +| move,type,color,piece,from,to,taken,promoted +*------------------------------------------------------------------*/ + +#define MV_BUILD(mv, ty, co, pc, fr, to, tk, pm) ( \ + (mv) = (fr) | (to)<< 8 | (ty)<< 6 | (co)<<8 \ + | (pc)<<16 | (pm)<< (3+16) | (tk)<< (6+16) \ +) + +#define MV_ADD_TOTK(mv, to, tk) ( \ + mv |= (uint32_t)(to) << 8 \ + | (uint32_t)(tk) << (6+16) \ +) + +#define map88(x) ( (x) + ((x)&070) ) +#define unmap88(x) ( ( (x) + ((x)& 07) ) >> 1 ) + +/*************************************************\ +| +| STATIC VARIABLES +| +\*************************************************/ + +static int GTB_scheme = 4; + +/*************************************************\ +| +| needed for +| PRE LOAD CACHE AND DEPENDENT FUNCTIONS +| +\*************************************************/ + +#define EGTB_MAXBLOCKSIZE 65536 + +static int GTB_MAXOPEN = 4; + +static bool_t Uncompressed = TRUE; + +static unsigned int zipinfo_init(void); + +static void zipinfo_done(void); + +enum Flip_flags { + WE_FLAG = 1, NS_FLAG = 2, NW_SE_FLAG = 4 +}; /* used in flipt */ + +struct filesopen { + int n; + tbkey_t *key; +}; + +/* STATIC GLOBALS */ + +static struct filesopen fd = {0, NULL}; + +static bool_t TB_INITIALIZED = FALSE; +static bool_t DTM_CACHE_INITIALIZED = FALSE; + +static int WDL_FRACTION = 64; +static int WDL_FRACTION_MAX = 128; + +static size_t DTM_cache_size = 0; +static size_t WDL_cache_size = 0; + +static unsigned int TB_AVAILABILITY = 0; + +/* LOCKS */ +static mythread_mutex_t Egtb_lock; + + +/****************************************************************************\ + * + * + * DEBUGGING or PRINTING ZONE + * + * + ****************************************************************************/ + +#if 0 + #define FOLLOW_EGTB +#ifndef DEBUG +#define DEBUG +#endif +#endif + +#define validsq(x) ((x) >= A1 && (x) <= H8) + +#if defined(DEBUG) +static void print_pos (const sq_t *ws, const sq_t *bs, const pc_t *wp, const pc_t *bp); +#endif + +#if defined(DEBUG) || defined(FOLLOW_EGTB) + static void output_state (unsigned stm, const SQUARE *wSQ, const SQUARE *bSQ, + const SQ_CONTENT *wPC, const SQ_CONTENT *bPC); +static const char *Square_str[64] = { + "a1","b1","c1","d1","e1","f1","g1","h1", + "a2","b2","c2","d2","e2","f2","g2","h2", + "a3","b3","c3","d3","e3","f3","g3","h3", + "a4","b4","c4","d4","e4","f4","g4","h4", + "a5","b5","c5","d5","e5","f5","g5","h5", + "a6","b6","c6","d6","e6","f6","g6","h6", + "a7","b7","c7","d7","e7","f7","g7","h7", + "a8","b8","c8","d8","e8","f8","g8","h8" +}; +static const char *P_str[] = { + "--", "P", "N", "B", "R", "Q", "K" +}; +#endif + +#ifdef FOLLOW_EGTB + #define STAB + #define STABCONDITION 1 /*(stm == BL && whiteSQ[0]==H1 && whiteSQ[1]==D1 && whiteSQ[2]==D3 && blackSQ[0]==C2 )*/ + static bool_t GLOB_REPORT = TRUE; +#endif + +#if defined(FOLLOW_EGTB) + static const char *Info_str[8] = { + " Draw", " Wmate", " Bmate", "Illegal", + "~Draw", "~Wmate", "~Bmate", "Unknown" +}; +#endif + +static void list_index(void); + +static void fatal_error(void) { + exit(EXIT_FAILURE); +} + +#ifdef STAB +#define FOLLOW_LU(x,y) {if (GLOB_REPORT) printf ("************** %s: %lu\n", (x), (long unsigned)(y));} +#else +#define FOLLOW_LU(x, y) +#endif + +#ifdef STAB +#define FOLLOW_LULU(x,y,z) {if (GLOB_REPORT) printf ("************** %s: %lu, %lu\n", (x), (long unsigned)(y), (long unsigned)(z));} +#else +#define FOLLOW_LULU(x, y, z) +#endif + +#ifdef STAB +#define FOLLOW_label(x) {if (GLOB_REPORT) printf ("************** %s\n", (x));} +#else +#define FOLLOW_label(x) +#endif + +#ifdef STAB + #define FOLLOW_DTM(msg,dtm) {if (GLOB_REPORT) printf ("************** %s: %lu, info:%s, plies:%lu \n"\ + , (msg), (long unsigned)(dtm), (Info_str[(dtm)&INFOMASK]), (long unsigned)((dtm)>>PLYSHIFT)\ + );} +#else +#define FOLLOW_DTM(msg, dtm) +#endif + + +/*--------------------------------*\ +| +| +| INDEXING FUNCTIONS +| +| +*---------------------------------*/ + +#define IDX_set_empty(x) {x=0;x--;} +#define IDX_is_empty(x) (0==(1+(x))) + +#define NO_KKINDEX NOINDEX +#define MAX_KKINDEX 462 +#define MAX_PPINDEX 576 +#define MAX_PpINDEX (24 * 48) +/*1128*/ +#define MAX_AAINDEX ((63-62) + (62 * (127-62)/2) - 1 + 1) +#define MAX_AAAINDEX (64*21*31) +#define MAX_PP48_INDEX (1128) +/* (24*23*22/6) + 24 * (24*23/2) */ +#define MAX_PPP48_INDEX 8648 + +/* VARIABLES */ + +static index_t kkidx[64][64]; +static index_t ppidx[24][48]; +static index_t pp48_idx[48][48]; +static index_t ppp48_idx[48][48][48]; + +static sq_t wksq[MAX_KKINDEX]; +static sq_t bksq[MAX_KKINDEX]; +static sq_t pp48_sq_x[MAX_PP48_INDEX]; +static sq_t pp48_sq_y[MAX_PP48_INDEX]; + +static index_t pp_hi24[MAX_PPINDEX]; /* was unsigned int */ +static index_t pp_lo48[MAX_PPINDEX]; +static unsigned int flipt[64][64]; +static index_t aaidx[64][64]; /* was unsigned int */ +static unsigned char aabase[MAX_AAINDEX]; + +static uint8_t ppp48_sq_x[MAX_PPP48_INDEX]; +static uint8_t ppp48_sq_y[MAX_PPP48_INDEX]; +static uint8_t ppp48_sq_z[MAX_PPP48_INDEX]; + +/* FUNCTIONS */ + +static void init_indexing(int verbosity); + +static void norm_kkindex(SQUARE x, SQUARE y, /*@out@*/ SQUARE *pi, /*@out@*/ SQUARE *pj); + +static void pp_putanchorfirst(SQUARE a, SQUARE b, /*@out@*/ SQUARE *out_anchor, /*@out@*/ SQUARE *out_loosen); + +static index_t wsq_to_pidx24(SQUARE pawn); + +static index_t wsq_to_pidx48(SQUARE pawn); + +static SQUARE pidx24_to_wsq(index_t a); + +static SQUARE pidx48_to_wsq(index_t a); + +static SQUARE flipWE(SQUARE x) { return x ^ 07; } + +static SQUARE flipNS(SQUARE x) { return x ^ 070; } + +static SQUARE flipNW_SE(SQUARE x) { return ((x & 7) << 3) | (x >> 3); } + +static SQUARE getcol(SQUARE x) { return x & 7; } + +static SQUARE getrow(SQUARE x) { return x >> 3; } + +static bool_t in_queenside(sq_t x) { return 0 == (x & (1 << 2)); } + +/* 1:0 */ +static void kxk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 2:0 */ +static void kabk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kakb_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kaak_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 2:1 */ +static void kabkc_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kaakb_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 3:0 */ +static void kabck_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kaabk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kaaak_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kabbk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* one pawn */ +static void kpk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 1:1 one pawn */ +static void kakp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 2:0 one pawn */ +static void kapk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 2:0 two pawns */ +static void kppk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 2:1 one pawn */ +static void kapkb_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kabkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kaakp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 2:1 + 3:0 two pawns */ +static void kppka_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kappk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kapkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 3:0 one pawn */ +static void kabpk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kaapk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* three pawns */ +static void kpppk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static void kppkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* 1:1 two pawns */ +static void kpkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +/* corresponding pc to index */ +static bool_t kxk_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kabk_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kakb_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kpk_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kakp_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kapk_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kppk_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kaak_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kabkc_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kaakb_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/ + +static bool_t kabck_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kaabk_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/ +static bool_t kaaak_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kabbk_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/ +static bool_t kapkb_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kabkp_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +static bool_t kaakp_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); + +static bool_t kppka_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out); + +static bool_t kappk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); + +static bool_t kapkp_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); + +static bool_t kabpk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); + +static bool_t kaapk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); + +static bool_t kppkp_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); + +static bool_t kpppk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out); + +static bool_t kpkp_pctoindex(const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out); + +/* testing functions */ +static bool_t test_kppk(void); + +static bool_t test_kaakb(void); + +static bool_t test_kaabk(void); + +static bool_t test_kaaak(void); + +static bool_t test_kabbk(void); + +static bool_t test_kapkb(void); + +static bool_t test_kabkp(void); + +static bool_t test_kppka(void); + +static bool_t test_kappk(void); + +static bool_t test_kapkp(void); + +static bool_t test_kabpk(void); + +static bool_t test_kaapk(void); + +static bool_t test_kaakp(void); + +static bool_t test_kppkp(void); + +static bool_t test_kpppk(void); + +static unsigned flip_type(SQUARE x, SQUARE y); + +static index_t init_kkidx(void); + +static index_t init_ppidx(void); + +static void init_flipt(void); + +static index_t init_aaidx(void); + +static index_t init_aaa(void); + +static index_t init_pp48_idx(void); + +static index_t init_ppp48_idx(void); + +enum TB_INDEXES { + MAX_KXK = MAX_KKINDEX * 64, + MAX_kabk = MAX_KKINDEX * 64 * 64, + MAX_kakb = MAX_KKINDEX * 64 * 64, + MAX_kpk = 24 * 64 * 64, + MAX_kakp = 24 * 64 * 64 * 64, + MAX_kapk = 24 * 64 * 64 * 64, + MAX_kppk = MAX_PPINDEX * 64 * 64, + MAX_kpkp = MAX_PpINDEX * 64 * 64, + MAX_kaak = MAX_KKINDEX * MAX_AAINDEX, + MAX_kabkc = MAX_KKINDEX * 64 * 64 * 64, + MAX_kabck = MAX_KKINDEX * 64 * 64 * 64, + MAX_kaakb = MAX_KKINDEX * MAX_AAINDEX * 64, + MAX_kaabk = MAX_KKINDEX * MAX_AAINDEX * 64, + MAX_kabbk = MAX_KKINDEX * MAX_AAINDEX * 64, + MAX_kaaak = MAX_KKINDEX * MAX_AAAINDEX, + MAX_kapkb = 24 * 64 * 64 * 64 * 64, + MAX_kabkp = 24 * 64 * 64 * 64 * 64, + MAX_kabpk = 24 * 64 * 64 * 64 * 64, + MAX_kppka = MAX_kppk * 64, + MAX_kappk = MAX_kppk * 64, + MAX_kapkp = MAX_kpkp * 64, + MAX_kaapk = 24 * MAX_AAINDEX * 64 * 64, + MAX_kaakp = 24 * MAX_AAINDEX * 64 * 64, + MAX_kppkp = 24 * MAX_PP48_INDEX * 64 * 64, + MAX_kpppk = MAX_PPP48_INDEX * 64 * 64 +}; + +#if defined(SHARED_forbuilding) + extern index_t +biggest_memory_needed (void) { + return MAX_kabkc; +} +#endif + +/*--------------------------------*\ +| +| +| CACHE PROTOTYPES +| +| +*---------------------------------*/ + +#if !defined(SHARED_forbuilding) + +mySHARED bool_t get_dtm(tbkey_t key, unsigned side, index_t idx, dtm_t *out, bool_t probe_hard); + +#endif + +static bool_t get_dtm_from_cache(tbkey_t key, unsigned side, index_t idx, dtm_t *out); + + +/*--------------------------------*\ +| +| +| INIT +| +| +*---------------------------------*/ + +static bool_t fd_init(struct filesopen *pfd); + +static void fd_done(struct filesopen *pfd); + +static void RAM_egtbfree(void); + +/*--------------------------------------------------------------------------*/ +#if !defined(SHARED_forbuilding) + +mySHARED void egtb_freemem(int i); + +#endif + +mySHARED struct endgamekey egkey[] = { + + {0, "kqk", MAX_KXK, 1, kxk_indextopc, kxk_pctoindex, NULL, NULL, NULL, 0, 0}, + {1, "krk", MAX_KXK, 1, kxk_indextopc, kxk_pctoindex, NULL, NULL, NULL, 0, 0}, + {2, "kbk", MAX_KXK, 1, kxk_indextopc, kxk_pctoindex, NULL, NULL, NULL, 0, 0}, + {3, "knk", MAX_KXK, 1, kxk_indextopc, kxk_pctoindex, NULL, NULL, NULL, 0, 0}, + {4, "kpk", MAX_kpk, 24, kpk_indextopc, kpk_pctoindex, NULL, NULL, NULL, 0, 0}, + /* 4 pieces */ + {5, "kqkq", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {6, "kqkr", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {7, "kqkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {8, "kqkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + + {9, "krkr", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {10, "krkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {11, "krkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + + {12, "kbkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {13, "kbkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + + {14, "knkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL, NULL, NULL, 0, 0}, + /**/ + {15, "kqqk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL, NULL, NULL, 0, 0}, + {16, "kqrk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {17, "kqbk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {18, "kqnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL, NULL, NULL, 0, 0}, + + {19, "krrk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL, NULL, NULL, 0, 0}, + {20, "krbk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {21, "krnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL, NULL, NULL, 0, 0}, + + {22, "kbbk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL, NULL, NULL, 0, 0}, + {23, "kbnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL, NULL, NULL, 0, 0}, + + {24, "knnk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL, NULL, NULL, 0, 0}, + /**/ + /**/ + {25, "kqkp", MAX_kakp, 24, kakp_indextopc, kakp_pctoindex, NULL, NULL, NULL, 0, 0}, + {26, "krkp", MAX_kakp, 24, kakp_indextopc, kakp_pctoindex, NULL, NULL, NULL, 0, 0}, + {27, "kbkp", MAX_kakp, 24, kakp_indextopc, kakp_pctoindex, NULL, NULL, NULL, 0, 0}, + {28, "knkp", MAX_kakp, 24, kakp_indextopc, kakp_pctoindex, NULL, NULL, NULL, 0, 0}, + /**/ + {29, "kqpk", MAX_kapk, 24, kapk_indextopc, kapk_pctoindex, NULL, NULL, NULL, 0, 0}, + {30, "krpk", MAX_kapk, 24, kapk_indextopc, kapk_pctoindex, NULL, NULL, NULL, 0, 0}, + {31, "kbpk", MAX_kapk, 24, kapk_indextopc, kapk_pctoindex, NULL, NULL, NULL, 0, 0}, + {32, "knpk", MAX_kapk, 24, kapk_indextopc, kapk_pctoindex, NULL, NULL, NULL, 0, 0}, + /**/ + {33, "kppk", MAX_kppk, MAX_PPINDEX, kppk_indextopc, kppk_pctoindex, NULL, NULL, NULL, 0, 0}, + /**/ + {34, "kpkp", MAX_kpkp, MAX_PpINDEX, kpkp_indextopc, kpkp_pctoindex, NULL, NULL, NULL, 0, 0}, + /**/ + /**/ + /* 5 pieces */ + {35, "kqqqk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL, NULL, NULL, 0, 0}, + {36, "kqqrk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {37, "kqqbk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {38, "kqqnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {39, "kqrrk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL, NULL, NULL, 0, 0}, + {40, "kqrbk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL, NULL, NULL, 0, 0}, + {41, "kqrnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL, NULL, NULL, 0, 0}, + {42, "kqbbk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL, NULL, NULL, 0, 0}, + {43, "kqbnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL, NULL, NULL, 0, 0}, + {44, "kqnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL, NULL, NULL, 0, 0}, + {45, "krrrk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL, NULL, NULL, 0, 0}, + {46, "krrbk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {47, "krrnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {48, "krbbk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL, NULL, NULL, 0, 0}, + {49, "krbnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL, NULL, NULL, 0, 0}, + {50, "krnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL, NULL, NULL, 0, 0}, + {51, "kbbbk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL, NULL, NULL, 0, 0}, + {52, "kbbnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL, NULL, NULL, 0, 0}, + {53, "kbnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL, NULL, NULL, 0, 0}, + {54, "knnnk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL, NULL, NULL, 0, 0}, + {55, "kqqkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {56, "kqqkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {57, "kqqkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {58, "kqqkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {59, "kqrkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {60, "kqrkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {61, "kqrkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {62, "kqrkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {63, "kqbkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {64, "kqbkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {65, "kqbkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {66, "kqbkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {67, "kqnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {68, "kqnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {69, "kqnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {70, "kqnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {71, "krrkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {72, "krrkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {73, "krrkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {74, "krrkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {75, "krbkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {76, "krbkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {77, "krbkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {78, "krbkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {79, "krnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {80, "krnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {81, "krnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {82, "krnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {83, "kbbkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {84, "kbbkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {85, "kbbkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {86, "kbbkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {87, "kbnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {88, "kbnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {89, "kbnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {90, "kbnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL, NULL, NULL, 0, 0}, + {91, "knnkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {92, "knnkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {93, "knnkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + {94, "knnkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL, NULL, NULL, 0, 0}, + + {95, "kqqpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL, NULL, NULL, 0, 0}, + {96, "kqrpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL, NULL, NULL, 0, 0}, + {97, "kqbpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL, NULL, NULL, 0, 0}, + {98, "kqnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL, NULL, NULL, 0, 0}, + {99, "krrpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL, NULL, NULL, 0, 0}, + {100, "krbpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL, NULL, NULL, 0, 0}, + {101, "krnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL, NULL, NULL, 0, 0}, + {102, "kbbpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL, NULL, NULL, 0, 0}, + {103, "kbnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL, NULL, NULL, 0, 0}, + {104, "knnpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL, NULL, NULL, 0, 0}, + + {105, "kqppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL, NULL, NULL, 0, 0}, + {106, "krppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL, NULL, NULL, 0, 0}, + {107, "kbppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL, NULL, NULL, 0, 0}, + {108, "knppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL, NULL, NULL, 0, 0}, + + {109, "kqpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {110, "kqpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {111, "kqpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {112, "kqpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {113, "krpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {114, "krpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {115, "krpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {116, "krpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {117, "kbpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {118, "kbpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {119, "kbpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {120, "kbpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {121, "knpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {122, "knpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {123, "knpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + {124, "knpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL, NULL, NULL, 0, 0}, + + {125, "kppkq", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL, NULL, NULL, 0, 0}, + {126, "kppkr", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL, NULL, NULL, 0, 0}, + {127, "kppkb", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL, NULL, NULL, 0, 0}, + {128, "kppkn", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL, NULL, NULL, 0, 0}, + + {129, "kqqkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL, NULL, NULL, 0, 0}, + {130, "kqrkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {131, "kqbkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {132, "kqnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {133, "krrkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL, NULL, NULL, 0, 0}, + {134, "krbkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {135, "krnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {136, "kbbkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL, NULL, NULL, 0, 0}, + {137, "kbnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {138, "knnkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL, NULL, NULL, 0, 0}, + + {139, "kqpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {140, "krpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {141, "kbpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {142, "knpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL, NULL, NULL, 0, 0}, + + {143, "kppkp", MAX_kppkp, 24 * MAX_PP48_INDEX, kppkp_indextopc, kppkp_pctoindex, NULL, NULL, NULL, 0, 0}, + {144, "kpppk", MAX_kpppk, MAX_PPP48_INDEX, kpppk_indextopc, kpppk_pctoindex, NULL, NULL, NULL, 0, 0}, + + {MAX_EGKEYS, NULL, 0, 1, NULL, NULL, NULL, NULL, NULL, 0, 0} + +}; + +#define EGKEY_HASH_SIZE 512 +static tbkey_t egkey_hash[EGKEY_HASH_SIZE]; + +static size_t +str_hash_func_1(const char *str) { + size_t h = 5381; + int c; + while ((c = *str++)) + h = h * 31 + c; + return h; +} + +static size_t +str_hash_func_2(const char *str) { + size_t h = 0; + int c; + while ((c = *str++)) + h = h * 65599 + c; + return 2 * h + 1; +} + +static void +init_egkey_hash(void) { + size_t h1, h2; + int i; + + for (i = 0; i < EGKEY_HASH_SIZE; i++) + egkey_hash[i] = -1; + + for (i = 0; i < MAX_EGKEYS; i++) { + h1 = str_hash_func_1(egkey[i].str) & (EGKEY_HASH_SIZE - 1); + h2 = str_hash_func_2(egkey[i].str); + while (egkey_hash[h1] >= 0) + h1 = (h1 + h2) & (EGKEY_HASH_SIZE - 1); + egkey_hash[h1] = egkey[i].id; + } +} + + +static int eg_was_open[MAX_EGKEYS]; + +static uint64_t Bytes_read = 0; + +/****************************************************************************\ +| +| +| PATH MANAGEMENT ZONE +| +| +\****************************************************************************/ + +#define MAXPATHLEN tb_MAXPATHLEN +#define MAX_GTBPATHS 10 + +static int Gtbpath_end_index = 0; +static const char **Gtbpath = NULL; + +/*---------------- EXTERNAL PATH MANAGEMENT --------------------------------*/ + +extern const char *tbpaths_getmain(void) { return Gtbpath[0]; } + +extern const char ** +tbpaths_init(void) { + const char **newps; + newps = (const char **) malloc(sizeof(char *)); + if (newps != NULL) { + newps[0] = NULL; + } + return newps; +} + +static const char ** +tbpaths_add_single(const char **ps, const char *newpath) { + size_t counter; + const char **newps; + size_t i, psize; + char *ppath; + + if (NULL == ps) + return NULL; + + psize = strlen(newpath) + 1; + ppath = (char *) malloc(psize * sizeof(char)); + if (NULL == ppath) + return ps; /* failed to incorporate a new path */ + for (i = 0; i < psize; i++) ppath[i] = newpath[i]; + + for (counter = 0; ps[counter] != NULL; counter++); + + /* cast to deal with const poisoning */ + newps = (const char **) realloc((char **) ps, sizeof(char *) * (counter + 2)); + if (newps != NULL) { + newps[counter] = ppath; + newps[counter + 1] = NULL; + } + return newps; +} + + +extern const char ** +tbpaths_add(const char **ps, const char *newpath) { + size_t i, psize; + char *mpath; + + if (NULL == ps) + return NULL; + + psize = strlen(newpath) + 1; + mpath = (char *) malloc(psize * sizeof(char)); + if (NULL == mpath) { + return ps; /* failed to incorporate a new path */ + } + for (i = 0; i < psize; i++) mpath[i] = newpath[i]; + + for (i = 0; i < psize; i++) { + if (';' == mpath[i]) + mpath[i] = '\0'; + } + + for (i = 0;;) { + while (i < psize && mpath[i] == '\0') i++; + if (i >= psize) break; + ps = tbpaths_add_single(ps, &mpath[i]); + while (i < psize && mpath[i] != '\0') i++; + } + + free(mpath); + return ps; +} + + +extern const char ** +tbpaths_done(const char **ps) { + int counter; + void *q; + + if (ps != NULL) { + for (counter = 0; ps[counter] != NULL; counter++) { + /* cast to deal with const poisoning */ + void *p = (void *) ps[counter]; + free(p); + } + /* cast to deal with const poisoning */ + q = (void *) ps; + free(q); + } + return NULL; +} + +/*---------------- PATH INITIALIZATION ROUTINES ----------------------------*/ + +static void path_system_reset(void) { Gtbpath_end_index = 0; } + +static bool_t +path_system_init(const char **path) { + size_t i; + size_t sz; + const char *x; + bool_t ok = TRUE; + path_system_reset(); + + if (path == NULL) { + return FALSE; + } + + /* calculate needed size for Gtbpath */ + i = 0; + do { + x = path[i++]; + } while (x != NULL); + sz = i; /* sz includes the NULL */ + + + Gtbpath = (const char **) malloc(sz * sizeof(char *)); + + if (Gtbpath) { + + ok = TRUE; + /* point to the same strings provided */ + Gtbpath_end_index = 0; + for (i = 0; i < sz; i++) { + Gtbpath[i] = path[i]; + Gtbpath_end_index++; + } + + } else { + ok = FALSE; + } + return ok; + +} + +static void +path_system_done(void) { + /* before we free Gtbpath, we have to deal with the + "const poisoning" and cast it. free() does not accept + const pointers */ + char **p = (char **) Gtbpath; + /* clean up */ + if (p != NULL) + free(p); + return; +} + + +/****************************************************************************\ + * + * + * General Initialization Zone + * + * + ****************************************************************************/ + + +#ifdef WDL_PROBE + +static size_t wdl_cache_init(size_t cache_mem); + +static void wdl_cache_flush(void); + +static void wdl_cache_reset_counters(void); + +static void wdl_cache_done(void); + +static bool_t get_WDL_from_cache(tbkey_t key, unsigned side, index_t idx, unsigned int *out); + +static bool_t wdl_preload_cache(tbkey_t key, unsigned side, index_t idx); + +#endif + +#ifdef GTB_SHARE +static void init_bettarr (void); +#endif + +static void eg_was_open_reset(void) { + int i; + for (i = 0; i < MAX_EGKEYS; i++) { + eg_was_open[i] = 0; + } +} + +static long unsigned int eg_was_open_count(void) { + long int i, x; + for (i = 0, x = 0; i < MAX_EGKEYS; i++) { + x += eg_was_open[i]; + } + return (long unsigned) x; +} + + +enum Sizes { + INISIZE = 4096 +}; +static char ini_str[INISIZE]; + +static void sjoin(char *s, const char *tail, size_t max) { strncat(s, tail, max - strlen(s) - 1); } + +char * +tb_init(int verbosity, int decoding_sch, const char **paths) { + unsigned int zi; + int paths_ok; + char *ret_str; + char localstr[256]; + + assert(!TB_INITIALIZED); + + init_egkey_hash(); + + if (verbosity) { + ini_str[0] = '\0'; + ret_str = ini_str; + } else { + ret_str = NULL; + } + + paths_ok = path_system_init(paths); + + if (paths_ok && verbosity) { + int g; + assert(Gtbpath != NULL); + sjoin(ini_str, "\nGTB PATHS\n", INISIZE); + for (g = 0; Gtbpath[g] != NULL; g++) { + const char *p = Gtbpath[g]; + if (0 == g) { + sprintf(localstr, " main: %s\n", p); + } else { + sprintf(localstr, " #%d: %s\n", g, p); + } + sjoin(ini_str, localstr, INISIZE); + } + } + + if (!paths_ok && verbosity) { + sjoin(ini_str, "\nGTB PATHS not initialized\n", INISIZE); + } + + if (!reach_was_initialized()) + reach_init(); + + attack_maps_init(); /* external initialization */ + + init_indexing(0 /* no verbosity */); + +#ifdef GTB_SHARE + init_bettarr(); +#endif + + if (!fd_init(&fd) && verbosity) { + sjoin(ini_str, " File Open Memory initialization = **FAILED**\n", INISIZE); + return ret_str; + } + + GTB_scheme = decoding_sch; + Uncompressed = GTB_scheme == 0; + + if (GTB_scheme == 0) { + Uncompressed = TRUE; + } + + set_decoding_scheme(GTB_scheme); + + if (verbosity) { + sjoin(ini_str, "\nGTB initialization\n", INISIZE); + sprintf(localstr, " Compression Scheme = %d\n", GTB_scheme); + sjoin(ini_str, localstr, INISIZE); + } + + zi = zipinfo_init(); + + TB_AVAILABILITY = zi; + + if (verbosity) { + if (0 == zi) { + sjoin(ini_str, " Compression Indexes = **FAILED**\n", INISIZE); + } else { + int n, bit; + + n = 3; + bit = 1; + if (zi & (1u << bit)) + sprintf(localstr, " Compression Indexes (%d-pc) = PASSED\n", n); + else + sprintf(localstr, " Compression Indexes (%d-pc) = **FAILED**\n", n); + sjoin(ini_str, localstr, INISIZE); + + n = 4; + bit = 3; + if (zi & (1u << bit)) + sprintf(localstr, " Compression Indexes (%d-pc) = PASSED\n", n); + else + sprintf(localstr, " Compression Indexes (%d-pc) = **FAILED**\n", n); + sjoin(ini_str, localstr, INISIZE); + + n = 5; + bit = 5; + if (zi & (1u << bit)) + sprintf(localstr, " Compression Indexes (%d-pc) = PASSED\n", n); + else + sprintf(localstr, " Compression Indexes (%d-pc) = **FAILED**\n", n); + sjoin(ini_str, localstr, INISIZE); + } + sjoin(ini_str, "\n", INISIZE); + } + + eg_was_open_reset(); + Bytes_read = 0; + + mythread_mutex_init(&Egtb_lock); + + TB_INITIALIZED = TRUE; + + return ret_str; +} + +extern unsigned int +tb_availability(void) { + return TB_AVAILABILITY; +} + +extern bool_t +tb_is_initialized(void) { + return TB_INITIALIZED; +} + +extern void +tb_done(void) { + assert(TB_INITIALIZED); + fd_done(&fd); + RAM_egtbfree(); + zipinfo_done(); + path_system_done(); + mythread_mutex_destroy(&Egtb_lock); + TB_INITIALIZED = FALSE; + + /* + HERE, I should be free() the ini_str, but in + the current implementation, it is static + rather than dynamic. + */ + return; +} + +char * +tb_restart(int verbosity, int decoding_sch, const char **paths) { + if (tb_is_initialized()) { + tb_done(); + } + return tb_init(verbosity, decoding_sch, paths); +} + +/* whenever the program exits should release this memory */ +static void +RAM_egtbfree(void) { + int i; + for (i = 0; egkey[i].str != NULL; i++) { + egtb_freemem(i); + } +} + +/*--------------------------------------------------------------------------*/ + +#ifdef GTB_SHARE + static void +init_bettarr (void) +{ +/* + iDRAW = 0, iWMATE = 1, iBMATE = 2, iFORBID = 3, + iDRAWt = 4, iWMATEt = 5, iBMATEt = 6, iUNKNOWN = 7 + */ + + int temp[] = { + /*White*/ + /*iDRAW vs*/ + 1, 2, 1, 1, 2, 2, 2, 2, + /*iWMATE vs*/ + 1, 3, 1, 1, 1, 1, 1, 1, + /*iBMATE vs*/ + 2, 2, 4, 1, 2, 2, 2, 2, + /*iFORBID vs*/ + 2, 2, 2, 2, 2, 2, 2, 2, + + /*iDRAWt vs*/ + 1, 2, 1, 1, 2, 2, 1, 2, + /*iWMATEt vs*/ + 1, 2, 1, 1, 1, 3, 1, 1, + /*iBMATEt vs*/ + 1, 2, 1, 1, 2, 2, 4, 2, + /*iUNKNOWN */ + 1, 2, 1, 1, 1, 2, 1, 2, + + /*Black*/ + /*iDRAW vs*/ + 1, 1, 2, 1, 2, 2, 2, 2, + /*iWMATE vs*/ + 2, 4, 2, 1, 2, 2, 2, 2, + /*iBMATE vs*/ + 1, 1, 3, 1, 1, 1, 1, 1, + /*iFORBID vs*/ + 2, 2, 2, 2, 2, 2, 2, 2, + + /*iDRAWt vs*/ + 1, 1, 2, 1, 2, 1, 2, 2, + /*iWMATEt vs*/ + 1, 1, 2, 1, 2, 4, 2, 2, + /*iBMATEt vs*/ + 1, 1, 2, 1, 1, 1, 3, 1, + /*iUNKNOWN */ + 1, 1, 2, 1, 1, 1, 2, 2 + }; + + int i, j, k, z; + + /* reset */ + z = 0; + for (i = 0; i < 2; i++) + for (j = 0; j < 8; j++) + for (k = 0; k < 8; k++) + bettarr [i][j][k] = temp[z++]; + + return; +} +#endif + +/* +| +| Own File Descriptors +| +\*---------------------------------------------------------------------------*/ + +static bool_t +fd_init(struct filesopen *pfd) { + tbkey_t *p; + int i, allowed; + + pfd->n = 0; + + allowed = mysys_fopen_max() - 5 /*stdin,stdout,sterr,stdlog,book*/; + if (allowed < 4) + GTB_MAXOPEN = 4; + if (allowed > 32) + GTB_MAXOPEN = 32; + + p = (tbkey_t *) malloc(sizeof(tbkey_t) * (size_t) GTB_MAXOPEN); + + if (p != NULL) { + for (i = 0; i < GTB_MAXOPEN; i++) { + p[i] = -1; + } + pfd->key = p; + return TRUE; + } else { + return FALSE; + } +} + +static void +fd_done(struct filesopen *pfd) { + int i; + tbkey_t closingkey; + FILE *finp; + + assert(pfd != NULL); + + for (i = 0; i < pfd->n; i++) { + closingkey = pfd->key[i]; + finp = egkey[closingkey].fd; + fclose(finp); + egkey[closingkey].fd = NULL; + pfd->key[i] = -1; + } + pfd->n = 0; + free(pfd->key); +} + +/****************************************************************************\ +| +| +| PROBE ZONE +| +| +\****************************************************************************/ + +#if !defined(SHARED_forbuilding) + +/* shared with building routines */ +mySHARED void list_sq_copy(const SQUARE *a, SQUARE *b); + +mySHARED void list_pc_copy(const SQ_CONTENT *a, SQ_CONTENT *b); + +mySHARED dtm_t inv_dtm(dtm_t x); + +mySHARED bool_t egtb_get_id(SQ_CONTENT *w, SQ_CONTENT *b, tbkey_t *id); + +mySHARED void list_sq_flipNS(SQUARE *s); + +mySHARED dtm_t adjust_up(dtm_t dist); + +mySHARED dtm_t bestx(unsigned stm, dtm_t a, dtm_t b); + +mySHARED void sortlists(SQUARE *ws, SQ_CONTENT *wp); + +mySHARED /*@NULL@*/ FILE *fd_openit(tbkey_t key); + +mySHARED dtm_t dtm_unpack(unsigned stm, unsigned char packed); + +mySHARED void unpackdist(dtm_t d, unsigned int *res, unsigned int *ply); + +mySHARED dtm_t packdist(unsigned int inf, unsigned int ply); + +mySHARED bool_t fread_entry_packed(FILE *dest, unsigned side, dtm_t *px); + +mySHARED bool_t fpark_entry_packed(FILE *finp, unsigned side, index_t max, index_t idx); + +#endif + +/* use only with probe */ +static bool_t egtb_get_dtm(tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard, dtm_t *dtm); + +static void removepiece(SQUARE *ys, SQ_CONTENT *yp, int j); + +static bool_t egtb_filepeek(tbkey_t key, unsigned side, index_t idx, dtm_t *out_dtm); + + +/*prototype*/ +#ifdef WDL_PROBE + +static bool_t +tb_probe_wdl + (unsigned stm, + const SQUARE *inp_wSQ, + const SQUARE *inp_bSQ, + const SQ_CONTENT *inp_wPC, + const SQ_CONTENT *inp_bPC, + bool_t probingtype, + /*@out@*/ unsigned *res); + +#endif + +static bool_t +tb_probe_(unsigned stm, + SQUARE epsq, + const SQUARE *inp_wSQ, + const SQUARE *inp_bSQ, + const SQ_CONTENT *inp_wPC, + const SQ_CONTENT *inp_bPC, + bool_t probingtype, + /*@out@*/ unsigned *res, + /*@out@*/ unsigned *ply); + + +extern bool_t +tb_probe_soft + (unsigned stm, + SQUARE epsq, + unsigned castles, + const SQUARE *inp_wSQ, + const SQUARE *inp_bSQ, + const SQ_CONTENT *inp_wPC, + const SQ_CONTENT *inp_bPC, + /*@out@*/ unsigned *res, + /*@out@*/ unsigned *ply) { + if (castles != 0) + return FALSE; + return tb_probe_(stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply); +} + +extern bool_t +tb_probe_hard + (unsigned stm, + SQUARE epsq, + unsigned castles, + const SQUARE *inp_wSQ, + const SQUARE *inp_bSQ, + const SQ_CONTENT *inp_wPC, + const SQ_CONTENT *inp_bPC, + /*@out@*/ unsigned *res, + /*@out@*/ unsigned *ply) { + if (castles != 0) + return FALSE; + return tb_probe_(stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply); +} + +extern bool_t +tb_probe_WDL_soft + (unsigned stm, + SQUARE epsq, + unsigned castles, + const SQUARE *inp_wSQ, + const SQUARE *inp_bSQ, + const SQ_CONTENT *inp_wPC, + const SQ_CONTENT *inp_bPC, + /*@out@*/ unsigned *res) { + unsigned ply_n; + unsigned *ply = &ply_n; + if (castles != 0) + return FALSE; + if (epsq != NOSQUARE) + return tb_probe_(stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply); + + /* probe bitbase like, assuming no en passant */ +#ifdef WDL_PROBE + return tb_probe_wdl(stm, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res); +#else + return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply); +#endif +} + +extern bool_t +tb_probe_WDL_hard + (unsigned stm, + SQUARE epsq, + unsigned castles, + const SQUARE *inp_wSQ, + const SQUARE *inp_bSQ, + const SQ_CONTENT *inp_wPC, + const SQ_CONTENT *inp_bPC, + /*@out@*/ unsigned *res) { + unsigned ply_n; + unsigned *ply = &ply_n; + if (castles != 0) + return FALSE; + if (epsq != NOSQUARE) + return tb_probe_(stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply); + + /* probe bitbase like, assuming no en passant */ +#ifdef WDL_PROBE + return tb_probe_wdl(stm, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res); +#else + return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply); +#endif +} + + +static bool_t +tb_probe_(unsigned stm, + SQUARE epsq, + const SQUARE *inp_wSQ, + const SQUARE *inp_bSQ, + const SQ_CONTENT *inp_wPC, + const SQ_CONTENT *inp_bPC, + bool_t probingtype, + /*@out@*/ unsigned *res, + /*@out@*/ unsigned *ply) { + int i = 0, j = 0; + tbkey_t id = -1; + dtm_t dtm = 0; + + SQUARE storage_ws[MAX_LISTSIZE], storage_bs[MAX_LISTSIZE]; + SQ_CONTENT storage_wp[MAX_LISTSIZE], storage_bp[MAX_LISTSIZE]; + + SQUARE *ws = storage_ws; + SQUARE *bs = storage_bs; + SQ_CONTENT *wp = storage_wp; + SQ_CONTENT *bp = storage_bp; + + SQUARE *xs; + SQUARE *ys; + SQ_CONTENT *xp; + SQ_CONTENT *yp; + + SQUARE tmp_ws[MAX_LISTSIZE], tmp_bs[MAX_LISTSIZE]; + SQ_CONTENT tmp_wp[MAX_LISTSIZE], tmp_bp[MAX_LISTSIZE]; + + SQUARE *temps; + bool_t straight = FALSE; + + SQUARE capturer_a, capturer_b, xed = NOSQUARE; + + unsigned int plies; + unsigned int inf; + + bool_t okdtm = TRUE; + bool_t okcall = TRUE; + + /************************************/ + + assert (stm == WH || stm == BL); + /*assert (inp_wPC[0] == KING && inp_bPC[0] == KING );*/ + assert ((epsq >> 3) == 2 || (epsq >> 3) == 5 || epsq == NOSQUARE); + + /* VALID ONLY FOR KK!! */ + if (inp_wPC[1] == NOPIECE && inp_bPC[1] == NOPIECE) { + index_t dummy_i; + bool_t b = kxk_pctoindex(inp_wSQ, inp_bSQ, &dummy_i); + *res = b ? iDRAW : iFORBID; + *ply = 0; + return TRUE; + } + + /* copy input */ + list_pc_copy(inp_wPC, wp); + list_pc_copy(inp_bPC, bp); + list_sq_copy(inp_wSQ, ws); + list_sq_copy(inp_bSQ, bs); + + sortlists(ws, wp); + sortlists(bs, bp); + + FOLLOW_label("EGTB_PROBE") + + if (egtb_get_id(wp, bp, &id)) { + FOLLOW_LU("got ID", id) + straight = TRUE; + } else if (egtb_get_id(bp, wp, &id)) { + FOLLOW_LU("rev ID", id) + straight = FALSE; + list_sq_flipNS(ws); + list_sq_flipNS(bs); + temps = ws; + ws = bs; + bs = temps; + stm = Opp(stm); + if (epsq != NOSQUARE) epsq ^= 070; /* added */ + { + SQ_CONTENT *tempp = wp; + wp = bp; + bp = tempp; + } /* added */ + } else { +#if defined(DEBUG) + printf("did not get id...\n"); + output_state (stm, ws, bs, wp, bp); +#endif + unpackdist(iFORBID, res, ply); + return FALSE; + } + + /* store position... */ + list_pc_copy(wp, tmp_wp); + list_pc_copy(bp, tmp_bp); + list_sq_copy(ws, tmp_ws); + list_sq_copy(bs, tmp_bs); + + /* x will be stm and y will be stw */ + if (stm == WH) { + xs = ws; + xp = wp; + ys = bs; + yp = bp; + } else { + xs = bs; + xp = bp; + ys = ws; + yp = wp; + } + + okdtm = egtb_get_dtm(id, stm, ws, bs, probingtype, &dtm); + + FOLLOW_LU("dtmok?", okdtm) + FOLLOW_DTM("dtm", dtm) + + if (okdtm) { + + capturer_a = NOSQUARE; + capturer_b = NOSQUARE; + + if (epsq != NOSQUARE) { + /* captured pawn, trick: from epsquare to captured */ + xed = epsq ^ (1 << 3); + + /* find index captured (j) */ + for (j = 0; ys[j] != NOSQUARE; j++) { + if (ys[j] == xed) break; + } + + /* try first possible ep capture */ + if (0 == (0x88 & (map88(xed) + 1))) + capturer_a = xed + 1; + /* try second possible ep capture */ + if (0 == (0x88 & (map88(xed) - 1))) + capturer_b = xed - 1; + + if (ys[j] == xed) { + + /* find capturers (i) */ + for (i = 0; xs[i] != NOSQUARE && okcall; i++) { + + if (xp[i] == PAWN && (xs[i] == capturer_a || xs[i] == capturer_b)) { + dtm_t epscore = iFORBID; + + /* execute capture */ + xs[i] = epsq; + removepiece(ys, yp, j); + + okcall = tb_probe_(Opp(stm), NOSQUARE, ws, bs, wp, bp, probingtype, &inf, &plies); + + if (okcall) { + epscore = packdist(inf, plies); + epscore = adjust_up(epscore); + + /* chooses to ep or not */ + dtm = bestx(stm, epscore, dtm); + } + + /* restore position */ + list_pc_copy(tmp_wp, wp); + list_pc_copy(tmp_bp, bp); + + list_sq_copy(tmp_ws, ws); + list_sq_copy(tmp_bs, bs); + } + } + } + } /* ep */ + + if (straight) { + unpackdist(dtm, res, ply); + } else { + unpackdist(inv_dtm(dtm), res, ply); + } + } + + if (!okdtm || !okcall) { + unpackdist(iFORBID, res, ply); + } + + return okdtm && okcall; +} + +#ifdef _MSC_VER + /* to silence warning for sprintf usage */ +#pragma warning(disable:4996) +#endif + +static bool_t +egtb_filepeek(tbkey_t key, unsigned side, index_t idx, dtm_t *out_dtm) { + FILE *finp; + +#define USE_FD + +#if !defined(USE_FD) + char buf[1024]; + char *filename = buf; +#endif + + bool_t ok; + dtm_t x = 0; + index_t maxindex = egkey[key].maxindex; + + + assert (Uncompressed); + assert (side == WH || side == BL); + assert (out_dtm != NULL); + assert (idx >= 0); + assert (key < MAX_EGKEYS); + + +#if defined(USE_FD) + if (NULL == (finp = egkey[key].fd)) { + if (NULL == (finp = fd_openit(key))) { + return FALSE; + } + } +#else + sprintf (buf, "%s.gtb", egkey[key].str); + if (NULL == (finp = fopen (filename, "rb"))) { + return FALSE; + } +#endif + + ok = fpark_entry_packed(finp, side, maxindex, idx); + ok = ok && fread_entry_packed(finp, side, &x); + + if (ok) { + *out_dtm = x; + } else + *out_dtm = iFORBID; + +#if !defined(USE_FD) + fclose (finp); +#endif + + return ok; +} + +/* will get defined later */ +static bool_t dtm_cache_is_on(void); + +static bool_t +egtb_get_dtm(tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, dtm_t *dtm) { + bool_t idxavail; + index_t idx; + dtm_t *tab[2]; + bool_t (*pc2idx)(const SQUARE *, const SQUARE *, index_t *); + + FOLLOW_label("egtb_get_dtm --> starts") + + if (egkey[k].status == STATUS_MALLOC || egkey[k].status == STATUS_STATICRAM) { + + tab[WH] = egkey[k].egt_w; + tab[BL] = egkey[k].egt_b; + pc2idx = egkey[k].pctoi; + + idxavail = pc2idx(wS, bS, &idx); + + FOLLOW_LU("indexavail (RAM)", idxavail) + + if (idxavail) { + *dtm = tab[stm][idx]; + } else { + *dtm = iFORBID; + } + + return TRUE; + + } else if (egkey[k].status == STATUS_ABSENT) { + + pc2idx = egkey[k].pctoi; + idxavail = pc2idx(wS, bS, &idx); + + FOLLOW_LU("indexavail (HD)", idxavail) + + if (idxavail) { + bool_t success; + + /* + | LOCK + *-------------------------------*/ + mythread_mutex_lock(&Egtb_lock); + + if (dtm_cache_is_on()) { + + success = get_dtm(k, stm, idx, dtm, probe_hard_flag); + + FOLLOW_LU("get_dtm (succ)", success) + FOLLOW_LU("get_dtm (dtm )", *dtm) + +#if defined(DEBUG) + if (Uncompressed) { + dtm_t dtm_temp; + bool_t ok; + bool_t success2; + + assert (decoding_scheme() == 0 && GTB_scheme == 0); + + success2 = egtb_filepeek (k, stm, idx, &dtm_temp); + ok = (success == success2) && (!success || *dtm == dtm_temp); + if (!ok) { + printf ("\nERROR\nsuccess1=%d sucess2=%d\n" + "k=%d stm=%u idx=%d dtm_peek=%d dtm_cache=%d\n", + success, success2, k, stm, idx, dtm_temp, *dtm); + fatal_error(); + } + } +#endif + + } else { + assert(Uncompressed); + if (probe_hard_flag && Uncompressed) + success = egtb_filepeek(k, stm, idx, dtm); + else + success = FALSE; + } + + mythread_mutex_unlock(&Egtb_lock); + /*------------------------------*\ + | UNLOCK + */ + + + if (success) { + return TRUE; + } else { + if (probe_hard_flag) /* after probing hard and failing, no chance to succeed later */ + egkey[k].status = STATUS_REJECT; + *dtm = iUNKNOWN; + return FALSE; + } + + } else { + *dtm = iFORBID; + return TRUE; + } + + } else if (egkey[k].status == STATUS_REJECT) { + + FOLLOW_label("STATUS_REJECT") + + *dtm = iFORBID; + return FALSE; + } else { + + FOLLOW_label("STATUS_WRONG!") + + assert(0); + *dtm = iFORBID; + return FALSE; + } + +} + +static void +removepiece(SQUARE *ys, SQ_CONTENT *yp, int j) { + int k; + for (k = j; ys[k] != NOSQUARE; k++) { + ys[k] = ys[k + 1]; + yp[k] = yp[k + 1]; + } +} + +/* +| +| mySHARED by probe and build +| +\*----------------------------------------------------*/ + +mySHARED /*@NULL@*/ FILE * +fd_openit(tbkey_t key) { + int i; + tbkey_t closingkey; + FILE *finp = NULL; + char buf[4096]; + char *filename = buf; + int start; + int end; + int pth; + const char *extension; + + assert (0 <= key && key < MAX_EGKEYS); + assert (0 <= fd.n && fd.n <= GTB_MAXOPEN); + + /* test if I reach limit of files open */ + if (fd.n == GTB_MAXOPEN) { + + /* fclose the last accessed, first in the list */ + closingkey = fd.key[0]; + finp = egkey[closingkey].fd; + assert (finp != NULL); + fclose(finp); + egkey[closingkey].fd = NULL; + finp = NULL; + + for (i = 1; i < fd.n; i++) { + fd.key[i - 1] = fd.key[i]; + } + fd.key[--fd.n] = -1; + } + + assert (fd.n < GTB_MAXOPEN); + + /* set proper extensions to the File */ + if (Uncompressed) { + assert (decoding_scheme() == 0 && GTB_scheme == 0); + extension = ".gtb"; + } else { + extension = Extension[decoding_scheme()]; + } + + /* Scan folders to find the File*/ + finp = NULL; + + start = egkey[key].pathn; + end = Gtbpath_end_index; + +/*@@ +printf ("start: %d\n",start); +printf ("===================Gtbpath[0]=%s\n",Gtbpath[0]); +*/ + for (pth = start; NULL == finp && pth < end && Gtbpath[pth] != NULL; pth++) { + const char *path = Gtbpath[pth]; + size_t pl = strlen(path); +/*@@ +printf ("path: %s\n",path); +*/ + if (pl == 0) { + sprintf(buf, "%s%s%s", path, egkey[key].str, extension); + } else { + if (isfoldersep(path[pl - 1])) { + sprintf(buf, "%s%s%s", path, egkey[key].str, extension); + } else { + sprintf(buf, "%s%s%s%s", path, FOLDERSEP, egkey[key].str, extension); + } + } +/*printf ("try to open %s --> ",filename);*/ + /* Finally found the file? */ + finp = fopen(filename, "rb"); +/*printf ("%d\n",finp != NULL);*/ + } + + /* File was found and opened */ + if (NULL != finp) { + fd.key[fd.n++] = key; + egkey[key].fd = finp; + egkey[key].pathn = pth; /* remember succesful path */ + eg_was_open[key] = 1; + return finp; + } + + start = 0; + end = egkey[key].pathn; + for (pth = start; NULL == finp && pth < end && Gtbpath[pth] != NULL; pth++) { + const char *path = Gtbpath[pth]; + size_t pl = strlen(path); + + if (pl == 0) { + sprintf(buf, "%s%s%s", path, egkey[key].str, extension); + } else { + if (isfoldersep(path[pl - 1])) { + sprintf(buf, "%s%s%s", path, egkey[key].str, extension); + } else { + sprintf(buf, "%s%s%s%s", path, FOLDERSEP, egkey[key].str, extension); + } + } +/*printf ("try to open %s --> ",filename);*/ + /* Finally found the file? */ + finp = fopen(filename, "rb"); +/*printf ("%d\n",finp != NULL);*/ + } + + + /* File was found and opened */ + if (NULL != finp) { + fd.key[fd.n++] = key; + egkey[key].fd = finp; + egkey[key].pathn = pth; /* remember succesful path */ + eg_was_open[key] = 1; + } + + return finp; +} + +#ifdef _MSC_VER + /* to silence warning for sprintf usage */ +#pragma warning(default:4996) +#endif + +mySHARED void +sortlists(SQUARE *ws, SQ_CONTENT *wp) { + int i, j; + SQUARE ts; + SQ_CONTENT tp; + /* input is sorted */ + for (i = 0; wp[i] != NOPIECE; i++) { + for (j = (i + 1); wp[j] != NOPIECE; j++) { + if (wp[j] > wp[i]) { + tp = wp[i]; + wp[i] = wp[j]; + wp[j] = tp; + ts = ws[i]; + ws[i] = ws[j]; + ws[j] = ts; + } + } + } +} + +mySHARED void +list_sq_copy(const SQUARE *a, SQUARE *b) { + while (NOSQUARE != (*b++ = *a++)); +} + +mySHARED void +list_pc_copy(const SQ_CONTENT *a, SQ_CONTENT *b) { + while (NOPIECE != (*b++ = *a++)); +} + +mySHARED dtm_t +inv_dtm(dtm_t x) { + unsigned mat; + assert ((x & iUNKNBIT) == 0); + + if (x == iDRAW || x == iFORBID) + return x; + + mat = (unsigned) x & 3u; + if (mat == iWMATE) + mat = iBMATE; + else + mat = iWMATE; + + x = (dtm_t) (((unsigned) x & ~3u) | mat); + + return x; +} + +static const char pctoch[] = {'-', 'p', 'n', 'b', 'r', 'q', 'k'}; + +mySHARED bool_t +egtb_get_id(SQ_CONTENT *w, SQ_CONTENT *b, tbkey_t *id) { + + char pcstr[2 * MAX_LISTSIZE]; + SQ_CONTENT *s; + char *t; + bool_t found; + tbkey_t i; + static tbkey_t cache_i = 0; + size_t h1, h2; + + assert (PAWN == 1 && KNIGHT == 2 && BISHOP == 3 && ROOK == 4 && QUEEN == 5 && KING == 6); + + t = pcstr; + + s = w; + while (NOPIECE != *s) + *t++ = pctoch[*s++]; + s = b; + while (NOPIECE != *s) + *t++ = pctoch[*s++]; + + *t = '\0'; + + found = (0 == strcmp(pcstr, egkey[cache_i].str)); + if (found) { + *id = cache_i; + return found; + } + + h1 = str_hash_func_1(pcstr) & (EGKEY_HASH_SIZE - 1); + h2 = str_hash_func_2(pcstr); + while (1) { + i = egkey_hash[h1]; + if (i < 0) + break; + found = (0 == strcmp(pcstr, egkey[i].str)); + if (found) + break; + h1 = (h1 + h2) & (EGKEY_HASH_SIZE - 1); + } + if (found) { + cache_i = *id = i; + } + + return found; +} + +mySHARED void +list_sq_flipNS(SQUARE *s) { + while (*s != NOSQUARE) { + *s ^= 070; + s++; + } +} + +mySHARED void +unpackdist(dtm_t d, unsigned int *res, unsigned int *ply) { + *ply = (unsigned int) d >> PLYSHIFT; + *res = d & INFOMASK; +} + +mySHARED dtm_t +packdist(unsigned int inf, unsigned int ply) { + assert (inf <= INFOMASK); + return (dtm_t) (inf | ply << PLYSHIFT); +} + +mySHARED dtm_t +adjust_up(dtm_t dist) { +#if 0 + static const dtm_t adding[] = { + 0, 1<> 2; + + if (WH == stm) { + switch (info) { + case iWMATE: + moves = store + 1; + plies = moves * 2 - 1; + prefx = info; + break; + + case iBMATE: + moves = store; + plies = moves * 2; + prefx = info; + break; + + case iDRAW: + moves = store + 1 + 63; + plies = moves * 2 - 1; + prefx = iWMATE; + break; + + case iFORBID: + + moves = store + 63; + plies = moves * 2; + prefx = iBMATE; + break; + default: + plies = 0; + prefx = 0; + assert(0); + break; + + } + ret = (dtm_t) (prefx | (plies << 3)); + } else { + switch (info) { + case iBMATE: + moves = store + 1; + plies = moves * 2 - 1; + prefx = info; + break; + + case iWMATE: + moves = store; + plies = moves * 2; + prefx = info; + break; + + case iDRAW: + + if (store == 63) { + /* exception: no position in the 5-man + TBs needs to store 63 for iBMATE + it is then used to indicate iWMATE + when just overflows */ + store++; + + moves = store + 63; + plies = moves * 2; + prefx = iWMATE; + + break; + } + + moves = store + 1 + 63; + plies = moves * 2 - 1; + prefx = iBMATE; + break; + + case iFORBID: + + moves = store + 63; + plies = moves * 2; + prefx = iWMATE; + break; + default: + plies = 0; + prefx = 0; + assert(0); + break; + + } + ret = (dtm_t) (prefx | (plies << 3)); + } + return ret; +} + + +/* +static bool_t fwrite_entry_packed (FILE *dest, unsigned side, dtm_t x); +*/ + + +mySHARED bool_t +fread_entry_packed(FILE *finp, unsigned side, dtm_t *px) { + unsigned char p[SLOTSIZE]; + bool_t ok = (SLOTSIZE == fread(p, sizeof(unsigned char), SLOTSIZE, finp)); + if (ok) { + *px = dtm_unpack(side, p[0]); + } + return ok; +} + + +mySHARED bool_t +fpark_entry_packed(FILE *finp, unsigned side, index_t max, index_t idx) { + bool_t ok; + index_t i; + long int fseek_i; + index_t sz = (index_t) sizeof(unsigned char); + + assert (side == WH || side == BL); + assert (finp != NULL); + assert (idx >= 0); + i = ((index_t) side * max + idx) * sz; + fseek_i = (long int) i; + assert (fseek_i >= 0); + ok = (0 == fseek(finp, fseek_i, SEEK_SET)); + return ok; +} + +/*----------------------------------------------------*\ +| +| shared by probe and build +| +\*/ + +static size_t +hash_func_1(tbkey_t key, unsigned side, index_t offset) { + size_t h = offset | (key << 1) | side; + h = ((h >> 16) ^ h) * 0x45d9f3b; + h = ((h >> 16) ^ h) * 0x45d9f3b; + h = ((h >> 16) ^ h); + return h; +} + +static size_t +hash_func_2(tbkey_t key, unsigned side, index_t offset) { + size_t h = offset | (key << 1) | side; + h = ((h >> 16) ^ h) * 0x3335b369; + h = ((h >> 16) ^ h) * 0x3335b369; + h = ((h >> 16) ^ h); + return h * 2 + 1; +} + +/*---------------------------------------------------------------------*\ +| WDL CACHE Implementation ZONE +\*---------------------------------------------------------------------*/ + +#define WDL_entries_per_unit 4 +#define WDL_entry_mask 3 +static size_t WDL_units_per_block = 0; + +static bool_t WDL_CACHE_INITIALIZED = FALSE; + +typedef unsigned char unit_t; /* block unit */ + +typedef struct wdl_block wdl_block_t; + +struct wdl_block { + tbkey_t key; + unsigned side; + index_t offset; + unit_t *p_arr; + wdl_block_t *prev; + wdl_block_t *next; +}; + +struct WDL_CACHE { + /* defined at init */ + bool_t cached; + size_t max_blocks; + size_t entries_per_block; + unit_t *buffer; + + /* flushables */ + wdl_block_t *top; + wdl_block_t *bot; + size_t n; + wdl_block_t *blocks; /* was entry */ + + /* fast lookup in LRU list */ + wdl_block_t **hash_table; + size_t ht_size; + size_t ht_used; + + /* counters */ + uint64_t hard; + uint64_t soft; + uint64_t hardmisses; + uint64_t hits; + uint64_t softmisses; + uint64_t comparisons; +}; + +struct WDL_CACHE wdl_cache = {FALSE, 0, 0, NULL, + NULL, NULL, 0, NULL, + 0, 0, 0, 0, 0, 0}; + + +/*---------------------------------------------------------------------*\ +| DTM CACHE Implementation ZONE +\*---------------------------------------------------------------------*/ + +struct dtm_block; + +typedef struct dtm_block dtm_block_t; + +struct dtm_block { + tbkey_t key; + unsigned side; + index_t offset; + dtm_t *p_arr; + dtm_block_t *prev; + dtm_block_t *next; +}; + +struct cache_table { + /* defined at init */ + bool_t cached; + size_t max_blocks; + size_t entries_per_block; + dtm_t *buffer; + + /* flushables */ + dtm_block_t *top; + dtm_block_t *bot; + size_t n; + dtm_block_t *entry; + + /* fast lookup in LRU list */ + dtm_block_t **hash_table; + size_t ht_size; + size_t ht_used; + + /* counters */ + uint64_t hard; + uint64_t soft; + uint64_t hardmisses; + uint64_t hits; + uint64_t softmisses; + unsigned long comparisons; +}; + +struct cache_table dtm_cache = {FALSE, 0, 0, NULL, + NULL, NULL, 0, NULL, + 0, 0, 0, 0, 0, 0}; + +struct general_counters { + /* counters */ + uint64_t hits; + uint64_t miss; +}; + +static struct general_counters Drive = {0, 0}; + + +static void split_index(size_t entries_per_block, index_t i, index_t *o, index_t *r); + +static dtm_block_t *point_block_to_replace(void); + +static bool_t preload_cache(tbkey_t key, unsigned side, index_t idx); + +static void movetotop(dtm_block_t *t); + +/*--cache prototypes--------------------------------------------------------*/ + +/*- WDL --------------------------------------------------------------------*/ +#ifdef WDL_PROBE + +static unsigned int wdl_extract(unit_t *uarr, index_t x); + +static wdl_block_t *wdl_point_block_to_replace(void); + +static void wdl_movetotop(wdl_block_t *t); + +#if 0 + static bool_t wdl_cache_init (size_t cache_mem); +static void wdl_cache_flush (void); +static bool_t get_WDL (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag); +#endif + +static bool_t wdl_cache_is_on(void); + +static void wdl_cache_reset_counters(void); + +static void wdl_cache_done(void); + +static wdl_block_t *wdl_point_block_to_replace(void); + +static bool_t get_WDL_from_cache(tbkey_t key, unsigned side, index_t idx, unsigned int *out); + +static void wdl_movetotop(wdl_block_t *t); + +static bool_t wdl_preload_cache(tbkey_t key, unsigned side, index_t idx); + +#endif +/*--------------------------------------------------------------------------*/ +/*- DTM --------------------------------------------------------------------*/ +static bool_t dtm_cache_is_on(void); + +static void dtm_cache_reset_counters(void); + +static void dtm_cache_done(void); + +static size_t dtm_cache_init(size_t cache_mem); + +static void dtm_cache_flush(void); + +/*--------------------------------------------------------------------------*/ + +static bool_t +dtm_cache_is_on(void) { + return dtm_cache.cached; +} + +static void +dtm_cache_reset_counters(void) { + dtm_cache.hard = 0; + dtm_cache.soft = 0; + dtm_cache.hardmisses = 0; + dtm_cache.hits = 0; + dtm_cache.softmisses = 0; + dtm_cache.comparisons = 0; + return; +} + + +static size_t +dtm_cache_init(size_t cache_mem) { + unsigned int i; + dtm_block_t *p; + size_t entries_per_block; + size_t max_blocks; + size_t block_mem; + + if (DTM_CACHE_INITIALIZED) + dtm_cache_done(); + + entries_per_block = 16 * 1024; /* fixed, needed for the compression schemes */ + + block_mem = entries_per_block * sizeof(dtm_t); + + max_blocks = cache_mem / block_mem; + if (!Uncompressed && 1 > max_blocks) + max_blocks = 1; + cache_mem = max_blocks * block_mem; + + + dtm_cache_reset_counters(); + + dtm_cache.entries_per_block = entries_per_block; + dtm_cache.max_blocks = max_blocks; + dtm_cache.cached = TRUE; + dtm_cache.top = NULL; + dtm_cache.bot = NULL; + dtm_cache.n = 0; + + if (0 == cache_mem || NULL == (dtm_cache.buffer = (dtm_t *) malloc(cache_mem))) { + dtm_cache.cached = FALSE; + dtm_cache.buffer = NULL; + dtm_cache.entry = NULL; + return 0; + } + + if (0 == max_blocks || NULL == (dtm_cache.entry = (dtm_block_t *) malloc(max_blocks * sizeof(dtm_block_t)))) { + dtm_cache.cached = FALSE; + dtm_cache.entry = NULL; + free(dtm_cache.buffer); + dtm_cache.buffer = NULL; + return 0; + } + + for (i = 0; i < max_blocks; i++) { + p = &dtm_cache.entry[i]; + p->key = -1; + p->side = gtbNOSIDE; + p->offset = gtbNOINDEX; + p->p_arr = dtm_cache.buffer + i * entries_per_block; + p->prev = NULL; + p->next = NULL; + } + + dtm_cache.ht_size = 1; + while (dtm_cache.ht_size < max_blocks * 4) + dtm_cache.ht_size *= 2; + dtm_cache.ht_used = 0; + dtm_cache.hash_table = (dtm_block_t **) malloc(dtm_cache.ht_size * sizeof(dtm_block_t *));; + if (dtm_cache.hash_table == NULL) { + dtm_cache.cached = FALSE; + free(dtm_cache.entry); + dtm_cache.entry = NULL; + free(dtm_cache.buffer); + dtm_cache.buffer = NULL; + return 0; + } + + for (i = 0; i < dtm_cache.ht_size; i++) { + dtm_cache.hash_table[i] = NULL; + } + + DTM_CACHE_INITIALIZED = TRUE; + + return cache_mem; +} + + +static void +dtm_cache_done(void) { + assert(DTM_CACHE_INITIALIZED); + + dtm_cache.cached = FALSE; + dtm_cache.hard = 0; + dtm_cache.soft = 0; + dtm_cache.hardmisses = 0; + dtm_cache.hits = 0; + dtm_cache.softmisses = 0; + dtm_cache.comparisons = 0; + dtm_cache.max_blocks = 0; + dtm_cache.entries_per_block = 0; + + dtm_cache.top = NULL; + dtm_cache.bot = NULL; + dtm_cache.n = 0; + + if (dtm_cache.buffer != NULL) + free(dtm_cache.buffer); + dtm_cache.buffer = NULL; + + if (dtm_cache.entry != NULL) + free(dtm_cache.entry); + dtm_cache.entry = NULL; + + if (dtm_cache.hash_table != NULL) + free(dtm_cache.hash_table); + dtm_cache.hash_table = NULL; + + DTM_CACHE_INITIALIZED = FALSE; + + return; +} + +static void +dtm_cache_flush(void) { + unsigned int i; + dtm_block_t *p; + size_t entries_per_block = dtm_cache.entries_per_block; + size_t max_blocks = dtm_cache.max_blocks; + + dtm_cache.top = NULL; + dtm_cache.bot = NULL; + dtm_cache.n = 0; + + for (i = 0; i < max_blocks; i++) { + p = &dtm_cache.entry[i]; + p->key = -1; + p->side = gtbNOSIDE; + p->offset = gtbNOINDEX; + p->p_arr = dtm_cache.buffer + i * entries_per_block; + p->prev = NULL; + p->next = NULL; + } + dtm_cache_reset_counters(); + return; +} + + +/*---- end tbcache zone ----------------------------------------------------------------------*/ + +extern bool_t +tbcache_is_on(void) { + return dtm_cache_is_on() || wdl_cache_is_on(); +} + + +/* STATISTICS OUTPUT */ + +extern void +tbstats_get(struct TB_STATS *x) { + long unsigned mask = 0xfffffffflu; + uint64_t memory_hits, total_hits; + + + /* + | WDL CACHE + \*---------------------------------------------------*/ + + x->wdl_easy_hits[0] = (long unsigned) (wdl_cache.hits & mask); + x->wdl_easy_hits[1] = (long unsigned) (wdl_cache.hits >> 32); + + x->wdl_hard_prob[0] = (long unsigned) (wdl_cache.hard & mask); + x->wdl_hard_prob[1] = (long unsigned) (wdl_cache.hard >> 32); + + x->wdl_soft_prob[0] = (long unsigned) (wdl_cache.soft & mask); + x->wdl_soft_prob[1] = (long unsigned) (wdl_cache.soft >> 32); + + x->wdl_cachesize = WDL_cache_size; + + /* occupancy */ + x->wdl_occupancy = + wdl_cache.max_blocks == 0 ? 0 : (double) 100.0 * (double) wdl_cache.n / (double) wdl_cache.max_blocks; + + /* + | DTM CACHE + \*---------------------------------------------------*/ + + x->dtm_easy_hits[0] = (long unsigned) (dtm_cache.hits & mask); + x->dtm_easy_hits[1] = (long unsigned) (dtm_cache.hits >> 32); + + x->dtm_hard_prob[0] = (long unsigned) (dtm_cache.hard & mask); + x->dtm_hard_prob[1] = (long unsigned) (dtm_cache.hard >> 32); + + x->dtm_soft_prob[0] = (long unsigned) (dtm_cache.soft & mask); + x->dtm_soft_prob[1] = (long unsigned) (dtm_cache.soft >> 32); + + x->dtm_cachesize = DTM_cache_size; + + /* occupancy */ + x->dtm_occupancy = + dtm_cache.max_blocks == 0 ? 0 : (double) 100.0 * (double) dtm_cache.n / (double) dtm_cache.max_blocks; + + /* + | GENERAL + \*---------------------------------------------------*/ + + /* memory */ + memory_hits = wdl_cache.hits + dtm_cache.hits; + x->memory_hits[0] = (long unsigned) (memory_hits & mask); + x->memory_hits[1] = (long unsigned) (memory_hits >> 32); + + /* hard drive */ + x->drive_hits[0] = (long unsigned) (Drive.hits & mask); + x->drive_hits[1] = (long unsigned) (Drive.hits >> 32); + + x->drive_miss[0] = (long unsigned) (Drive.miss & mask); + x->drive_miss[1] = (long unsigned) (Drive.miss >> 32); + + x->bytes_read[0] = (long unsigned) (Bytes_read & mask); + x->bytes_read[1] = (long unsigned) (Bytes_read >> 32); + + x->files_opened = eg_was_open_count(); + + /* total */ + total_hits = memory_hits + Drive.hits; + x->total_hits[0] = (long unsigned) (total_hits & mask); + x->total_hits[1] = (long unsigned) (total_hits >> 32); + + /* efficiency */ + { + uint64_t denominator = memory_hits + Drive.hits + Drive.miss; + x->memory_efficiency = 0 == denominator ? 0 : 100.0 * (double) (memory_hits) / (double) (denominator); + } +} + + +extern bool_t +tbcache_init(size_t cache_mem, int wdl_fraction) { + assert (wdl_fraction <= WDL_FRACTION_MAX && wdl_fraction >= 0); + + /* defensive against input */ + if (wdl_fraction > WDL_FRACTION_MAX) wdl_fraction = WDL_FRACTION_MAX; + if (wdl_fraction < 0) wdl_fraction = 0; + WDL_FRACTION = wdl_fraction; + + DTM_cache_size = (cache_mem / (size_t) WDL_FRACTION_MAX) * (size_t) (WDL_FRACTION_MAX - WDL_FRACTION); + WDL_cache_size = (cache_mem / (size_t) WDL_FRACTION_MAX) * (size_t) WDL_FRACTION; + +#ifdef WDL_PROBE + /* returns the actual memory allocated */ + DTM_cache_size = dtm_cache_init(DTM_cache_size); + WDL_cache_size = wdl_cache_init(WDL_cache_size); +#else + /* returns the actual memory allocated */ + DTM_cache_size = dtm_cache_init (DTM_cache_size); +#endif + tbstats_reset(); + return TRUE; +} + +extern bool_t +tbcache_restart(size_t cache_mem, int wdl_fraction) { + return tbcache_init(cache_mem, wdl_fraction); +} + +extern void +tbcache_done(void) { + dtm_cache_done(); +#ifdef WDL_PROBE + wdl_cache_done(); +#endif + tbstats_reset(); + return; +} + +extern void +tbcache_flush(void) { + dtm_cache_flush(); +#ifdef WDL_PROBE + wdl_cache_flush(); +#endif + tbstats_reset(); + return; +} + +extern void +tbstats_reset(void) { + dtm_cache_reset_counters(); +#ifdef WDL_PROBE + wdl_cache_reset_counters(); +#endif + eg_was_open_reset(); + Drive.hits = 0; + Drive.miss = 0; + return; +} + +static void dtm_hash_insert(dtm_block_t *e); + +static void +dtm_hash_rebuild(void) { + dtm_block_t *p; + size_t i; + + for (i = 0; i < dtm_cache.ht_size; i++) + dtm_cache.hash_table[i] = NULL; + dtm_cache.ht_used = 0; + + for (p = dtm_cache.top; p != NULL; p = p->prev) + dtm_hash_insert(p); +} + +static void +dtm_hash_insert(dtm_block_t *e) { + size_t h1, h2; + + if (dtm_cache.ht_used > dtm_cache.ht_size * 3 / 4) + dtm_hash_rebuild(); + + h1 = hash_func_1(e->key, e->side, e->offset) & (dtm_cache.ht_size - 1); + h2 = hash_func_2(e->key, e->side, e->offset); + while (dtm_cache.hash_table[h1]) + h1 = (h1 + h2) & (dtm_cache.ht_size - 1); + dtm_cache.hash_table[h1] = e; + dtm_cache.ht_used++; +} + +static dtm_block_t * +dtm_cache_pointblock(tbkey_t key, unsigned side, index_t idx) { + index_t offset; + index_t remainder; + dtm_block_t *p; + dtm_block_t *ret; + size_t h1, h2; + + if (!dtm_cache_is_on()) + return NULL; + + split_index(dtm_cache.entries_per_block, idx, &offset, &remainder); + + ret = NULL; + + h1 = hash_func_1(key, side, offset) & (dtm_cache.ht_size - 1); + h2 = hash_func_2(key, side, offset); + while (1) { + p = dtm_cache.hash_table[h1]; + if (!p) + break; + + dtm_cache.comparisons++; + + if (key == p->key && side == p->side && offset == p->offset) { + ret = p; + break; + } + + h1 = (h1 + h2) & (dtm_cache.ht_size - 1); + } + + FOLLOW_LU("point_to_dtm_block ok?", (ret != NULL)) + + return ret; +} + +/****************************************************************************\ +| +| +| WRAPPERS for ENCODING/DECODING FUNCTIONS ZONE +| +| +\****************************************************************************/ + +#include "gtb-dec.h" + +/* +| +| PRE LOAD CACHE AND DEPENDENT FUNCTIONS +| +\*--------------------------------------------------------------------------*/ + +struct ZIPINFO { + index_t extraoffset; + index_t totalblocks; + index_t *blockindex; +}; + +struct ZIPINFO Zipinfo[MAX_EGKEYS]; + +static index_t egtb_block_getnumber(tbkey_t key, unsigned side, index_t idx); + +static index_t egtb_block_getsize(tbkey_t key, index_t idx); + +static index_t egtb_block_getsize_zipped(tbkey_t key, index_t block); + +static bool_t egtb_block_park(tbkey_t key, index_t block); + +static bool_t egtb_block_read(tbkey_t key, index_t len, unsigned char *buffer); + +static bool_t egtb_block_decode(tbkey_t key, index_t z, unsigned char *bz, index_t n, unsigned char *bp); + +static bool_t egtb_block_unpack(unsigned side, index_t n, const unsigned char *bp, dtm_t *out); + +static bool_t egtb_file_beready(tbkey_t key); + +static bool_t egtb_loadindexes(tbkey_t key); + +static index_t egtb_block_uncompressed_to_index(tbkey_t key, index_t b); + +static bool_t fread32(FILE *f, unsigned long int *y); + + +static unsigned int +zipinfo_init(void) { + int i, start, end; + unsigned ret; + bool_t ok, complet[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + bool_t pa, partial[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + unsigned int z; + int x, j; + + /* reset all values */ + for (i = 0; i < MAX_EGKEYS; i++) { + Zipinfo[i].blockindex = NULL; + Zipinfo[i].extraoffset = 0; + Zipinfo[i].totalblocks = 0; + } + + /* load all values */ + start = 0; + end = 5; + x = 3; + for (i = start, ok = TRUE, pa = FALSE; i < end; i++) { + ok = NULL != fd_openit(i); + pa = pa || ok; + ok = ok && egtb_loadindexes(i); + } + complet[x] = ok; + partial[x] = pa; + + start = 5; + end = 35; + x = 4; + for (i = start, ok = TRUE, pa = FALSE; i < end; i++) { + ok = NULL != fd_openit(i); + pa = pa || ok; + ok = ok && egtb_loadindexes(i); + } + complet[x] = ok; + partial[x] = pa; + + start = 35; + end = MAX_EGKEYS; + x = 5; + for (i = start, ok = TRUE, pa = FALSE; i < end; i++) { + ok = NULL != fd_openit(i); + pa = pa || ok; + ok = ok && egtb_loadindexes(i); + } + complet[x] = ok; + partial[x] = pa; + + + for (j = 0, z = 0, x = 3; x < 8; x++) { + if (partial[x]) z |= 1u << j; + j++; + if (complet[x]) z |= 1u << j; + j++; + } + + ret = z; + + return ret; +} + +static void +zipinfo_done(void) { + int i; + bool_t ok; + for (i = 0, ok = TRUE; ok && i < MAX_EGKEYS; i++) { + if (Zipinfo[i].blockindex != NULL) { + free(Zipinfo[i].blockindex); + Zipinfo[i].blockindex = NULL; + Zipinfo[i].extraoffset = 0; + Zipinfo[i].totalblocks = 0; + } + } + return; +} + +static size_t +zipinfo_memory_allocated(void) { + int i; + index_t accum_blocks = 0; + for (i = 0; i < MAX_EGKEYS; i++) { + if (Zipinfo[i].blockindex != NULL) { + accum_blocks += Zipinfo[i].totalblocks; + } + } + return (size_t) accum_blocks * sizeof(index_t); +} + +extern size_t +tb_indexmemory(void) { + return zipinfo_memory_allocated(); +} + +static bool_t +fread32(FILE *f, unsigned long int *y) { + enum SIZE { + SZ = 4 + }; + int i; + unsigned long int x; + unsigned char p[SZ]; + bool_t ok; + + ok = (SZ == fread(p, sizeof(unsigned char), SZ, f)); + + if (ok) { + for (x = 0, i = 0; i < SZ; i++) { + x |= (unsigned long int) p[i] << (i * 8); + } + *y = x; + } + return ok; +} + +static bool_t +egtb_loadindexes(tbkey_t key) { + + unsigned long int blocksize = 1; + unsigned long int tailblocksize1 = 0; + unsigned long int tailblocksize2 = 0; + unsigned long int offset = 0; + unsigned long int dummy; + unsigned long int i; + unsigned long int blocks; + unsigned long int n_idx; + unsigned long int idx = 0; + index_t *p; + + bool_t ok; + + FILE *f; + + if (Uncompressed) { + assert (decoding_scheme() == 0 && GTB_scheme == 0); + return TRUE; /* no need to load indexes */ + } + if (Zipinfo[key].blockindex != NULL) + return TRUE; /* indexes must have been loaded already */ + + if (NULL == (f = egkey[key].fd)) + return FALSE; /* file was no open */ + + /* Get Reserved bytes, blocksize, offset */ + ok = (0 == fseek(f, 0, SEEK_SET)) && + fread32(f, &dummy) && + fread32(f, &dummy) && + fread32(f, &blocksize) && + fread32(f, &dummy) && + fread32(f, &tailblocksize1) && + fread32(f, &dummy) && + fread32(f, &tailblocksize2) && + fread32(f, &dummy) && + fread32(f, &offset) && + fread32(f, &dummy); + + blocks = (offset - 40) / 4 - 1; + n_idx = blocks + 1; + + p = NULL; + + ok = ok && NULL != (p = (index_t *) malloc(n_idx * sizeof(index_t))); + + /* Input of Indexes */ + for (i = 0; ok && i < n_idx; i++) { + ok = fread32(f, &idx); + p[i] = (index_t) idx; /* reads a 32 bit int, and converts it to index_t */ assert (sizeof(index_t) >= 4); + } + + if (ok) { + Zipinfo[key].extraoffset = 0; + assert (n_idx <= MAXINDEX_T); + Zipinfo[key].totalblocks = (index_t) n_idx; + Zipinfo[key].blockindex = p; + } + + if (!ok && p != NULL) { + free(p); + } + + return ok; +} + +static index_t +egtb_block_uncompressed_to_index(tbkey_t key, index_t b) { + index_t max; + index_t blocks_per_side; + index_t idx; + + max = egkey[key].maxindex; + blocks_per_side = 1 + (max - 1) / (index_t) dtm_cache.entries_per_block; + + if (b < blocks_per_side) { + idx = 0; + } else { + b -= blocks_per_side; + idx = max; + } + idx += b * (index_t) dtm_cache.entries_per_block; + return idx; +} + + +static index_t +egtb_block_getnumber(tbkey_t key, unsigned side, index_t idx) { + index_t blocks_per_side; + index_t block_in_side; + index_t max = egkey[key].maxindex; + + blocks_per_side = 1 + (max - 1) / (index_t) dtm_cache.entries_per_block; + block_in_side = idx / (index_t) dtm_cache.entries_per_block; + + return (index_t) side * blocks_per_side + block_in_side; /* block */ +} + + +static index_t +egtb_block_getsize(tbkey_t key, index_t idx) { + index_t blocksz = (index_t) dtm_cache.entries_per_block; + index_t maxindex = egkey[key].maxindex; + index_t block, offset, x; + + assert (dtm_cache.entries_per_block <= MAXINDEX_T); + assert (0 <= idx && idx < maxindex); + assert (key < MAX_EGKEYS); + + block = idx / blocksz; + offset = block * blocksz; + + /* + | adjust block size in case that this is the last block + | and is shorter than "blocksz" + */ + if ((offset + blocksz) > maxindex) + x = maxindex - offset; /* last block size */ + else + x = blocksz; /* size of a normal block */ + + return x; +} + +static index_t +egtb_block_getsize_zipped(tbkey_t key, index_t block) { + index_t i, j; + assert (Zipinfo[key].blockindex != NULL); + i = Zipinfo[key].blockindex[block]; + j = Zipinfo[key].blockindex[block + 1]; + return j - i; +} + + +static bool_t +egtb_file_beready(tbkey_t key) { + bool_t success; + assert (key < MAX_EGKEYS); + success = (NULL != egkey[key].fd) || + (NULL != fd_openit(key) && egtb_loadindexes(key)); + return success; +} + + +static bool_t +egtb_block_park(tbkey_t key, index_t block) { + index_t i; + long fseek_i; + assert (egkey[key].fd != NULL); + + if (Uncompressed) { + assert (decoding_scheme() == 0 && GTB_scheme == 0); + i = egtb_block_uncompressed_to_index(key, block); + } else { + assert (Zipinfo[key].blockindex != NULL); + i = Zipinfo[key].blockindex[block]; + i += Zipinfo[key].extraoffset; + } + + fseek_i = (long) i; + assert (fseek_i >= 0); + return 0 == fseek(egkey[key].fd, fseek_i, SEEK_SET); +} + + +static bool_t +egtb_block_read(tbkey_t key, index_t len, unsigned char *buffer) { + assert (egkey[key].fd != NULL); + assert (sizeof(size_t) >= sizeof(len)); + return ((size_t) len == fread(buffer, sizeof(unsigned char), (size_t) len, egkey[key].fd)); +} + +tbkey_t TB_PROBE_indexing_dummy; + +static bool_t +egtb_block_decode(tbkey_t key, index_t z, unsigned char *bz, index_t n, unsigned char *bp) +/* bz:buffer zipped to bp:buffer packed */ +{ + size_t zz = (size_t) z; + size_t nn = (size_t) n; + TB_PROBE_indexing_dummy = key; /* to silence compiler */ + assert (sizeof(size_t) >= sizeof(n)); + assert (sizeof(size_t) >= sizeof(z)); + return decode(zz - 1, bz + 1, nn, bp); +} + +static bool_t +egtb_block_unpack(unsigned side, index_t n, const unsigned char *bp, dtm_t *out) +/* bp:buffer packed to out:distance to mate buffer */ +{ + index_t i; + if (WH == side) { + for (i = 0; i < n; i++) { + *out++ = dtm_unpack(WH, bp[i]); + } + } else { + for (i = 0; i < n; i++) { + *out++ = dtm_unpack(BL, bp[i]); + } + } + return TRUE; +} + +static bool_t +preload_cache(tbkey_t key, unsigned side, index_t idx) +/* output to the least used block of the cache */ +{ + dtm_block_t *pblock; + dtm_t *p; + bool_t ok; + unsigned char Buffer_zipped[EGTB_MAXBLOCKSIZE]; + unsigned char Buffer_packed[EGTB_MAXBLOCKSIZE]; + + FOLLOW_label("preload_cache starts") + + if (idx >= egkey[key].maxindex) { + FOLLOW_LULU("Wrong index", __LINE__, idx) + return FALSE; + } + + /* find aged blocked in cache */ + pblock = point_block_to_replace(); + + if (NULL == pblock) + return FALSE; + + p = pblock->p_arr; + + if (Uncompressed) { + + index_t block = egtb_block_getnumber(key, side, idx); + index_t n = egtb_block_getsize(key, idx); + + ok = egtb_file_beready(key) + && egtb_block_park(key, block) + && egtb_block_read(key, n, Buffer_packed) + && egtb_block_unpack(side, n, Buffer_packed, p); + + FOLLOW_LULU("preload_cache", __LINE__, ok) + + assert (decoding_scheme() == 0 && GTB_scheme == 0); + + if (ok) { Bytes_read = Bytes_read + (uint64_t) n; } + + } else { + + index_t block = 0; + index_t n = 0; + index_t z = 0; + + ok = egtb_file_beready(key); + + FOLLOW_LULU("preload_cache", __LINE__, ok) + + if (ok) { + block = egtb_block_getnumber(key, side, idx); + n = egtb_block_getsize(key, idx); + z = egtb_block_getsize_zipped(key, block); + } + + ok = ok + && egtb_block_park(key, block); + FOLLOW_LULU("preload_cache", __LINE__, ok) + + ok = ok + && egtb_block_read(key, z, Buffer_zipped); + FOLLOW_LULU("preload_cache", __LINE__, ok) + + mythread_mutex_unlock(&Egtb_lock); + + ok = ok + && egtb_block_decode(key, z, Buffer_zipped, n, Buffer_packed); + FOLLOW_LULU("preload_cache", __LINE__, ok) + + mythread_mutex_lock(&Egtb_lock); + pblock = point_block_to_replace(); + p = pblock->p_arr; + + ok = ok + && egtb_block_unpack(side, n, Buffer_packed, p); + FOLLOW_LULU("preload_cache", __LINE__, ok) + + if (ok) { Bytes_read = Bytes_read + (uint64_t) z; } + } + + if (ok) { + + index_t offset; + index_t remainder; + split_index(dtm_cache.entries_per_block, idx, &offset, &remainder); + + pblock->key = key; + pblock->side = side; + pblock->offset = offset; + dtm_hash_insert(pblock); + } else { + /* make it unusable */ + pblock->key = -1; + pblock->side = gtbNOSIDE; + pblock->offset = gtbNOINDEX; + } + + FOLLOW_LU("preload_cache?", ok) + + return ok; +} + +/****************************************************************************\ +| +| +| MEMORY ALLOCATION ZONE +| +| +\****************************************************************************/ + + +mySHARED void +egtb_freemem(int i) { + if (egkey[i].status == STATUS_MALLOC) { + assert (egkey[i].egt_w != NULL); + assert (egkey[i].egt_b != NULL); + free(egkey[i].egt_w); + free(egkey[i].egt_b); + egkey[i].egt_w = NULL; + egkey[i].egt_b = NULL; + } + egkey[i].status = STATUS_ABSENT; +} + +/***************************************************************************/ + +mySHARED bool_t +get_dtm(tbkey_t key, unsigned side, index_t idx, dtm_t *out, bool_t probe_hard_flag) { + bool_t found; + + if (probe_hard_flag) { + dtm_cache.hard++; + } else { + dtm_cache.soft++; + } + + if (get_dtm_from_cache(key, side, idx, out)) { + dtm_cache.hits++; + found = TRUE; + } else if (probe_hard_flag) { + dtm_cache.hardmisses++; + found = preload_cache(key, side, idx) && + get_dtm_from_cache(key, side, idx, out); + + if (found) { + Drive.hits++; + } else { + Drive.miss++; + } + + + } else { + dtm_cache.softmisses++; + found = FALSE; + } + return found; +} + + +static bool_t +get_dtm_from_cache(tbkey_t key, unsigned side, index_t idx, dtm_t *out) { + index_t offset; + index_t remainder; + bool_t found; + dtm_block_t *p; + + if (!dtm_cache_is_on()) + return FALSE; + + split_index(dtm_cache.entries_per_block, idx, &offset, &remainder); + + found = NULL != (p = dtm_cache_pointblock(key, side, idx)); + + if (found) { + *out = p->p_arr[remainder]; + movetotop(p); + } + + FOLLOW_LU("get_dtm_from_cache ok?", found) + + return found; +} + + +static void +split_index(size_t entries_per_block, index_t i, index_t *o, index_t *r) { + index_t n; + n = i / (index_t) entries_per_block; + *o = n * (index_t) entries_per_block; + *r = i - *o; + return; +} + + +static dtm_block_t * +point_block_to_replace(void) { + dtm_block_t *p, *t, *s; + + assert (0 == dtm_cache.n || dtm_cache.top != NULL); + assert (0 == dtm_cache.n || dtm_cache.bot != NULL); + assert (0 == dtm_cache.n || dtm_cache.bot->prev == NULL); + assert (0 == dtm_cache.n || dtm_cache.top->next == NULL); + + /* no cache is being used */ + if (dtm_cache.max_blocks == 0) + return NULL; + + if (dtm_cache.n > 0 && -1 == dtm_cache.top->key) { + + /* top entry is unusable, should be the one to replace*/ + p = dtm_cache.top; + + } else if (dtm_cache.n == 0) { + + assert (NULL != dtm_cache.entry); + p = &dtm_cache.entry[dtm_cache.n++]; + dtm_cache.top = p; + dtm_cache.bot = p; + + assert (NULL != p); + p->prev = NULL; + p->next = NULL; + + } else if (dtm_cache.n < dtm_cache.max_blocks) { /* add */ + + assert (NULL != dtm_cache.entry); + s = dtm_cache.top; + p = &dtm_cache.entry[dtm_cache.n++]; + dtm_cache.top = p; + + assert (NULL != p && NULL != s); + s->next = p; + p->prev = s; + p->next = NULL; + + } else if (1 < dtm_cache.max_blocks) { /* replace*/ + + assert (NULL != dtm_cache.bot && NULL != dtm_cache.top); + t = dtm_cache.bot; + s = dtm_cache.top; + + dtm_cache.bot = t->next; + dtm_cache.top = t; + + s->next = t; + t->prev = s; + + assert (dtm_cache.top); + dtm_cache.top->next = NULL; + + assert (dtm_cache.bot); + dtm_cache.bot->prev = NULL; + + p = t; + + } else { + + assert (1 == dtm_cache.max_blocks); + p = dtm_cache.top; + assert (p == dtm_cache.bot && p == dtm_cache.entry); + } + + /* make the information content unusable, it will be replaced */ + p->key = -1; + p->side = gtbNOSIDE; + p->offset = gtbNOINDEX; + + return p; +} + +static void +movetotop(dtm_block_t *t) { + dtm_block_t *s, *nx, *pv; + + assert (t != NULL); + + if (t->next == NULL) /* at the top already */ + return; + + /* detach */ + pv = t->prev; + nx = t->next; + + if (pv == NULL) /* at the bottom */ + dtm_cache.bot = nx; + else + pv->next = nx; + + if (nx == NULL) /* at the top */ + dtm_cache.top = pv; + else + nx->prev = pv; + + /* relocate */ + s = dtm_cache.top; + assert (s != NULL); + if (s == NULL) + dtm_cache.bot = t; + else + s->next = t; + + t->next = NULL; + t->prev = s; + dtm_cache.top = t; + + return; +} + +/****************************************************************************\ + * + * + * INDEXING ZONE + * + * + ****************************************************************************/ + +static void +init_indexing(int verbosity) { + index_t a, b, c, d, e, f; + + init_flipt(); + + a = init_kkidx(); + b = init_ppidx(); + c = init_aaidx(); + d = init_aaa(); + e = init_pp48_idx(); + f = init_ppp48_idx(); + + if (verbosity) { + printf("\nGTB supporting tables, Initialization\n"); + printf(" Max kk idx: %8d\n", (int) a); + printf(" Max pp idx: %8d\n", (int) b); + printf(" Max aa idx: %8d\n", (int) c); + printf(" Max aaa idx: %8d\n", (int) d); + printf(" Max pp48 idx: %8d\n", (int) e); + printf(" Max ppp48 idx: %8d\n", (int) f); + } + + if (!reach_was_initialized()) + reach_init(); + + /* testing used only in development stage */ + +#ifdef _MSC_VER +#pragma warning(disable:4127) +#endif + + if (0) { + list_index(); + printf("\nTEST indexing functions\n"); + + test_kaakb(); + test_kaabk(); + test_kaaak(); + test_kabbk(); + + test_kapkb(); + test_kabkp(); + + test_kppka(); + + test_kapkp(); + test_kabpk(); + test_kaapk(); + + test_kappk(); + test_kaakp(); + test_kppk(); + test_kppkp(); + test_kpppk(); + } + +#ifdef _MSC_VER +#pragma warning(default:4127) +#endif + + return; +} + + +static index_t +init_kkidx(void) +/* modifies kkidx[][], wksq[], bksq[] */ +{ + index_t idx; + SQUARE x, y, i, j; + + /* default is noindex */ + for (x = 0; x < 64; x++) { + for (y = 0; y < 64; y++) { + IDX_set_empty(kkidx[x][y]); + } + } + + idx = 0; + for (x = 0; x < 64; x++) { + for (y = 0; y < 64; y++) { + + /* is x,y illegal? continue */ + if (possible_attack(x, y, wK) || x == y) + continue; + + /* normalize */ + /*i <-- x; j <-- y */ + norm_kkindex(x, y, &i, &j); + + if (IDX_is_empty(kkidx[i][j])) { /* still empty */ + kkidx[i][j] = idx; + kkidx[x][y] = idx; + bksq[idx] = i; + wksq[idx] = j; + idx++; + } + } + } + + assert (idx == MAX_KKINDEX); + + return idx; +} + + +static index_t +init_aaidx(void) +/* modifies aabase[], aaidx[][] */ +{ + index_t idx; + SQUARE x, y; + + /* default is noindex */ + for (x = 0; x < 64; x++) { + for (y = 0; y < 64; y++) { + IDX_set_empty(aaidx[x][y]); + } + } + + for (idx = 0; idx < MAX_AAINDEX; idx++) + aabase[idx] = 0; + + idx = 0; + for (x = 0; x < 64; x++) { + for (y = x + 1; y < 64; y++) { + + assert (idx == (int) ((y - x) + x * (127 - x) / 2 - 1)); + + if (IDX_is_empty(aaidx[x][y])) { /* still empty */ + aaidx[x][y] = idx; + aaidx[y][x] = idx; + aabase[idx] = (unsigned char) x; + idx++; + } else { + assert (aaidx[x][y] == idx); + assert (aabase[idx] == x); + } + + + } + } + + assert (idx == MAX_AAINDEX); + + return idx; +} + + +static index_t +init_ppidx(void) +/* modifies ppidx[][], pp_hi24[], pp_lo48[] */ +{ + index_t i, j; + index_t idx = 0; + SQUARE a, b; + + /* default is noindex */ + for (i = 0; i < 24; i++) { + for (j = 0; j < 48; j++) { + IDX_set_empty(ppidx[i][j]); + } + } + + for (idx = 0; idx < MAX_PPINDEX; idx++) { + IDX_set_empty(pp_hi24[idx]); + IDX_set_empty(pp_lo48[idx]); + } + + idx = 0; + for (a = H7; a >= A2; a--) { + + if ((a & 07) < 4) /* square in the queen side */ + continue; + + for (b = a - 1; b >= A2; b--) { + + SQUARE anchor, loosen; + + pp_putanchorfirst(a, b, &anchor, &loosen); + + if ((anchor & 07) > 3) { /* square in the king side */ + anchor = flipWE(anchor); + loosen = flipWE(loosen); + } + + i = wsq_to_pidx24(anchor); + j = wsq_to_pidx48(loosen); + + if (IDX_is_empty(ppidx[i][j])) { + + ppidx[i][j] = idx; + assert (idx < MAX_PPINDEX); + pp_hi24[idx] = i; + assert (i < 24); + pp_lo48[idx] = j; + assert (j < 48); + idx++; + } + + } + } + assert (idx == MAX_PPINDEX); + return idx; +} + +static void +init_flipt(void) { + unsigned int i, j; + for (i = 0; i < 64; i++) { + for (j = 0; j < 64; j++) { + flipt[i][j] = flip_type(i, j); + } + } +} + +/*--- NORMALIZE -------*/ + +static void +norm_kkindex(SQUARE x, SQUARE y, /*@out@*/ SQUARE *pi, /*@out@*/ SQUARE *pj) { + unsigned int rowx, rowy, colx, coly; + + assert (x < 64); + assert (y < 64); + + if (getcol(x) > 3) { + x = flipWE(x); /* x = x ^ 07 */ + y = flipWE(y); + } + if (getrow(x) > 3) { + x = flipNS(x); /* x = x ^ 070 */ + y = flipNS(y); + } + rowx = getrow(x); + colx = getcol(x); + if (rowx > colx) { + x = flipNW_SE(x); /* x = ((x&7)<<3) | (x>>3) */ + y = flipNW_SE(y); + } + rowy = getrow(y); + coly = getcol(y); + if (rowx == colx && rowy > coly) { + x = flipNW_SE(x); + y = flipNW_SE(y); + } + + *pi = x; + *pj = y; +} + +static unsigned int +flip_type(SQUARE x, SQUARE y) { + unsigned int rowx, rowy, colx, coly; + unsigned int ret = 0; + + assert (x < 64); + assert (y < 64); + + + if (getcol(x) > 3) { + x = flipWE(x); /* x = x ^ 07 */ + y = flipWE(y); + ret |= 1; + } + if (getrow(x) > 3) { + x = flipNS(x); /* x = x ^ 070 */ + y = flipNS(y); + ret |= 2; + } + rowx = getrow(x); + colx = getcol(x); + if (rowx > colx) { + x = flipNW_SE(x); /* x = ((x&7)<<3) | (x>>3) */ + y = flipNW_SE(y); + ret |= 4; + } + rowy = getrow(y); + coly = getcol(y); + if (rowx == colx && rowy > coly) { + x = flipNW_SE(x); + y = flipNW_SE(y); + ret |= 4; + } + return ret; +} + + +static void +pp_putanchorfirst(SQUARE a, SQUARE b, /*@out@*/ SQUARE *out_anchor, /*@out@*/ SQUARE *out_loosen) { + unsigned int anchor, loosen; + + unsigned int row_b, row_a; + row_b = b & 070; + row_a = a & 070; + + /* default */ + anchor = a; + loosen = b; + if (row_b > row_a) { + anchor = b; + loosen = a; + } else if (row_b == row_a) { + unsigned int x, col, inv, hi_a, hi_b; + x = a; + col = x & 07; + inv = col ^ 07; + x = (1u << col) | (1u << inv); + x &= (x - 1); + hi_a = x; + + x = b; + col = x & 07; + inv = col ^ 07; + x = (1u << col) | (1u << inv); + x &= (x - 1); + hi_b = x; + + if (hi_b > hi_a) { + anchor = b; + loosen = a; + } + + if (hi_b < hi_a) { + anchor = a; + loosen = b; + } + + if (hi_b == hi_a) { + if (a < b) { + anchor = a; + loosen = b; + } else { + anchor = b; + loosen = a; + } + } + } + + *out_anchor = anchor; + *out_loosen = loosen; + return; +} + + +static index_t +wsq_to_pidx24(SQUARE pawn) { + unsigned int idx24; + SQUARE sq = pawn; + + /* input can be only queen side, pawn valid */ + assert (A2 <= pawn && pawn < A8); + assert ((pawn & 07) < 4); + + sq ^= 070; /* flipNS*/ + sq -= 8; /* down one row*/ + idx24 = (sq + (sq & 3)) >> 1; + assert (idx24 < 24); + return (index_t) idx24; +} + +static index_t +wsq_to_pidx48(SQUARE pawn) { + unsigned int idx48; + SQUARE sq = pawn; + + /* input can be both queen or king side, pawn valid square */ + assert (A2 <= pawn && pawn < A8); + + sq ^= 070; /* flipNS*/ + sq -= 8; /* down one row*/ + idx48 = sq; + assert (idx48 < 48); + return (index_t) idx48; +} + +static SQUARE +pidx24_to_wsq(index_t a) { + enum { + B11100 = 7u << 2 + }; + unsigned int x = (unsigned int) a; /* x is pslice */ + assert (a < 24); + + x += x & B11100; /* get upper part and double it */ + x += 8; /* add extra row */ + x ^= 070; /* flip NS */ + return (SQUARE) x; +} + +static SQUARE +pidx48_to_wsq(index_t a) { + unsigned int x; + assert (a < 48); + /* x is pslice */ + x = (unsigned int) a; + x += 8; /* add extra row */ + x ^= 070; /* flip NS */ + return x; +} + + +static void +kxk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_A = 64 + }; + + index_t a = i / BLOCK_A; + index_t b = i - a * BLOCK_A; + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + pw[1] = (SQUARE) b; + pw[2] = NOSQUARE; + pb[1] = NOSQUARE; + + assert (kxk_pctoindex(pw, pb, &a) && a == i); + + return; +} + +static bool_t +kxk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) { + enum { + BLOCK_A = 64 + }; + SQUARE *p; + SQUARE ws[32], bs[32]; + index_t ki; + int i; + + unsigned int ft; + + ft = flip_type(inp_pb[0], inp_pw[0]); + + assert (ft < 8); + + + for (i = 0; inp_pw[i] != NOSQUARE; i++) { + ws[i] = inp_pw[i]; + } + ws[i] = NOSQUARE; + for (i = 0; inp_pb[i] != NOSQUARE; i++) { + bs[i] = inp_pb[i]; + } + bs[i] = NOSQUARE; + + if ((ft & 1) != 0) { + for (p = ws; *p != NOSQUARE; p++) + *p = flipWE(*p); + for (p = bs; *p != NOSQUARE; p++) + *p = flipWE(*p); + } + + if ((ft & 2) != 0) { + for (p = ws; *p != NOSQUARE; p++) + *p = flipNS(*p); + for (p = bs; *p != NOSQUARE; p++) + *p = flipNS(*p); + } + + if ((ft & 4) != 0) { + for (p = ws; *p != NOSQUARE; p++) + *p = flipNW_SE(*p); + for (p = bs; *p != NOSQUARE; p++) + *p = flipNW_SE(*p); + } + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + + if (IDX_is_empty(ki)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + (index_t) ws[1]; + return TRUE; + +} + + +static void +kabk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + index_t a, b, c, r; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r; + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + pw[1] = (SQUARE) b; + pw[2] = (SQUARE) c; + pw[3] = NOSQUARE; + + pb[1] = NOSQUARE; + + assert (kabk_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kabk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) { + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + SQUARE *p; + SQUARE ws[32], bs[32]; + index_t ki; + int i; + + unsigned int ft; + + ft = flip_type(inp_pb[0], inp_pw[0]); + + assert (ft < 8); + + for (i = 0; inp_pw[i] != NOSQUARE; i++) { + ws[i] = inp_pw[i]; + } + ws[i] = NOSQUARE; + for (i = 0; inp_pb[i] != NOSQUARE; i++) { + bs[i] = inp_pb[i]; + } + bs[i] = NOSQUARE; + + if ((ft & 1) != 0) { + for (p = ws; *p != NOSQUARE; p++) + *p = flipWE(*p); + for (p = bs; *p != NOSQUARE; p++) + *p = flipWE(*p); + } + + if ((ft & 2) != 0) { + for (p = ws; *p != NOSQUARE; p++) + *p = flipNS(*p); + for (p = bs; *p != NOSQUARE; p++) + *p = flipNS(*p); + } + + if ((ft & 4) != 0) { + for (p = ws; *p != NOSQUARE; p++) + *p = flipNW_SE(*p); + for (p = bs; *p != NOSQUARE; p++) + *p = flipNW_SE(*p); + } + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + + if (IDX_is_empty(ki)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + (index_t) ws[1] * BLOCK_B + (index_t) ws[2]; + return TRUE; + +} + + +static void +kabkc_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t a, b, c, d, r; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + pw[1] = (SQUARE) b; + pw[2] = (SQUARE) c; + pw[3] = NOSQUARE; + + pb[1] = (SQUARE) d; + pb[2] = NOSQUARE; + + assert (kabkc_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kabkc_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) { + enum { + N_WHITE = 3, N_BLACK = 2 + }; + + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; + index_t ki; + int i; + unsigned int ft; + +#if 0 + ft = flip_type (inp_pb[0], inp_pw[0]); +#else + ft = flipt[inp_pb[0]][inp_pw[0]]; +#endif + + assert (ft < 8); + + for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; + ws[N_WHITE] = NOSQUARE; + for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; + bs[N_BLACK] = NOSQUARE; + + if ((ft & WE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipWE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipWE(bs[i]); + } + + if ((ft & NS_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNS(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNS(bs[i]); + } + + if ((ft & NW_SE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE(bs[i]); + } + + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + + if (IDX_is_empty(ki)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + (index_t) ws[1] * BLOCK_B + (index_t) ws[2] * BLOCK_C + (index_t) bs[1]; + return TRUE; + +} + +/* ABC/ ***/ + +extern void +kabck_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t a, b, c, d, r; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + pw[1] = (SQUARE) b; + pw[2] = (SQUARE) c; + pw[3] = (SQUARE) d; + pw[4] = NOSQUARE; + + pb[1] = NOSQUARE; + + assert (kabck_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +extern bool_t +kabck_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) { + enum { + N_WHITE = 4, N_BLACK = 1 + }; + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + + SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; + index_t ki; + int i; + unsigned int ft; + + ft = flipt[inp_pb[0]][inp_pw[0]]; + + assert (ft < 8); + + for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; + ws[N_WHITE] = NOSQUARE; + for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; + bs[N_BLACK] = NOSQUARE; + + if ((ft & WE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipWE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipWE(bs[i]); + } + + if ((ft & NS_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNS(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNS(bs[i]); + } + + if ((ft & NW_SE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE(bs[i]); + } + + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + + if (IDX_is_empty(ki)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + (index_t) ws[1] * BLOCK_B + (index_t) ws[2] * BLOCK_C + (index_t) ws[3]; + return TRUE; + +} + + +static void +kakb_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + index_t a, b, c, r; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r; + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + pw[1] = (SQUARE) b; + pw[2] = NOSQUARE; + + pb[1] = (SQUARE) c; + pb[2] = NOSQUARE; + + assert (kakb_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kakb_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) { + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + SQUARE ws[32], bs[32]; + index_t ki; + unsigned int ft; + +#if 0 + ft = flip_type (inp_pb[0], inp_pw[0]); +#else + ft = flipt[inp_pb[0]][inp_pw[0]]; +#endif + + assert (ft < 8); + + ws[0] = inp_pw[0]; + ws[1] = inp_pw[1]; + ws[2] = NOSQUARE; + + bs[0] = inp_pb[0]; + bs[1] = inp_pb[1]; + bs[2] = NOSQUARE; + + if ((ft & 1) != 0) { + ws[0] = flipWE(ws[0]); + ws[1] = flipWE(ws[1]); + bs[0] = flipWE(bs[0]); + bs[1] = flipWE(bs[1]); + } + + if ((ft & 2) != 0) { + ws[0] = flipNS(ws[0]); + ws[1] = flipNS(ws[1]); + bs[0] = flipNS(bs[0]); + bs[1] = flipNS(bs[1]); + } + + if ((ft & 4) != 0) { + ws[0] = flipNW_SE(ws[0]); + ws[1] = flipNW_SE(ws[1]); + bs[0] = flipNW_SE(bs[0]); + bs[1] = flipNW_SE(bs[1]); + } + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + + if (IDX_is_empty(ki)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + (index_t) ws[1] * BLOCK_B + (index_t) bs[1]; + return TRUE; + +} + +/********************** KAAKB *************************************/ + +static bool_t test_kaakb(void); + +static bool_t kaakb_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kaakb_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kaakb(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kaakb"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = NOSQUARE; + + pb[0] = d; + pb[1] = e; + pb[2] = NOSQUARE; + + if (kaakb_pctoindex(pw, pb, &i)) { + kaakb_indextopc(i, px, py); + kaakb_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + +static void +kaakb_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_B = 64, + BLOCK_A = BLOCK_B * MAX_AAINDEX + }; + index_t a, b, c, r, x, y; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + + b = r / BLOCK_B; + r -= b * BLOCK_B; + + c = r; + + assert (i == (a * BLOCK_A + b * BLOCK_B + c)); + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + x = aabase[b]; + y = (b + 1) + x - (x * (127 - x) / 2); + + pw[1] = (SQUARE) x; + pw[2] = (SQUARE) y; + pw[3] = NOSQUARE; + + pb[1] = (SQUARE) c; + pb[2] = NOSQUARE; + + assert (kaakb_pctoindex(pw, pb, &a) && a == i); + + return; +} + +static bool_t +kaakb_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out) { + enum { + N_WHITE = 3, N_BLACK = 2 + }; + enum { + BLOCK_B = 64, + BLOCK_A = BLOCK_B * MAX_AAINDEX + }; + SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; + index_t ki, ai; + unsigned int ft; + int i; + + ft = flipt[inp_pb[0]][inp_pw[0]]; + + assert (ft < 8); + + for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; + ws[N_WHITE] = NOSQUARE; + for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; + bs[N_BLACK] = NOSQUARE; + + if ((ft & WE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipWE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipWE(bs[i]); + } + + if ((ft & NS_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNS(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNS(bs[i]); + } + + if ((ft & NW_SE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE(bs[i]); + } + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + ai = aaidx[ws[1]][ws[2]]; + + if (IDX_is_empty(ki) || IDX_is_empty(ai)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + ai * BLOCK_B + (index_t) bs[1]; + return TRUE; +} + +/****************** End KAAKB *************************************/ + +/********************** KAAB/K ************************************/ + +static bool_t test_kaabk(void); + +static bool_t kaabk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kaabk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kaabk(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kaabk"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = d; + pw[4] = NOSQUARE; + + pb[0] = e; + pb[1] = NOSQUARE; + + if (kaabk_pctoindex(pw, pb, &i)) { + kaabk_indextopc(i, px, py); + kaabk_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + +static void +kaabk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_B = 64, + BLOCK_A = BLOCK_B * MAX_AAINDEX + }; + index_t a, b, c, r, x, y; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + + b = r / BLOCK_B; + r -= b * BLOCK_B; + + c = r; + + assert (i == (a * BLOCK_A + b * BLOCK_B + c)); + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + x = aabase[b]; + y = (b + 1) + x - (x * (127 - x) / 2); + + pw[1] = (SQUARE) x; + pw[2] = (SQUARE) y; + pw[3] = (SQUARE) c; + pw[4] = NOSQUARE; + + pb[1] = NOSQUARE; + + assert (kaabk_pctoindex(pw, pb, &a) && a == i); + + return; +} + +static bool_t +kaabk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out) { + enum { + N_WHITE = 4, N_BLACK = 1 + }; + enum { + BLOCK_B = 64, + BLOCK_A = BLOCK_B * MAX_AAINDEX + }; + SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; + index_t ki, ai; + unsigned int ft; + int i; + + ft = flipt[inp_pb[0]][inp_pw[0]]; + + assert (ft < 8); + + for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; + ws[N_WHITE] = NOSQUARE; + for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; + bs[N_BLACK] = NOSQUARE; + + if ((ft & WE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipWE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipWE(bs[i]); + } + + if ((ft & NS_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNS(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNS(bs[i]); + } + + if ((ft & NW_SE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE(bs[i]); + } + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + ai = aaidx[ws[1]][ws[2]]; + + if (IDX_is_empty(ki) || IDX_is_empty(ai)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + ai * BLOCK_B + (index_t) ws[3]; + return TRUE; +} + +/****************** End KAAB/K *************************************/ + +/********************** KABB/K ************************************/ + +static bool_t test_kabbk(void); + +static bool_t kabbk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kabbk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kabbk(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kabbk"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = d; + pw[4] = NOSQUARE; + + pb[0] = e; + pb[1] = NOSQUARE; + + if (kabbk_pctoindex(pw, pb, &i)) { + kabbk_indextopc(i, px, py); + kabbk_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + +static void +kabbk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_B = 64, + BLOCK_A = BLOCK_B * MAX_AAINDEX + }; + index_t a, b, c, r, x, y; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + + b = r / BLOCK_B; + r -= b * BLOCK_B; + + c = r; + + assert (i == (a * BLOCK_A + b * BLOCK_B + c)); + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + x = aabase[b]; + y = (b + 1) + x - (x * (127 - x) / 2); + + pw[1] = (SQUARE) c; + pw[2] = (SQUARE) x; + pw[3] = (SQUARE) y; + pw[4] = NOSQUARE; + + pb[1] = NOSQUARE; + + assert (kabbk_pctoindex(pw, pb, &a) && a == i); + + return; +} + +static bool_t +kabbk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out) { + enum { + N_WHITE = 4, N_BLACK = 1 + }; + enum { + BLOCK_B = 64, + BLOCK_A = BLOCK_B * MAX_AAINDEX + }; + SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; + index_t ki, ai; + unsigned int ft; + int i; + + ft = flipt[inp_pb[0]][inp_pw[0]]; + + assert (ft < 8); + + for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; + ws[N_WHITE] = NOSQUARE; + for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; + bs[N_BLACK] = NOSQUARE; + + if ((ft & WE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipWE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipWE(bs[i]); + } + + if ((ft & NS_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNS(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNS(bs[i]); + } + + if ((ft & NW_SE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE(bs[i]); + } + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + ai = aaidx[ws[2]][ws[3]]; + + if (IDX_is_empty(ki) || IDX_is_empty(ai)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + ai * BLOCK_B + (index_t) ws[1]; + return TRUE; +} + +/********************** End KABB/K *************************************/ + +/********************** init KAAA/K ************************************/ + +static index_t +aaa_getsubi(sq_t x, sq_t y, sq_t z); + +static sq_t aaa_xyz[MAX_AAAINDEX][3]; +static index_t aaa_base[64]; + +static index_t +init_aaa(void) +/* modifies aaa_base[], aaa_xyz[][] */ +{ + index_t comb[64]; + index_t accum; + index_t a; + + index_t idx; + SQUARE x, y, z; + + /* getting aaa_base */ + comb[0] = 0; + for (a = 1; a < 64; a++) { + comb[a] = a * (a - 1) / 2; + } + + accum = 0; + aaa_base[0] = accum; + for (a = 0; a < (64 - 1); a++) { + accum += comb[a]; + aaa_base[a + 1] = accum; + } + + assert ((accum + comb[63]) == MAX_AAAINDEX); + /* end getting aaa_base */ + + + /* initialize aaa_xyz [][] */ + for (idx = 0; idx < MAX_AAAINDEX; idx++) { + IDX_set_empty (aaa_xyz[idx][0]); + IDX_set_empty (aaa_xyz[idx][1]); + IDX_set_empty (aaa_xyz[idx][2]); + } + + idx = 0; + for (z = 0; z < 64; z++) { + for (y = 0; y < z; y++) { + for (x = 0; x < y; x++) { + + assert (idx == aaa_getsubi(x, y, z)); + + aaa_xyz[idx][0] = x; + aaa_xyz[idx][1] = y; + aaa_xyz[idx][2] = z; + + idx++; + } + } + } + + assert (idx == MAX_AAAINDEX); + + return idx; +} + + +static index_t +aaa_getsubi(sq_t x, sq_t y, sq_t z) +/* uses aaa_base */ +{ + index_t calc_idx, base; + + assert (x < 64 && y < 64 && z < 64); + assert (x < y && y < z); + + base = aaa_base[z]; + calc_idx = (index_t) x + ((index_t) y - 1) * (index_t) y / 2 + base; + + return calc_idx; +} + +/********************** KAAA/K ************************************/ + +static bool_t test_kaaak(void); + +static bool_t kaaak_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kaaak_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kaaak(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kaaak"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = d; + pw[4] = NOSQUARE; + + pb[0] = e; + pb[1] = NOSQUARE; + + if (kaaak_pctoindex(pw, pb, &i)) { + kaaak_indextopc(i, px, py); + kaaak_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + +static void +kaaak_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_A = MAX_AAAINDEX + }; + index_t a, b, r; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + + b = r; + + assert (i == (a * BLOCK_A + b)); + assert (b < BLOCK_A); + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + pw[1] = aaa_xyz[b][0]; + pw[2] = aaa_xyz[b][1]; + pw[3] = aaa_xyz[b][2]; + pw[4] = NOSQUARE; + + pb[1] = NOSQUARE; + + assert (kaaak_pctoindex(pw, pb, &a) && a == i); + + return; +} + +static bool_t +kaaak_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) { + enum { + N_WHITE = 4, N_BLACK = 1 + }; + enum { + BLOCK_A = MAX_AAAINDEX + }; + SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; + index_t ki, ai; + unsigned int ft; + int i; + + ft = flipt[inp_pb[0]][inp_pw[0]]; + + assert (ft < 8); + + for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; + ws[N_WHITE] = NOSQUARE; + for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; + bs[N_BLACK] = NOSQUARE; + + if ((ft & WE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipWE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipWE(bs[i]); + } + + if ((ft & NS_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNS(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNS(bs[i]); + } + + if ((ft & NW_SE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE(bs[i]); + } + + + { + SQUARE tmp; + if (ws[2] < ws[1]) { + tmp = ws[1]; + ws[1] = ws[2]; + ws[2] = tmp; + } + if (ws[3] < ws[2]) { + tmp = ws[2]; + ws[2] = ws[3]; + ws[3] = tmp; + } + if (ws[2] < ws[1]) { + tmp = ws[1]; + ws[1] = ws[2]; + ws[2] = tmp; + } + } + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + +/*128 == (128 & (((ws[1]^ws[2])-1) | ((ws[1]^ws[3])-1) | ((ws[2]^ws[3])-1)) */ + + if (ws[1] == ws[2] || ws[1] == ws[3] || ws[2] == ws[3]) { + *out = NOINDEX; + return FALSE; + } + + ai = aaa_getsubi(ws[1], ws[2], ws[3]); + + if (IDX_is_empty(ki) || IDX_is_empty(ai)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + ai; + return TRUE; +} + +/****************** End KAAB/K *************************************/ + +/********************** KAP/KB ************************************/ + +static bool_t test_kapkb(void); + +static bool_t kapkb_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kapkb_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kapkb(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kapkb"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (c <= H1 || c >= A8) + continue; + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = NOSQUARE; + + pb[0] = e; + pb[1] = d; + pb[2] = NOSQUARE; + + if (kapkb_pctoindex(pw, pb, &i)) { + kapkb_indextopc(i, px, py); + kapkb_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + +static void +kapkb_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e; + *----------------------------------------------------------*/ + enum { + B11100 = 7u << 2 + }; + enum { + BLOCK_A = 64 * 64 * 64 * 64, BLOCK_B = 64 * 64 * 64, BLOCK_C = 64 * 64, BLOCK_D = 64 + }; + index_t a, b, c, d, e, r; + index_t x; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r / BLOCK_D; + r -= d * BLOCK_D; + e = r; + + /* x is pslice */ + x = a; + x += x & B11100; /* get upper part and double it */ + x += 8; /* add extra row */ + x ^= 070; /* flip NS */ + + pw[0] = (SQUARE) b; + pb[0] = (SQUARE) c; + pw[1] = (SQUARE) d; + pw[2] = (SQUARE) x; + pw[3] = NOSQUARE; + pb[1] = (SQUARE) e; + pb[2] = NOSQUARE; + + assert (kapkb_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kapkb_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64 * 64 * 64, BLOCK_B = 64 * 64 * 64, BLOCK_C = 64 * 64, BLOCK_D = 64 + }; + index_t pslice; + SQUARE sq; + SQUARE pawn = pw[2]; + SQUARE wa = pw[1]; + SQUARE wk = pw[0]; + SQUARE bk = pb[0]; + SQUARE ba = pb[1]; + + assert (A2 <= pawn && pawn < A8); + + if (!(A2 <= pawn && pawn < A8)) { + *out = NOINDEX; + return FALSE; + } + + if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + pawn = flipWE(pawn); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + ba = flipWE(ba); + } + + sq = pawn; + sq ^= 070; /* flipNS*/ + sq -= 8; /* down one row*/ + pslice = (index_t) ((sq + (sq & 3)) >> 1); + + *out = pslice * BLOCK_A + (index_t) wk * BLOCK_B + (index_t) bk * BLOCK_C + (index_t) wa * BLOCK_D + (index_t) ba; + + return TRUE; +} +/********************** end KAP/KB ************************************/ + +/************************* KAB/KP ************************************/ + +static bool_t test_kabkp(void); + +static bool_t kabkp_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kabkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kabkp(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kabkp"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (d <= H1 || d >= A8) + continue; + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = NOSQUARE; + + pb[0] = e; + pb[1] = d; + pb[2] = NOSQUARE; + + if (kabkp_pctoindex(pw, pb, &i)) { + kabkp_indextopc(i, px, py); + kabkp_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + +static void +kabkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e; + *----------------------------------------------------------*/ + enum { + B11100 = 7u << 2 + }; + enum { + BLOCK_A = 64 * 64 * 64 * 64, BLOCK_B = 64 * 64 * 64, BLOCK_C = 64 * 64, BLOCK_D = 64 + }; + index_t a, b, c, d, e, r; + index_t x; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r / BLOCK_D; + r -= d * BLOCK_D; + e = r; + + /* x is pslice */ + x = a; + x += x & B11100; /* get upper part and double it */ + x += 8; /* add extra row */ + /*x ^= 070;*/ /* do not flip NS */ + + pw[0] = (SQUARE) b; + pb[0] = (SQUARE) c; + pw[1] = (SQUARE) d; + pw[2] = (SQUARE) e; + pw[3] = NOSQUARE; + pb[1] = (SQUARE) x; + pb[2] = NOSQUARE; + + assert (kabkp_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kabkp_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64 * 64 * 64, BLOCK_B = 64 * 64 * 64, BLOCK_C = 64 * 64, BLOCK_D = 64 + }; + index_t pslice; + SQUARE sq; + SQUARE pawn = pb[1]; + SQUARE wa = pw[1]; + SQUARE wk = pw[0]; + SQUARE bk = pb[0]; + SQUARE wb = pw[2]; + + assert (A2 <= pawn && pawn < A8); + + if (!(A2 <= pawn && pawn < A8)) { + *out = NOINDEX; + return FALSE; + } + + if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + pawn = flipWE(pawn); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + wb = flipWE(wb); + } + + sq = pawn; + /*sq ^= 070;*/ /* do not flipNS*/ + sq -= 8; /* down one row*/ + pslice = (index_t) ((sq + (sq & 3)) >> 1); + + *out = pslice * BLOCK_A + (index_t) wk * BLOCK_B + (index_t) bk * BLOCK_C + (index_t) wa * BLOCK_D + (index_t) wb; + + return TRUE; +} + +/********************** end KAB/KP ************************************/ + + +static void +kpk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c; + *----------------------------------------------------------*/ + enum { + B11100 = 7u << 2 + }; + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + index_t a, b, c, r; + index_t x; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r; + + /* x is pslice */ + x = a; + x += x & B11100; /* get upper part and double it */ + x += 8; /* add extra row */ + x ^= 070; /* flip NS */ + + pw[1] = (SQUARE) x; + pw[0] = (SQUARE) b; + pb[0] = (SQUARE) c; + + pw[2] = NOSQUARE; + pb[1] = NOSQUARE; + + assert (kpk_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kpk_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + index_t pslice; + SQUARE sq; + SQUARE pawn = pw[1]; + SQUARE wk = pw[0]; + SQUARE bk = pb[0]; + +#ifdef DEBUG + if ( !(A2 <= pawn && pawn < A8)) { + SQ_CONTENT wp[MAX_LISTSIZE], bp[MAX_LISTSIZE]; + bp [0] = wp[0] = KING; + wp[1] = PAWN; + wp[2] = bp[1] = NOPIECE; + output_state (0, pw, pb, wp, bp); + } +#endif + + assert (A2 <= pawn && pawn < A8); + + if (!(A2 <= pawn && pawn < A8)) { + *out = NOINDEX; + return FALSE; + } + + if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + pawn = flipWE(pawn); + wk = flipWE(wk); + bk = flipWE(bk); + } + + sq = pawn; + sq ^= 070; /* flipNS*/ + sq -= 8; /* down one row*/ + pslice = (index_t) ((sq + (sq & 3)) >> 1); + + *out = pslice * BLOCK_A + (index_t) wk * BLOCK_B + (index_t) bk; + + return TRUE; +} + + +/********************** KPP/K ************************************/ + +static bool_t test_kppk(void); + +static bool_t kppk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kppk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kppk(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kppk"; + SQUARE a, b, c, d; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + sq_t anchor1, anchor2, loosen1, loosen2; + if (c <= H1 || c >= A8) + continue; + if (b <= H1 || b >= A8) + continue; + + pp_putanchorfirst(b, c, &anchor1, &loosen1); + pp_putanchorfirst(c, b, &anchor2, &loosen2); + if (!(anchor1 == anchor2 && loosen1 == loosen2)) { + printf("Output depends on input in pp_outanchorfirst()\n input:%u, %u\n", (unsigned) b, (unsigned) c); + fatal_error(); + } + } + } + + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + + + if (c <= H1 || c >= A8) + continue; + if (b <= H1 || b >= A8) + continue; + + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = NOSQUARE; + + pb[0] = d; + pb[1] = NOSQUARE; + + if (kppk_pctoindex(pw, pb, &i)) { + kppk_indextopc(i, px, py); + kppk_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + +static void +kppk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c; + *----------------------------------------------------------*/ + enum { + B11100 = 7u << 2 + }; + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + index_t a, b, c, r; + index_t m, n; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r; + + m = pp_hi24[a]; + n = pp_lo48[a]; + + pw[0] = (SQUARE) b; + pb[0] = (SQUARE) c; + pb[1] = NOSQUARE; + + pw[1] = pidx24_to_wsq(m); + pw[2] = pidx48_to_wsq(n); + + pw[3] = NOSQUARE; + + + assert (A2 <= pw[1] && pw[1] < A8); + assert (A2 <= pw[2] && pw[2] < A8); + +#ifdef DEBUG + if (!(kppk_pctoindex (pw, pb, &a) && a == i)) { + pc_t wp[] = {KING, PAWN, PAWN, NOPIECE}; + pc_t bp[] = {KING, NOPIECE}; + printf("Indexes not matching: input:%d, output:%d\n", i, a); + print_pos (pw, pb, wp, bp); + } +#endif + + assert (kppk_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kppk_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + index_t pp_slice; + SQUARE anchor, loosen; + + SQUARE wk = pw[0]; + SQUARE pawn_a = pw[1]; + SQUARE pawn_b = pw[2]; + SQUARE bk = pb[0]; + index_t i, j; + +#ifdef DEBUG + if (!(A2 <= pawn_a && pawn_a < A8)) { + printf ("\n\nsquare of pawn_a: %s\n", Square_str[pawn_a]); + printf(" wk %s\n p1 %s\n p2 %s\n bk %s\n" + , Square_str[wk] + , Square_str[pawn_a] + , Square_str[pawn_b] + , Square_str[bk] + ); + } +#endif + + assert (A2 <= pawn_a && pawn_a < A8); + assert (A2 <= pawn_b && pawn_b < A8); + + pp_putanchorfirst(pawn_a, pawn_b, &anchor, &loosen); + + if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + anchor = flipWE(anchor); + loosen = flipWE(loosen); + wk = flipWE(wk); + bk = flipWE(bk); + } + + i = wsq_to_pidx24(anchor); + j = wsq_to_pidx48(loosen); + + pp_slice = ppidx[i][j]; + + if (IDX_is_empty(pp_slice)) { + *out = NOINDEX; + return FALSE; + } + + assert (pp_slice < MAX_PPINDEX); + + *out = pp_slice * BLOCK_A + (index_t) wk * BLOCK_B + (index_t) bk; + + return TRUE; +} + +/****************** end KPP/K ************************************/ + +static void +kakp_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + enum { + B11100 = 7u << 2 + }; + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t a, b, c, d, r; + index_t x; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + /* x is pslice */ + x = a; + x += x & B11100; /* get upper part and double it */ + x += 8; /* add extra row */ +/* x ^= 070; */ /* flip NS */ + + pw[0] = (SQUARE) b; + pb[0] = (SQUARE) c; + pw[1] = (SQUARE) d; + pb[1] = (SQUARE) x; + pw[2] = NOSQUARE; + pb[2] = NOSQUARE; + + assert (kakp_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kakp_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t pslice; + SQUARE sq; + SQUARE pawn = pb[1]; + SQUARE wa = pw[1]; + SQUARE wk = pw[0]; + SQUARE bk = pb[0]; + + assert (A2 <= pawn && pawn < A8); + + if (!(A2 <= pawn && pawn < A8)) { + *out = NOINDEX; + return FALSE; + } + + if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + pawn = flipWE(pawn); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + } + + sq = pawn; + /*sq ^= 070;*/ /* flipNS*/ + sq -= 8; /* down one row*/ + pslice = (index_t) ((sq + (sq & 3)) >> 1); + + *out = pslice * BLOCK_A + (index_t) wk * BLOCK_B + (index_t) bk * BLOCK_C + (index_t) wa; + + return TRUE; +} + + +static void +kapk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + enum { + B11100 = 7u << 2 + }; + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t a, b, c, d, r; + index_t x; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + /* x is pslice */ + x = a; + x += x & B11100; /* get upper part and double it */ + x += 8; /* add extra row */ + x ^= 070; /* flip NS */ + + pw[0] = (SQUARE) b; + pb[0] = (SQUARE) c; + pw[1] = (SQUARE) d; + pw[2] = (SQUARE) x; + pw[3] = NOSQUARE; + pb[1] = NOSQUARE; + + assert (kapk_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kapk_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t pslice; + SQUARE sq; + SQUARE pawn = pw[2]; + SQUARE wa = pw[1]; + SQUARE wk = pw[0]; + SQUARE bk = pb[0]; + + assert (A2 <= pawn && pawn < A8); + + if (!(A2 <= pawn && pawn < A8)) { + *out = NOINDEX; + return FALSE; + } + + if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + pawn = flipWE(pawn); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + } + + sq = pawn; + sq ^= 070; /* flipNS*/ + sq -= 8; /* down one row*/ + pslice = (index_t) ((sq + (sq & 3)) >> 1); + + *out = pslice * BLOCK_A + (index_t) wk * BLOCK_B + (index_t) bk * BLOCK_C + (index_t) wa; + + return TRUE; +} + + +static void +kaak_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + enum { + BLOCK_A = MAX_AAINDEX + }; + index_t a, b, r, x, y; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r; + + assert (i == (a * BLOCK_A + b)); + + pw[0] = wksq[a]; + pb[0] = bksq[a]; + + x = aabase[b]; + y = (b + 1) + x - (x * (127 - x) / 2); + + pw[1] = (SQUARE) x; + pw[2] = (SQUARE) y; + pw[3] = NOSQUARE; + + pb[1] = NOSQUARE; + + assert (kaak_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kaak_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out) { + enum { + N_WHITE = 3, N_BLACK = 1 + }; + enum { + BLOCK_A = MAX_AAINDEX + }; + SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE]; + index_t ki, ai; + unsigned int ft; + SQUARE i; + + ft = flipt[inp_pb[0]][inp_pw[0]]; + + assert (ft < 8); + + for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; + ws[N_WHITE] = NOSQUARE; + for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; + bs[N_BLACK] = NOSQUARE; + + if ((ft & WE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipWE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipWE(bs[i]); + } + + if ((ft & NS_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNS(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNS(bs[i]); + } + + if ((ft & NW_SE_FLAG) != 0) { + for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE(ws[i]); + for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE(bs[i]); + } + + ki = kkidx[bs[0]][ws[0]]; /* kkidx [black king] [white king] */ + ai = (index_t) aaidx[ws[1]][ws[2]]; + + if (IDX_is_empty(ki) || IDX_is_empty(ai)) { + *out = NOINDEX; + return FALSE; + } + *out = ki * BLOCK_A + ai; + return TRUE; +} + +/********************** KPP/KA ************************************/ + +static bool_t test_kppka(void); + +static bool_t kppka_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kppka_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kppka(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kppka"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (c <= H1 || c >= A8) + continue; + if (b <= H1 || b >= A8) + continue; + + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = NOSQUARE; + + pb[0] = e; + pb[1] = d; + pb[2] = NOSQUARE; + + if (kppka_pctoindex(pw, pb, &i)) { + kppka_indextopc(i, px, py); + kppka_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + + +static void +kppka_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t a, b, c, d, r; + index_t m, n; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + m = pp_hi24[a]; + n = pp_lo48[a]; + + pw[0] = (SQUARE) b; + pw[1] = pidx24_to_wsq(m); + pw[2] = pidx48_to_wsq(n); + pw[3] = NOSQUARE; + + pb[0] = (SQUARE) c; + pb[1] = (SQUARE) d; + pb[2] = NOSQUARE; + + + assert (A2 <= pw[1] && pw[1] < A8); + assert (A2 <= pw[2] && pw[2] < A8); + assert (kppka_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kppka_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t pp_slice; + index_t i, j; + + SQUARE anchor, loosen; + + SQUARE wk = pw[0]; + SQUARE pawn_a = pw[1]; + SQUARE pawn_b = pw[2]; + SQUARE bk = pb[0]; + SQUARE ba = pb[1]; + + + assert (A2 <= pawn_a && pawn_a < A8); + assert (A2 <= pawn_b && pawn_b < A8); + + pp_putanchorfirst(pawn_a, pawn_b, &anchor, &loosen); + + if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + anchor = flipWE(anchor); + loosen = flipWE(loosen); + wk = flipWE(wk); + bk = flipWE(bk); + ba = flipWE(ba); + } + + i = wsq_to_pidx24(anchor); + j = wsq_to_pidx48(loosen); + + pp_slice = ppidx[i][j]; + + if (IDX_is_empty(pp_slice)) { + *out = NOINDEX; + return FALSE; + } + + assert (pp_slice < MAX_PPINDEX); + + *out = pp_slice * (index_t) BLOCK_A + (index_t) wk * (index_t) BLOCK_B + (index_t) bk * (index_t) BLOCK_C + + (index_t) ba; + + return TRUE; +} + +/********************** end KPP/KA ************************************/ + +/********************** KAPP/K ************************************/ + +static bool_t test_kappk(void); + +static bool_t kappk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kappk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kappk(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kappk"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (c <= H1 || c >= A8) + continue; + if (b <= H1 || b >= A8) + continue; + + + pw[0] = a; + pw[1] = d; + pw[2] = b; + pw[3] = c; + pw[4] = NOSQUARE; + + pb[0] = e; + pb[1] = NOSQUARE; + + if (kappk_pctoindex(pw, pb, &i)) { + kappk_indextopc(i, px, py); + kappk_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + + +static void +kappk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t a, b, c, d, r; + index_t m, n; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + m = pp_hi24[a]; + n = pp_lo48[a]; + + pw[0] = (SQUARE) b; + pw[1] = (SQUARE) d; + pw[2] = pidx24_to_wsq(m); + pw[3] = pidx48_to_wsq(n); + pw[4] = NOSQUARE; + + pb[0] = (SQUARE) c; + pb[1] = NOSQUARE; + + + assert (A2 <= pw[3] && pw[3] < A8); + assert (A2 <= pw[2] && pw[2] < A8); + assert (kappk_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kappk_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t pp_slice; + SQUARE anchor, loosen; + + SQUARE wk = pw[0]; + SQUARE wa = pw[1]; + SQUARE pawn_a = pw[2]; + SQUARE pawn_b = pw[3]; + SQUARE bk = pb[0]; + + index_t i, j; + + assert (A2 <= pawn_a && pawn_a < A8); + assert (A2 <= pawn_b && pawn_b < A8); + + pp_putanchorfirst(pawn_a, pawn_b, &anchor, &loosen); + + if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + anchor = flipWE(anchor); + loosen = flipWE(loosen); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + } + + i = wsq_to_pidx24(anchor); + j = wsq_to_pidx48(loosen); + + pp_slice = ppidx[i][j]; + + if (IDX_is_empty(pp_slice)) { + *out = NOINDEX; + return FALSE; + } + + assert (pp_slice < MAX_PPINDEX); + + *out = pp_slice * (index_t) BLOCK_A + (index_t) wk * (index_t) BLOCK_B + (index_t) bk * (index_t) BLOCK_C + + (index_t) wa; + + return TRUE; +} + +/********************** end KAPP/K ************************************/ + +/********************** KAPP/K ************************************/ + +static bool_t test_kapkp(void); + +static bool_t kapkp_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kapkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kapkp(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kapkp"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (c <= H1 || c >= A8) + continue; + if (b <= H1 || b >= A8) + continue; + + + pw[0] = a; + pw[1] = d; + pw[2] = b; + pw[3] = NOSQUARE; + + pb[0] = e; + pb[1] = c; + pb[2] = NOSQUARE; + + if (kapkp_pctoindex(pw, pb, &i)) { + kapkp_indextopc(i, px, py); + kapkp_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + + +static bool_t +kapkp_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t pp_slice; + SQUARE anchor, loosen; + + SQUARE wk = pw[0]; + SQUARE wa = pw[1]; + SQUARE pawn_a = pw[2]; + SQUARE bk = pb[0]; + SQUARE pawn_b = pb[1]; + index_t m, n; + + assert (A2 <= pawn_a && pawn_a < A8); + assert (A2 <= pawn_b && pawn_b < A8); + assert (pw[3] == NOSQUARE && pb[2] == NOSQUARE); + + anchor = pawn_a; + loosen = pawn_b; + + if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + anchor = flipWE(anchor); + loosen = flipWE(loosen); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + } + + m = wsq_to_pidx24(anchor); + n = (index_t) loosen - 8; + + pp_slice = m * 48 + n; + + if (IDX_is_empty(pp_slice)) { + *out = NOINDEX; + return FALSE; + } + + assert (pp_slice < (64 * MAX_PpINDEX)); + + *out = pp_slice * (index_t) BLOCK_A + (index_t) wk * (index_t) BLOCK_B + (index_t) bk * (index_t) BLOCK_C + + (index_t) wa; + + return TRUE; +} + +static void +kapkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + enum { + BLOCK_A = 64 * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + enum { + block_m = 48 + }; + index_t a, b, c, d, r; + index_t m, n; + SQUARE sq_m, sq_n; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + /* unpack a, which is pslice, into m and n */ + r = a; + m = r / block_m; + r -= m * block_m; + n = r; + + sq_m = pidx24_to_wsq(m); + sq_n = (SQUARE) n + 8; + + pw[0] = (SQUARE) b; + pb[0] = (SQUARE) c; + pw[1] = (SQUARE) d; + pw[2] = sq_m; + pb[1] = sq_n; + pw[3] = NOSQUARE; + pb[2] = NOSQUARE; + + assert (A2 <= sq_m && sq_m < A8); + assert (A2 <= sq_n && sq_n < A8); + assert (kapkp_pctoindex(pw, pb, &a) && a == i); + + return; +} + +/********************** end KAP/KP ************************************/ + +/********************** KABP/K ************************************/ + +static bool_t test_kabpk(void); + +static bool_t kabpk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kabpk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kabpk(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kabpk"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (d <= H1 || d >= A8) + continue; + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = d; + pw[4] = NOSQUARE; + + pb[0] = e; + pb[1] = NOSQUARE; + + if (kabpk_pctoindex(pw, pb, &i)) { + kabpk_indextopc(i, px, py); + kabpk_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + + +static void +kabpk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e; + *----------------------------------------------------------*/ + enum { + BLOCK_A = 64 * 64 * 64 * 64, BLOCK_B = 64 * 64 * 64, BLOCK_C = 64 * 64, BLOCK_D = 64 + }; + index_t a, b, c, d, e, r; + SQUARE x; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r / BLOCK_D; + r -= d * BLOCK_D; + e = r; + + x = pidx24_to_wsq(a); + + pw[0] = (SQUARE) b; + pw[1] = (SQUARE) d; + pw[2] = (SQUARE) e; + pw[3] = x; + pw[4] = NOSQUARE; + + pb[0] = (SQUARE) c; + pb[1] = NOSQUARE; + + assert (kabpk_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kabpk_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64 * 64 * 64, BLOCK_B = 64 * 64 * 64, BLOCK_C = 64 * 64, BLOCK_D = 64 + }; + index_t pslice; + + SQUARE wk = pw[0]; + SQUARE wa = pw[1]; + SQUARE wb = pw[2]; + SQUARE pawn = pw[3]; + SQUARE bk = pb[0]; + + assert (A2 <= pawn && pawn < A8); + + if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + pawn = flipWE(pawn); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + wb = flipWE(wb); + } + + pslice = wsq_to_pidx24(pawn); + + *out = pslice * (index_t) BLOCK_A + (index_t) wk * (index_t) BLOCK_B + (index_t) bk * (index_t) BLOCK_C + + (index_t) wa * (index_t) BLOCK_D + (index_t) wb; + + return TRUE; +} + +/********************** end KABP/K ************************************/ + +/********************** KAAP/K ************************************/ + +static bool_t test_kaapk(void); + +static bool_t kaapk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kaapk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kaapk(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kaapk"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (d <= H1 || d >= A8) + continue; + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = d; + pw[4] = NOSQUARE; + + pb[0] = e; + pb[1] = NOSQUARE; + + if (kaapk_pctoindex(pw, pb, &i)) { + kaapk_indextopc(i, px, py); + kaapk_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + + +static void +kaapk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + enum { + BLOCK_C = MAX_AAINDEX, BLOCK_B = 64 * BLOCK_C, BLOCK_A = 64 * BLOCK_B + }; + index_t a, b, c, d, r; + index_t x, y, z; + + assert (i >= 0); + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + z = (index_t) pidx24_to_wsq(a); + + /* split d into x, y*/ + x = aabase[d]; + y = (d + 1) + x - (x * (127 - x) / 2); + + assert (aaidx[x][y] == aaidx[y][x]); + assert (aaidx[x][y] == d); + + + pw[0] = (SQUARE) b; + pw[1] = (SQUARE) x; + pw[2] = (SQUARE) y; + pw[3] = (SQUARE) z; + pw[4] = NOSQUARE; + + pb[0] = (SQUARE) c; + pb[1] = NOSQUARE; + + assert (kaapk_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kaapk_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_C = MAX_AAINDEX, BLOCK_B = 64 * BLOCK_C, BLOCK_A = 64 * BLOCK_B + }; + index_t aa_combo, pslice; + + SQUARE wk = pw[0]; + SQUARE wa = pw[1]; + SQUARE wa2 = pw[2]; + SQUARE pawn = pw[3]; + SQUARE bk = pb[0]; + + assert (A2 <= pawn && pawn < A8); + + if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + pawn = flipWE(pawn); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + wa2 = flipWE(wa2); + } + + pslice = wsq_to_pidx24(pawn); + + aa_combo = (index_t) aaidx[wa][wa2]; + + if (IDX_is_empty(aa_combo)) { + *out = NOINDEX; + return FALSE; + } + + *out = pslice * (index_t) BLOCK_A + (index_t) wk * (index_t) BLOCK_B + (index_t) bk * (index_t) BLOCK_C + aa_combo; + + assert (*out >= 0); + + return TRUE; +} + +/********************** end KAAP/K ************************************/ + +/********************** KAA/KP ************************************/ + +static bool_t test_kaakp(void); + +static bool_t kaakp_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kaakp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static bool_t +test_kaakp(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kaakp"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (d <= H1 || d >= A8) + continue; + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = NOSQUARE; + + pb[0] = e; + pb[1] = d; + pb[2] = NOSQUARE; + + if (kaakp_pctoindex(pw, pb, &i)) { + kaakp_indextopc(i, px, py); + kaakp_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + + +static void +kaakp_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + enum { + BLOCK_C = MAX_AAINDEX, BLOCK_B = 64 * BLOCK_C, BLOCK_A = 64 * BLOCK_B + }; + index_t a, b, c, d, r; + index_t x, y, z; + SQUARE zq; + + assert (i >= 0); + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + zq = pidx24_to_wsq(a); + z = (index_t) flipNS(zq); + + + /* split d into x, y*/ + x = aabase[d]; + y = (d + 1) + x - (x * (127 - x) / 2); + + assert (aaidx[x][y] == aaidx[y][x]); + assert (aaidx[x][y] == d); + + + pw[0] = (SQUARE) b; + pw[1] = (SQUARE) x; + pw[2] = (SQUARE) y; + pw[3] = NOSQUARE; + + pb[0] = (SQUARE) c; + pb[1] = (SQUARE) z; + pb[2] = NOSQUARE; + + assert (kaakp_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kaakp_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_C = MAX_AAINDEX, BLOCK_B = 64 * BLOCK_C, BLOCK_A = 64 * BLOCK_B + }; + index_t aa_combo, pslice; + + SQUARE wk = pw[0]; + SQUARE wa = pw[1]; + SQUARE wa2 = pw[2]; + SQUARE bk = pb[0]; + SQUARE pawn = pb[1]; + + assert (A2 <= pawn && pawn < A8); + + if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + pawn = flipWE(pawn); + wk = flipWE(wk); + bk = flipWE(bk); + wa = flipWE(wa); + wa2 = flipWE(wa2); + } + + pawn = flipNS(pawn); + pslice = wsq_to_pidx24(pawn); + + aa_combo = (index_t) aaidx[wa][wa2]; + + if (IDX_is_empty(aa_combo)) { + *out = NOINDEX; + return FALSE; + } + + *out = pslice * (index_t) BLOCK_A + (index_t) wk * (index_t) BLOCK_B + (index_t) bk * (index_t) BLOCK_C + aa_combo; + + assert (*out >= 0); + + return TRUE; +} + +/********************** end KAA/KP ************************************/ + +/********************** KPP/KP ************************************/ +/* +index_t pp48_idx[48][48]; +sq_t pp48_sq_x[MAX_PP48_INDEX]; +sq_t pp48_sq_y[MAX_PP48_INDEX]; +*/ +static bool_t test_kppkp(void); + +static bool_t kppkp_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kppkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static sq_t map24_b(sq_t s); + +static sq_t unmap24_b(index_t i); + +static index_t +init_pp48_idx(void) +/* modifies pp48_idx[][], pp48_sq_x[], pp48_sq_y[] */ +{ + enum { + MAX_I = 48, MAX_J = 48 + }; + SQUARE i, j; + index_t idx = 0; + SQUARE a, b; + + /* default is noindex */ + for (i = 0; i < MAX_I; i++) { + for (j = 0; j < MAX_J; j++) { + IDX_set_empty (pp48_idx[i][j]); + } + } + + for (idx = 0; idx < MAX_PP48_INDEX; idx++) { + pp48_sq_x[idx] = NOSQUARE; + pp48_sq_y[idx] = NOSQUARE; + } + + idx = 0; + for (a = H7; a >= A2; a--) { + + for (b = a - 1; b >= A2; b--) { + + i = flipWE(flipNS(a)) - 8; + j = flipWE(flipNS(b)) - 8; + + if (IDX_is_empty(pp48_idx[i][j])) { + + pp48_idx[i][j] = idx; + assert (idx < MAX_PP48_INDEX); + pp48_idx[j][i] = idx; + pp48_sq_x[idx] = i; + assert (i < MAX_I); + pp48_sq_y[idx] = j; + assert (j < MAX_J); + idx++; + } + } + } + assert (idx == MAX_PP48_INDEX); + return idx; +} + + +static bool_t +test_kppkp(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kppkp"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (c <= H1 || c >= A8) + continue; + if (b <= H1 || b >= A8) + continue; + if (d <= H1 || d >= A8) + continue; + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = NOSQUARE; + + pb[0] = e; + pb[1] = d; + pb[2] = NOSQUARE; + + if (kppkp_pctoindex(pw, pb, &i)) { + kppkp_indextopc(i, px, py); + kppkp_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + + +static void +kppkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + + enum { + BLOCK_A = MAX_PP48_INDEX * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t a, b, c, d, r; + SQUARE m, n; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r / BLOCK_C; + r -= c * BLOCK_C; + d = r; + + m = pp48_sq_x[b]; + n = pp48_sq_y[b]; + + pw[0] = (SQUARE) c; + pw[1] = flipWE(flipNS(m + 8)); + pw[2] = flipWE(flipNS(n + 8)); + pw[3] = NOSQUARE; + + pb[0] = (SQUARE) d; + pb[1] = (SQUARE) unmap24_b(a); + pb[2] = NOSQUARE; + + + assert (A2 <= pw[1] && pw[1] < A8); + assert (A2 <= pw[2] && pw[2] < A8); + assert (A2 <= pb[1] && pb[1] < A8); + assert (kppkp_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kppkp_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = MAX_PP48_INDEX * 64 * 64, BLOCK_B = 64 * 64, BLOCK_C = 64 + }; + index_t pp48_slice; + + SQUARE wk = pw[0]; + SQUARE pawn_a = pw[1]; + SQUARE pawn_b = pw[2]; + SQUARE bk = pb[0]; + SQUARE pawn_c = pb[1]; + SQUARE i, j, k; + + assert (A2 <= pawn_a && pawn_a < A8); + assert (A2 <= pawn_b && pawn_b < A8); + assert (A2 <= pawn_c && pawn_c < A8); + + if ((pawn_c & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + wk = flipWE(wk); + pawn_a = flipWE(pawn_a); + pawn_b = flipWE(pawn_b); + bk = flipWE(bk); + pawn_c = flipWE(pawn_c); + } + + i = flipWE(flipNS(pawn_a)) - 8; + j = flipWE(flipNS(pawn_b)) - 8; + k = map24_b(pawn_c); /* black pawn, so low indexes mean more advanced 0 == A2 */ + + pp48_slice = pp48_idx[i][j]; + + if (IDX_is_empty(pp48_slice)) { + *out = NOINDEX; + return FALSE; + } + + assert (pp48_slice < MAX_PP48_INDEX); + + *out = (index_t) k * (index_t) BLOCK_A + pp48_slice * (index_t) BLOCK_B + (index_t) wk * (index_t) BLOCK_C + + (index_t) bk; + + return TRUE; +} + +static sq_t +map24_b(sq_t s) { + s -= 8; + return ((s & 3) + s) >> 1; +} + +static sq_t +unmap24_b(index_t i) { + return (sq_t) ((i & (4 + 8 + 16)) + i + 8); +} + +/********************** end KPP/KP ************************************/ + +/********************** KPPP/K ************************************/ + +static const sq_t itosq[48] = { + H7, G7, F7, E7, + H6, G6, F6, E6, + H5, G5, F5, E5, + H4, G4, F4, E4, + H3, G3, F3, E3, + H2, G2, F2, E2, + D7, C7, B7, A7, + D6, C6, B6, A6, + D5, C5, B5, A5, + D4, C4, B4, A4, + D3, C3, B3, A3, + D2, C2, B2, A2 +}; + +static bool_t test_kpppk(void); + +static bool_t kpppk_pctoindex(const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out); + +static void kpppk_indextopc(index_t i, SQUARE *pw, SQUARE *pb); + +static index_t +init_ppp48_idx(void) +/* modifies ppp48_idx[][], ppp48_sq_x[], ppp48_sq_y[], ppp48_sq_z[] */ +{ + enum { + MAX_I = 48, MAX_J = 48, MAX_K = 48 + }; + SQUARE i, j, k; + index_t idx = 0; + SQUARE a, b, c; + int x, y, z; + + /* default is noindex */ + for (i = 0; i < MAX_I; i++) { + for (j = 0; j < MAX_J; j++) { + for (k = 0; k < MAX_K; k++) { + IDX_set_empty(ppp48_idx[i][j][k]); + } + } + } + + for (idx = 0; idx < MAX_PPP48_INDEX; idx++) { + ppp48_sq_x[idx] = (uint8_t) NOSQUARE; + ppp48_sq_y[idx] = (uint8_t) NOSQUARE; + ppp48_sq_z[idx] = (uint8_t) NOSQUARE; + } + + idx = 0; + for (x = 0; x < 48; x++) { + for (y = x + 1; y < 48; y++) { + for (z = y + 1; z < 48; z++) { + + a = itosq[x]; + b = itosq[y]; + c = itosq[z]; + + if (!in_queenside(b) || !in_queenside(c)) + continue; + + i = a - 8; + j = b - 8; + k = c - 8; + + if (IDX_is_empty(ppp48_idx[i][j][k])) { + + ppp48_idx[i][j][k] = idx; + ppp48_idx[i][k][j] = idx; + ppp48_idx[j][i][k] = idx; + ppp48_idx[j][k][i] = idx; + ppp48_idx[k][i][j] = idx; + ppp48_idx[k][j][i] = idx; + ppp48_sq_x[idx] = (uint8_t) i; + assert (i < MAX_I); + ppp48_sq_y[idx] = (uint8_t) j; + assert (j < MAX_J); + ppp48_sq_z[idx] = (uint8_t) k; + assert (k < MAX_K); + idx++; + } + } + } + } + +/* assert (idx == MAX_PPP48_INDEX);*/ + return idx; +} + +static bool_t +test_kpppk(void) { + + enum { + MAXPC = 16 + 1 + }; + char str[] = "kpppk"; + SQUARE a, b, c, d, e; + SQUARE pw[MAXPC], pb[MAXPC]; + SQUARE px[MAXPC], py[MAXPC]; + + index_t i, j; + bool_t err = FALSE; + + printf("%8s ", str); + + for (a = 0; a < 64; a++) { + for (b = 0; b < 64; b++) { + for (c = 0; c < 64; c++) { + for (d = 0; d < 64; d++) { + for (e = 0; e < 64; e++) { + + if (c <= H1 || c >= A8) + continue; + if (b <= H1 || b >= A8) + continue; + if (d <= H1 || d >= A8) + continue; + + pw[0] = a; + pw[1] = b; + pw[2] = c; + pw[3] = d; + pw[4] = NOSQUARE; + + pb[0] = e; + pb[1] = NOSQUARE; + + if (kpppk_pctoindex(pw, pb, &i)) { + kpppk_indextopc(i, px, py); + kpppk_pctoindex(px, py, &j); + if (i != j) { + err = TRUE; + } + assert (i == j); + } + + } + } + } + } + + if ((a & 1) == 0) { + printf("."); + fflush(stdout); + } + } + + if (err) + printf("> %s NOT passed\n", str); + else + printf("> %s PASSED\n", str); + return !err; +} + + +static void +kpppk_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d; + *----------------------------------------------------------*/ + + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + index_t a, b, c, r; + SQUARE m, n, o; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r; + + m = ppp48_sq_x[a]; + n = ppp48_sq_y[a]; + o = ppp48_sq_z[a]; + + + pw[0] = (SQUARE) b; + pw[1] = m + 8; + pw[2] = n + 8; + pw[3] = o + 8; + pw[4] = NOSQUARE; + + pb[0] = (SQUARE) c; + pb[1] = NOSQUARE; + + + assert (A2 <= pw[1] && pw[1] < A8); + assert (A2 <= pw[2] && pw[2] < A8); + assert (A2 <= pw[3] && pw[3] < A8); + assert (kpppk_pctoindex(pw, pb, &a) && a == i); + + return; +} + + +static bool_t +kpppk_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + index_t ppp48_slice; + + SQUARE wk = pw[0]; + SQUARE pawn_a = pw[1]; + SQUARE pawn_b = pw[2]; + SQUARE pawn_c = pw[3]; + + SQUARE bk = pb[0]; + + SQUARE i, j, k; + + assert (A2 <= pawn_a && pawn_a < A8); + assert (A2 <= pawn_b && pawn_b < A8); + assert (A2 <= pawn_c && pawn_c < A8); + + i = pawn_a - 8; + j = pawn_b - 8; + k = pawn_c - 8; + + ppp48_slice = ppp48_idx[i][j][k]; + + if (IDX_is_empty(ppp48_slice)) { + wk = flipWE(wk); + pawn_a = flipWE(pawn_a); + pawn_b = flipWE(pawn_b); + pawn_c = flipWE(pawn_c); + bk = flipWE(bk); + } + + i = pawn_a - 8; + j = pawn_b - 8; + k = pawn_c - 8; + + ppp48_slice = ppp48_idx[i][j][k]; + + if (IDX_is_empty(ppp48_slice)) { + *out = NOINDEX; + return FALSE; + } + + assert (ppp48_slice < MAX_PPP48_INDEX); + + *out = (index_t) ppp48_slice * BLOCK_A + (index_t) wk * BLOCK_B + (index_t) bk; + + return TRUE; +} + + +/********************** end KPPP/K ************************************/ + + +static bool_t +kpkp_pctoindex(const SQUARE *pw, const SQUARE *pb, index_t *out) { + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + SQUARE pp_slice; + SQUARE anchor, loosen; + + SQUARE wk = pw[0]; + SQUARE bk = pb[0]; + SQUARE pawn_a = pw[1]; + SQUARE pawn_b = pb[1]; + + SQUARE m, n; + +#ifdef DEBUG + if (!(A2 <= pawn_a && pawn_a < A8)) { + printf ("\n\nsquare of pawn_a: %s\n", Square_str[pawn_a]); + printf(" wk %s\n p1 %s\n p2 %s\n bk %s\n" + , Square_str[wk] + , Square_str[pawn_a] + , Square_str[pawn_b] + , Square_str[bk] + ); + } +#endif + + assert (A2 <= pawn_a && pawn_a < A8); + assert (A2 <= pawn_b && pawn_b < A8); + assert (pw[2] == NOSQUARE && pb[2] == NOSQUARE); + + /*pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen);*/ + anchor = pawn_a; + loosen = pawn_b; + + if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */ + anchor = flipWE(anchor); + loosen = flipWE(loosen); + wk = flipWE(wk); + bk = flipWE(bk); + } + + m = (SQUARE) wsq_to_pidx24(anchor); + n = loosen - 8; + + pp_slice = m * 48 + n; + + if (IDX_is_empty(pp_slice)) { + *out = NOINDEX; + return FALSE; + } + + assert (pp_slice < MAX_PpINDEX); + + *out = (index_t) (pp_slice * BLOCK_A + wk * BLOCK_B + bk); + + return TRUE; +} + + +static void +kpkp_indextopc(index_t i, SQUARE *pw, SQUARE *pb) { + /*---------------------------------------------------------* + inverse work to make sure that the following is valid + index = a * BLOCK_A + b * BLOCK_B + c; + *----------------------------------------------------------*/ + enum { + B11100 = 7u << 2 + }; + enum { + BLOCK_A = 64 * 64, BLOCK_B = 64 + }; + enum { + block_m = 48 + }; + index_t a, b, c, r; + index_t m, n; + SQUARE sq_m, sq_n; + + r = i; + a = r / BLOCK_A; + r -= a * BLOCK_A; + b = r / BLOCK_B; + r -= b * BLOCK_B; + c = r; + + /* unpack a, which is pslice, into m and n */ + r = a; + m = r / block_m; + r -= m * block_m; + n = r; + + sq_m = pidx24_to_wsq(m); + sq_n = (SQUARE) n + 8; + + pw[0] = (SQUARE) b; + pb[0] = (SQUARE) c; + pw[1] = sq_m; + pb[1] = sq_n; + pw[2] = NOSQUARE; + pb[2] = NOSQUARE; + + assert (A2 <= pw[1] && pw[1] < A8); + assert (A2 <= pb[1] && pb[1] < A8); + + return; +} + + +/****************************************************************************\ + * + * + * DEBUG ZONE + * + * + ****************************************************************************/ + +#if defined(DEBUG) + static void +print_pos (const sq_t *ws, const sq_t *bs, const pc_t *wp, const pc_t *bp) +{ + int i; + printf ("White: "); + for (i = 0; ws[i] != NOSQUARE; i++) { + printf ("%s%s ", P_str[wp[i]], Square_str[ws[i]]); + } + printf ("\nBlack: "); + for (i = 0; bs[i] != NOSQUARE; i++) { + printf ("%s%s ", P_str[bp[i]], Square_str[bs[i]]); + } + printf ("\n"); +} +#endif + +#if defined(DEBUG) || defined(FOLLOW_EGTB) + static void +output_state (unsigned stm, const SQUARE *wSQ, const SQUARE *bSQ, + const SQ_CONTENT *wPC, const SQ_CONTENT *bPC) +{ + int i; + assert (stm == WH || stm == BL); + + printf("\n%s to move\n", stm==WH?"White":"Black"); + printf("W: "); + for (i = 0; wSQ[i] != NOSQUARE; i++) { + printf("%s%s ", P_str[wPC[i]], Square_str[wSQ[i]]); + } + printf("\n"); + printf("B: "); + for (i = 0; bSQ[i] != NOSQUARE; i++) { + printf("%s%s ", P_str[bPC[i]], Square_str[bSQ[i]]); + } + printf("\n\n"); +} +#endif + +static void +list_index(void) { + enum { + START_GTB = 0, END_GTB = (MAX_EGKEYS) + }; + int i; + index_t accum = 0; + printf("\nIndex for each GTB\n"); + printf("%3s: %7s %7s %7s %7s\n", "i", "TB", "RAM-slice", "RAM-max", "HD-cumulative"); + for (i = START_GTB; i < END_GTB; i++) { + index_t indiv_k = egkey[i].maxindex * (index_t) sizeof(dtm_t) * 2 / 1024; + accum += indiv_k; + printf("%3d: %7s %8luk %8luk %8luM\n", i, egkey[i].str, (long unsigned) (indiv_k / egkey[i].slice_n), + (long unsigned) indiv_k, (long unsigned) accum / 1024 / 2); + } + printf("\n"); + return; +} + +/************************************************************************************************************** + + NEW_WDL + +**************************************************************************************************************/ + +/*---------------------------------------------------------------------*\ +| WDL CACHE Implementation ZONE +\*---------------------------------------------------------------------*/ + +/* +| WDL CACHE Statics +\*---------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +static unsigned int wdl_extract(unit_t *uarr, index_t x); + +static wdl_block_t *wdl_point_block_to_replace(void); + +static void wdl_movetotop(wdl_block_t *t); + +#if 0 + static bool_t wdl_cache_init (size_t cache_mem); +static void wdl_cache_flush (void); +static bool_t get_WDL (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag); +#endif + +static bool_t wdl_cache_is_on(void); + +static void wdl_cache_reset_counters(void); + +static void wdl_cache_done(void); + +static wdl_block_t *wdl_point_block_to_replace(void); + +static bool_t get_WDL_from_cache(tbkey_t key, unsigned side, index_t idx, unsigned int *out); + +static void wdl_movetotop(wdl_block_t *t); + +static bool_t wdl_preload_cache(tbkey_t key, unsigned side, index_t idx); + +/*--------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------*\ +| WDL CACHE Maintainance +\*---------------------------------------------------------------------*/ + + +static size_t +wdl_cache_init(size_t cache_mem) { + unsigned int i; + wdl_block_t *p; + size_t entries_per_block; + size_t max_blocks; + size_t block_mem; + + if (WDL_CACHE_INITIALIZED) + wdl_cache_done(); + + entries_per_block = 16 * 1024; /* fixed, needed for the compression schemes */ + + WDL_units_per_block = entries_per_block / WDL_entries_per_unit; + block_mem = WDL_units_per_block * sizeof(unit_t); + + max_blocks = cache_mem / block_mem; + cache_mem = max_blocks * block_mem; + + + wdl_cache_reset_counters(); + + wdl_cache.entries_per_block = entries_per_block; + wdl_cache.max_blocks = max_blocks; + wdl_cache.cached = TRUE; + wdl_cache.top = NULL; + wdl_cache.bot = NULL; + wdl_cache.n = 0; + + if (0 == cache_mem || NULL == (wdl_cache.buffer = (unit_t *) malloc(cache_mem))) { + wdl_cache.cached = FALSE; + return 0; + } + + if (0 == max_blocks || NULL == (wdl_cache.blocks = (wdl_block_t *) malloc(max_blocks * sizeof(wdl_block_t)))) { + wdl_cache.cached = FALSE; + free(wdl_cache.buffer); + return 0; + } + + for (i = 0; i < max_blocks; i++) { + p = &wdl_cache.blocks[i]; + p->key = -1; + p->side = gtbNOSIDE; + p->offset = gtbNOINDEX; + p->p_arr = wdl_cache.buffer + i * WDL_units_per_block; + p->prev = NULL; + p->next = NULL; + } + + wdl_cache.ht_size = 1; + while (wdl_cache.ht_size < max_blocks * 4) + wdl_cache.ht_size *= 2; + wdl_cache.ht_used = 0; + wdl_cache.hash_table = (wdl_block_t **) malloc(wdl_cache.ht_size * sizeof(wdl_block_t *));; + if (wdl_cache.hash_table == NULL) { + wdl_cache.cached = FALSE; + free(wdl_cache.blocks); + wdl_cache.blocks = NULL; + free(wdl_cache.buffer); + wdl_cache.buffer = NULL; + return 0; + } + + for (i = 0; i < wdl_cache.ht_size; i++) { + wdl_cache.hash_table[i] = NULL; + } + + WDL_CACHE_INITIALIZED = TRUE; + + return cache_mem; +} + + +static void +wdl_cache_done(void) { + assert(WDL_CACHE_INITIALIZED); + + wdl_cache.cached = FALSE; + wdl_cache.hard = 0; + wdl_cache.soft = 0; + wdl_cache.hardmisses = 0; + wdl_cache.hits = 0; + wdl_cache.softmisses = 0; + wdl_cache.comparisons = 0; + wdl_cache.max_blocks = 0; + wdl_cache.entries_per_block = 0; + + wdl_cache.top = NULL; + wdl_cache.bot = NULL; + wdl_cache.n = 0; + + if (wdl_cache.buffer != NULL) + free(wdl_cache.buffer); + wdl_cache.buffer = NULL; + + if (wdl_cache.blocks != NULL) + free(wdl_cache.blocks); + wdl_cache.blocks = NULL; + + if (wdl_cache.hash_table != NULL) + free(wdl_cache.hash_table); + wdl_cache.hash_table = NULL; + + WDL_CACHE_INITIALIZED = FALSE; + return; +} + + +static void +wdl_cache_flush(void) { + unsigned int i; + wdl_block_t *p; + size_t max_blocks = wdl_cache.max_blocks; + + wdl_cache.top = NULL; + wdl_cache.bot = NULL; + wdl_cache.n = 0; + + for (i = 0; i < max_blocks; i++) { + p = &wdl_cache.blocks[i]; + p->key = -1; + p->side = gtbNOSIDE; + p->offset = gtbNOINDEX; + p->p_arr = wdl_cache.buffer + i * WDL_units_per_block; + p->prev = NULL; + p->next = NULL; + } + + wdl_cache_reset_counters(); + + return; +} + + +static void +wdl_cache_reset_counters(void) { + wdl_cache.hard = 0; + wdl_cache.soft = 0; + wdl_cache.hardmisses = 0; + wdl_cache.hits = 0; + wdl_cache.softmisses = 0; + wdl_cache.comparisons = 0; + return; +} + + +static bool_t +wdl_cache_is_on(void) { + return wdl_cache.cached; +} + +/****************************************************************************\ +| Replacement +\****************************************************************************/ + +static wdl_block_t * +wdl_point_block_to_replace(void) { + wdl_block_t *p, *t, *s; + + assert (0 == wdl_cache.n || wdl_cache.top != NULL); + assert (0 == wdl_cache.n || wdl_cache.bot != NULL); + assert (0 == wdl_cache.n || wdl_cache.bot->prev == NULL); + assert (0 == wdl_cache.n || wdl_cache.top->next == NULL); + + if (wdl_cache.n > 0 && -1 == wdl_cache.top->key) { + + /* top blocks is unusable, should be the one to replace*/ + p = wdl_cache.top; + + } else if (wdl_cache.n == 0) { + + p = &wdl_cache.blocks[wdl_cache.n++]; + wdl_cache.top = p; + wdl_cache.bot = p; + + p->prev = NULL; + p->next = NULL; + + } else if (wdl_cache.n < wdl_cache.max_blocks) { /* add */ + + s = wdl_cache.top; + p = &wdl_cache.blocks[wdl_cache.n++]; + wdl_cache.top = p; + + s->next = p; + p->prev = s; + p->next = NULL; + + } else { /* replace*/ + + t = wdl_cache.bot; + s = wdl_cache.top; + wdl_cache.bot = t->next; + wdl_cache.top = t; + + s->next = t; + t->prev = s; + wdl_cache.top->next = NULL; + wdl_cache.bot->prev = NULL; + + p = t; + } + + /* make the information content unusable, it will be replaced */ + p->key = -1; + p->side = gtbNOSIDE; + p->offset = gtbNOINDEX; + + return p; +} + +/****************************************************************************\ +| +| NEW PROBING ZONE +| +\****************************************************************************/ + +static unsigned int wdl_extract(unit_t *uarr, index_t x); + +static bool_t get_WDL_from_cache(tbkey_t key, unsigned side, index_t idx, unsigned int *info_out); + +static unsigned dtm2WDL(dtm_t dtm); + +static void wdl_movetotop(wdl_block_t *t); + +static bool_t wdl_preload_cache(tbkey_t key, unsigned side, index_t idx); + +static void dtm_block_2_wdl_block(dtm_block_t *g, wdl_block_t *w, size_t n); + +static bool_t +get_WDL(tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag) { + dtm_t dtm; + bool_t found; + + found = get_WDL_from_cache(key, side, idx, info_out); + + if (found) { + wdl_cache.hits++; + } else { + /* may probe soft */ + found = get_dtm(key, side, idx, &dtm, probe_hard_flag); + if (found) { + *info_out = dtm2WDL(dtm); + /* move cache info from dtm_cache to WDL_cache */ + if (wdl_cache_is_on()) + wdl_preload_cache(key, side, idx); + } + } + + if (probe_hard_flag) { + wdl_cache.hard++; + if (!found) { + wdl_cache.hardmisses++; + } + } else { + wdl_cache.soft++; + if (!found) { + wdl_cache.softmisses++; + } + } + + return found; +} + +static void wdl_hash_insert(wdl_block_t *e); + +static void +wdl_hash_rebuild(void) { + wdl_block_t *p; + size_t i; + + for (i = 0; i < wdl_cache.ht_size; i++) + wdl_cache.hash_table[i] = NULL; + wdl_cache.ht_used = 0; + + for (p = wdl_cache.top; p != NULL; p = p->prev) + wdl_hash_insert(p); +} + +static void +wdl_hash_insert(wdl_block_t *e) { + size_t h1, h2; + + if (wdl_cache.ht_used > wdl_cache.ht_size * 3 / 4) + wdl_hash_rebuild(); + + h1 = hash_func_1(e->key, e->side, e->offset) & (wdl_cache.ht_size - 1); + h2 = hash_func_2(e->key, e->side, e->offset); + while (wdl_cache.hash_table[h1]) + h1 = (h1 + h2) & (wdl_cache.ht_size - 1); + wdl_cache.hash_table[h1] = e; + wdl_cache.ht_used++; +} + +static bool_t +get_WDL_from_cache(tbkey_t key, unsigned side, index_t idx, unsigned int *out) { + index_t offset; + index_t remainder; + wdl_block_t *p; + wdl_block_t *ret; + size_t h1, h2; + + if (!wdl_cache_is_on()) + return FALSE; + + split_index(wdl_cache.entries_per_block, idx, &offset, &remainder); + + ret = NULL; + + h1 = hash_func_1(key, side, offset) & (wdl_cache.ht_size - 1); + h2 = hash_func_2(key, side, offset); + while (1) { + p = wdl_cache.hash_table[h1]; + if (!p) + break; + + wdl_cache.comparisons++; + + if (key == p->key && side == p->side && offset == p->offset) { + ret = p; + break; + } + + h1 = (h1 + h2) & (wdl_cache.ht_size - 1); + } + + if (ret != NULL) { + *out = wdl_extract(ret->p_arr, remainder); + wdl_movetotop(ret); + } + + FOLLOW_LU("get_wdl_from_cache ok?", (ret != NULL)) + + return ret != NULL; +} + +static unsigned int +wdl_extract(unit_t *uarr, index_t x) { + index_t width = 2; + index_t nu = x / WDL_entries_per_unit; + index_t y = x - (nu * WDL_entries_per_unit); + return (uarr[nu] >> (y * width)) & WDL_entry_mask; +} + +static void +wdl_movetotop(wdl_block_t *t) { + wdl_block_t *s, *nx, *pv; + + assert (t != NULL); + + if (t->next == NULL) /* at the top already */ + return; + + /* detach */ + pv = t->prev; + nx = t->next; + + if (pv == NULL) /* at the bottom */ + wdl_cache.bot = nx; + else + pv->next = nx; + + if (nx == NULL) /* at the top */ + wdl_cache.top = pv; + else + nx->prev = pv; + + /* relocate */ + s = wdl_cache.top; + assert (s != NULL); + if (s == NULL) + wdl_cache.bot = t; + else + s->next = t; + + t->next = NULL; + t->prev = s; + wdl_cache.top = t; + + return; +} + +/****************************************************************************************************/ + +static bool_t +wdl_preload_cache(tbkey_t key, unsigned side, index_t idx) +/* output to the least used block of the cache */ +{ + dtm_block_t *dtm_block; + wdl_block_t *to_modify; + bool_t ok; + + FOLLOW_label("wdl preload_cache starts") + + if (idx >= egkey[key].maxindex) { + FOLLOW_LULU("Wrong index", __LINE__, idx) + return FALSE; + } + + /* find fresh block in dtm cache */ + dtm_block = dtm_cache_pointblock(key, side, idx); + + /* find aged blocked in wdl cache */ + to_modify = wdl_point_block_to_replace(); + + ok = !(NULL == dtm_block || NULL == to_modify); + + if (!ok) + return FALSE; + + /* transform and move a block */ + dtm_block_2_wdl_block(dtm_block, to_modify, dtm_cache.entries_per_block); + + if (ok) { + index_t offset; + index_t remainder; + split_index(wdl_cache.entries_per_block, idx, &offset, &remainder); + + to_modify->key = key; + to_modify->side = side; + to_modify->offset = offset; + wdl_hash_insert(to_modify); + } else { + /* make it unusable */ + to_modify->key = -1; + to_modify->side = gtbNOSIDE; + to_modify->offset = gtbNOINDEX; + } + + FOLLOW_LU("wdl preload_cache?", ok) + + return ok; +} + +/****************************************************************************************************/ + +static void +dtm_block_2_wdl_block(dtm_block_t *g, wdl_block_t *w, size_t n) { + int width = 2; + int shifting; + size_t i; + int j; + unsigned int x, y; + dtm_t *s = g->p_arr; + unit_t *d = w->p_arr; + + for (i = 0, y = 0; i < n; i++) { + j = i & 3; /* modulo WDL_entries_per_unit */ + x = dtm2WDL(s[i]); + shifting = j * width; + y |= (x << shifting); + + if (j == 3) { + d[i / WDL_entries_per_unit] = (unit_t) y; + y = 0; + } + } + + if (0 != (n & 3)) { /* not multiple of 4 */ + d[(n - 1) / WDL_entries_per_unit] = (unit_t) y; /* save the rest */ + y = 0; + } + + return; +} + +static unsigned +dtm2WDL(dtm_t dtm) { + return (unsigned) dtm & 3; +} + + +/**************************/ +#ifdef WDL_PROBE + +static unsigned int inv_wdl(unsigned w); + +static bool_t +egtb_get_wdl(tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, unsigned int *wdl); + +static bool_t +tb_probe_wdl + (unsigned stm, + const SQUARE *inp_wSQ, + const SQUARE *inp_bSQ, + const SQ_CONTENT *inp_wPC, + const SQ_CONTENT *inp_bPC, + bool_t probingtype, + /*@out@*/ unsigned *res) { + tbkey_t id = -1; + unsigned int wdl = iUNKNOWN; + + SQUARE storage_ws[MAX_LISTSIZE], storage_bs[MAX_LISTSIZE]; + SQ_CONTENT storage_wp[MAX_LISTSIZE], storage_bp[MAX_LISTSIZE]; + + SQUARE *ws = storage_ws; + SQUARE *bs = storage_bs; + SQ_CONTENT *wp = storage_wp; + SQ_CONTENT *bp = storage_bp; + SQUARE tmp_ws[MAX_LISTSIZE], tmp_bs[MAX_LISTSIZE]; + SQ_CONTENT tmp_wp[MAX_LISTSIZE], tmp_bp[MAX_LISTSIZE]; + + SQUARE *temps; + bool_t straight = FALSE; + + bool_t okcall = TRUE; + unsigned ply_; + unsigned *ply = &ply_; + + /************************************/ + + assert (stm == WH || stm == BL); + + /* VALID ONLY FOR KK!! */ + if (inp_wPC[1] == NOPIECE && inp_bPC[1] == NOPIECE) { + index_t dummy_i; + bool_t b = kxk_pctoindex(inp_wSQ, inp_bSQ, &dummy_i); + *res = b ? iDRAW : iFORBID; + *ply = 0; + return TRUE; + } + + /* copy input */ + list_pc_copy(inp_wPC, wp); + list_pc_copy(inp_bPC, bp); + list_sq_copy(inp_wSQ, ws); + list_sq_copy(inp_bSQ, bs); + + sortlists(ws, wp); + sortlists(bs, bp); + + FOLLOW_label("EGTB_PROBE") + + if (egtb_get_id(wp, bp, &id)) { + FOLLOW_LU("got ID", id) + straight = TRUE; + } else if (egtb_get_id(bp, wp, &id)) { + FOLLOW_LU("rev ID", id) + straight = FALSE; + list_sq_flipNS(ws); + list_sq_flipNS(bs); + temps = ws; + ws = bs; + bs = temps; + stm = Opp(stm); + /* no enpassant in this fuction, so no adjustment */ + { + SQ_CONTENT *tempp = wp; + wp = bp; + bp = tempp; + } /* added */ + } else { +#if defined(DEBUG) + printf("did not get id...\n"); + output_state (stm, ws, bs, wp, bp); +#endif + unpackdist(iFORBID, res, ply); + return FALSE; + } + + /* store position... */ + list_pc_copy(wp, tmp_wp); + list_pc_copy(bp, tmp_bp); + list_sq_copy(ws, tmp_ws); + list_sq_copy(bs, tmp_bs); + + /* x will be stm and y will be stw */ +/* + if (stm == WH) { + xs = ws; + xp = wp; + ys = bs; + yp = bp; + } else { + xs = bs; + xp = bp; + ys = ws; + yp = wp; + } +*/ + okcall = egtb_get_wdl(id, stm, ws, bs, probingtype, &wdl); + + FOLLOW_LU("dtmok?", okcall) + FOLLOW_DTM("wdl", wdl) + + if (okcall) { + + /*assert(epsq == NOSQUARE); */ + + if (straight) { + *res = wdl; + } else { + *res = inv_wdl(wdl); + } + } else { + unpackdist(iFORBID, res, ply); + } + + return okcall; +} + +static unsigned int +inv_wdl(unsigned w) { + unsigned r = tb_UNKNOWN; + switch (w) { + case tb_DRAW: + r = tb_DRAW; + break; + case tb_WMATE: + r = tb_BMATE; + break; + case tb_BMATE: + r = tb_WMATE; + break; + case tb_FORBID: + r = tb_FORBID; + break; + case tb_UNKNOWN: + r = tb_UNKNOWN; + break; + default: + r = tb_UNKNOWN; + break; + } + return r; +} + +static bool_t +egtb_get_wdl(tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, unsigned int *wdl) { + bool_t idxavail; + index_t idx; + dtm_t *tab[2]; + bool_t (*pc2idx)(const SQUARE *, const SQUARE *, index_t *); + + FOLLOW_label("egtb_get_wdl --> starts") + + if (egkey[k].status == STATUS_MALLOC || egkey[k].status == STATUS_STATICRAM) { + + tab[WH] = egkey[k].egt_w; + tab[BL] = egkey[k].egt_b; + pc2idx = egkey[k].pctoi; + + idxavail = pc2idx(wS, bS, &idx); + + FOLLOW_LU("indexavail (RAM)", idxavail) + + if (idxavail) { + *wdl = dtm2WDL(tab[stm][idx]); + } else { + *wdl = dtm2WDL(iFORBID); + } + + return FALSE; + + } else if (egkey[k].status == STATUS_ABSENT) { + + pc2idx = egkey[k].pctoi; + idxavail = pc2idx(wS, bS, &idx); + + FOLLOW_LU("indexavail (HD)", idxavail) + + if (idxavail) { + bool_t success; + + /* + | LOCK + *-------------------------------*/ + mythread_mutex_lock(&Egtb_lock); + + success = get_WDL(k, stm, idx, wdl, probe_hard_flag); + FOLLOW_LU("get_wld (succ)", success) + FOLLOW_LU("get_wld (wdl )", *wdl) + + /* this may not be needed */ + if (!success) { + dtm_t dtm; + unsigned res, ply; + if (probe_hard_flag && Uncompressed) { + assert(Uncompressed); + success = egtb_filepeek(k, stm, idx, &dtm); + unpackdist(dtm, &res, &ply); + *wdl = res; + } else + success = FALSE; + } + + mythread_mutex_unlock(&Egtb_lock); + /*------------------------------*\ + | UNLOCK + */ + + if (success) { + return TRUE; + } else { + if (probe_hard_flag) /* after probing hard and failing, no chance to succeed later */ + egkey[k].status = STATUS_REJECT; + *wdl = dtm2WDL(iUNKNOWN); + return FALSE; + } + + } else { + *wdl = dtm2WDL(iFORBID); + return TRUE; + } + } else if (egkey[k].status == STATUS_REJECT) { + FOLLOW_label("STATUS_REJECT") + *wdl = dtm2WDL(iFORBID); + return FALSE; + } else { + FOLLOW_label("STATUS_WRONG!") + assert(0); + *wdl = dtm2WDL(iFORBID); + return FALSE; + } + +} + +#endif + +#pragma GCC diagnostic pop + diff --git a/src/db/gaviota/gtb/gtb-probe.h b/src/db/gaviota/gtb/gtb-probe.h new file mode 100644 index 00000000..cf98470c --- /dev/null +++ b/src/db/gaviota/gtb/gtb-probe.h @@ -0,0 +1,234 @@ +/* +This Software is distributed with the following X11 License, +sometimes also known as MIT license. + +Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + +#if !defined(H_GTBPROBE) +#define H_GTBPROBE +#ifdef __cplusplus +extern "C" { +#endif +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + +#include + +#define tb_MAXPATHLEN 1024 + +/*----------------------------------*\ +| CONSTANTS +\*----------------------------------*/ + +enum TB_mask_values { tb_RESMASK = 3, tb_INFOMASK = 7, tb_PLYSHIFT = 3 }; + +enum TB_return_values { + tb_DRAW = 0, + tb_WMATE = 1, + tb_BMATE = 2, + tb_FORBID = 3, + tb_UNKNOWN = 7 +}; + +enum TB_pieces { + tb_NOPIECE, tb_PAWN, tb_KNIGHT, tb_BISHOP, tb_ROOK, tb_QUEEN, tb_KING +}; + +enum TB_sides { + tb_WHITE_TO_MOVE, tb_BLACK_TO_MOVE +}; + +enum TB_squares { + tb_A1, tb_B1, tb_C1, tb_D1, tb_E1, tb_F1, tb_G1, tb_H1, + tb_A2, tb_B2, tb_C2, tb_D2, tb_E2, tb_F2, tb_G2, tb_H2, + tb_A3, tb_B3, tb_C3, tb_D3, tb_E3, tb_F3, tb_G3, tb_H3, + tb_A4, tb_B4, tb_C4, tb_D4, tb_E4, tb_F4, tb_G4, tb_H4, + tb_A5, tb_B5, tb_C5, tb_D5, tb_E5, tb_F5, tb_G5, tb_H5, + tb_A6, tb_B6, tb_C6, tb_D6, tb_E6, tb_F6, tb_G6, tb_H6, + tb_A7, tb_B7, tb_C7, tb_D7, tb_E7, tb_F7, tb_G7, tb_H7, + tb_A8, tb_B8, tb_C8, tb_D8, tb_E8, tb_F8, tb_G8, tb_H8, + tb_NOSQUARE +}; + +enum TB_castling { + tb_NOCASTLE = 0, + tb_WOO = 8, + tb_WOOO = 4, + tb_BOO = 2, + tb_BOOO = 1 +}; + +enum TB_compression_scheme { + tb_UNCOMPRESSED, tb_CP1, tb_CP2, tb_CP3, tb_CP4 +}; + +/*----------------------------------*\ +| FUNCTIONS +\*----------------------------------*/ + +extern char * tb_init (int verbosity, int compression_scheme, const char **paths); + +extern char * tb_restart(int verbosity, int compression_scheme, const char **paths); + +extern void tb_done (void); + +extern int /*bool*/ tb_probe_hard + (unsigned stm, + unsigned epsq, + unsigned castles, + const unsigned *inp_wSQ, + const unsigned *inp_bSQ, + const unsigned char *inp_wPC, + const unsigned char *inp_bPC, + /*@out@*/ unsigned *tbinfo, + /*@out@*/ unsigned *plies); + +extern int /*bool*/ tb_probe_soft + (unsigned stm, + unsigned epsq, + unsigned castles, + const unsigned *inp_wSQ, + const unsigned *inp_bSQ, + const unsigned char *inp_wPC, + const unsigned char *inp_bPC, + /*@out@*/ unsigned *tbinfo, + /*@out@*/ unsigned *plies); + +extern int /*bool*/ tb_probe_WDL_hard + (unsigned stm, + unsigned epsq, + unsigned castles, + const unsigned *inp_wSQ, + const unsigned *inp_bSQ, + const unsigned char *inp_wPC, + const unsigned char *inp_bPC, + /*@out@*/ unsigned *tbinfo); + +extern int /*bool*/ tb_probe_WDL_soft + (unsigned stm, + unsigned epsq, + unsigned castles, + const unsigned *inp_wSQ, + const unsigned *inp_bSQ, + const unsigned char *inp_wPC, + const unsigned char *inp_bPC, + /*@out@*/ unsigned *tbinfo); + +extern int /*bool*/ tb_is_initialized (void); + +/* +| tb_availability() returns 0 if no TBs available +| Otherwise, the following bits are turned 'on' if... +| ---------------------------------- +| bit: meaning +| ---------------------------------- +| 0: at least one 3-pc TB is present +| 1: 3-pc TBs are complete +| 2: at least one 4-pc TB is present +| 3: 4-pc TBs are complete +| 4: at least one 5-pc TB is present +| 5: 5-pc TBs are complete +| 6: at least one 6-pc TB is present +| 7: 6-pc TBs are complete +| Example: if 63 is returned, it means all 3-4-5-pc TBs are present +| Bits 6 and 7 will be always off, of course, until 6-piece TBs +| are supported. +*/ + +extern unsigned int tb_availability(void); + +/* +| tb_indexmemory ()returns +| how much memory has been allocated for indexes +*/ + +extern size_t tb_indexmemory (void); + +/*----------------------------------*\ +| cache +\*----------------------------------*/ + +extern int /*bool*/ tbcache_init (size_t cache_mem, int wdl_fraction); +extern int /*bool*/ tbcache_restart (size_t cache_mem, int wdl_fraction); +extern void tbcache_done (void); +extern int /*bool*/ tbcache_is_on (void); +extern void tbcache_flush (void); + +/*----------------------------------*\ +| STATS +\*----------------------------------*/ + +/* +| For maximum portability, some stats are provided +| in two 32 bits integers rather than a single 64 bit number. +| For intance, prob_hard_hits[0] contains the less significant 32 bits +| (0 to 31), and prob_hard_hits[1] the most significant ones (32 to 63). +| The 64-bit number can be recreated like this: +| uint64_t x; +| x = (uint64_t)probe_hard_hits[0]|((uint64_t)probe_hard_hits[1]<<32); +| The user has the responsibility to combine the numbers and use the +| proper 64 bit integers. +*/ + +struct TB_STATS { + long unsigned int wdl_easy_hits [2]; /* hits that were found in own wdl cache */ + long unsigned int wdl_hard_prob [2]; /* hard probes to the wdl cache: if fail, they will go to HD */ + long unsigned int wdl_soft_prob [2]; /* soft probes to the wdl cache: if fail, they won't go to HD */ + size_t wdl_cachesize ; /* size allocated for wdl cache */ + double wdl_occupancy ; /* % of slots filled in wdl cache */ + + long unsigned int dtm_easy_hits [2]; /* hits that were found in own dtm cache */ + long unsigned int dtm_hard_prob [2]; /* hard probes to the dtm cache: if fail, they will go to HD */ + long unsigned int dtm_soft_prob [2]; /* soft probes to the dtm cache: if fail, they won't go to HD */ + size_t dtm_cachesize ; /* size allocated for dtm cache */ + double dtm_occupancy ; /* % of slots filled in dtm cache */ + + long unsigned int total_hits [2]; /* succesful probes */ + long unsigned int memory_hits [2]; /* succesful probes to memory */ + long unsigned int drive_hits [2]; /* succesful probes to the Hard drive */ + long unsigned int drive_miss [2]; /* failing probes to the Hard drive */ + long unsigned int bytes_read [2]; /* bytes read from Hard drive */ + long unsigned int files_opened ; /* number of files newly opened */ + double memory_efficiency ; /* % hits from memory over total hits */ +}; + +extern void tbstats_reset (void); +extern void tbstats_get (struct TB_STATS *stats); + + +/*----------------------------------*\ +| PATH MANAGEMENT +\*----------------------------------*/ + +extern const char ** tbpaths_init (void); +extern const char ** tbpaths_add (const char **ps, const char *newpath); +extern const char ** tbpaths_done (const char **ps); + +extern const char * tbpaths_getmain (void); + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/db/gaviota/gtb/gtb-types.h b/src/db/gaviota/gtb/gtb-types.h new file mode 100644 index 00000000..c227713e --- /dev/null +++ b/src/db/gaviota/gtb/gtb-types.h @@ -0,0 +1,25 @@ +#if !defined(H_GTBTYPES) +#define H_GTBTYPES +#ifdef __cplusplus +extern "C" { +#endif +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +#include "sysport/sysport.h" + +typedef uint32_t sq_t; +typedef uint8_t pc_t; +typedef uint32_t mv_t; +typedef int32_t tbkey_t; +typedef uint16_t dtm_t; +typedef int32_t index_t; + +#define MAXINDEX_T ((1ul << 31)-1ul) + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ +#ifdef __cplusplus +} +#endif +#endif + + + diff --git a/src/db/gaviota/gtb/license.txt b/src/db/gaviota/gtb/license.txt new file mode 100644 index 00000000..57b5fd89 --- /dev/null +++ b/src/db/gaviota/gtb/license.txt @@ -0,0 +1,100 @@ + Gaviota Tablebases Probing Code API + Copyright (c) 2010 Miguel A. Ballicora +----------------------------------------------------------------------------- + + LICENSES + +----------------------------------------------------------------------------- +This Software is distributed with the following X11 License, +sometimes also known as MIT license. + +Copyright (c) 2010 Miguel A. Ballicora + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + +----------------------------------------------------------------------------- +This Software also contain the following compression libraries: +----------------------------------------------------------------------------- +LZMA: +2009-02-02 : Igor Pavlov : Public domain +----------------------------------------------------------------------------- +ZLIB License + +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ +---------------------------------------------------------------------------- +LZF: + +Copyright (c) 2000-2007 Marc Alexander Lehmann + +Redistribution and use in source and binary forms, with or without modifica- +tion, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- +CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- +CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- +ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +Alternatively, the following files carry an additional notice that +explicitly allows relicensing under the GPLv2: lzf.c lzf.h lzfP.h lzf_c.c +lzf_d.c +----------------------------------------------------------------------------- diff --git a/src/db/gaviota/gtb/readme.txt b/src/db/gaviota/gtb/readme.txt new file mode 100644 index 00000000..91cb23a9 --- /dev/null +++ b/src/db/gaviota/gtb/readme.txt @@ -0,0 +1,146 @@ + Gaviota Tablebases Probing Code API + Copyright (c) 2010 Miguel A. Ballicora +----------------------------------------------------------------------------- + +This software provides C code to probe the Gaviota Endgame Tablebases. +It is released under then X11 ("MIT") license (see license.txt). + +This API (Application Programming Interface) is designed to be as portable +as possible. Functions could be called from Linux or Windows. +Most likely it will work in other operating systems but that has not been +tested. This API is a beta version and as such, it is not guaranteed any +type of backward compatibility or to remain untouched, at least until +version 1.0 is released. + +A very small set of tablebase files is included in this distribution +for testing purposes (only 3 pieces). They are compressed with four +different compression schemes. For a more complete set, please download +Gaviota from + +http://sites.google.com/site/gaviotachessengine/ + +and generate the 4 and 5 piece tablebases. Instructions how to generate +and compressed them are in the website. More information can always be found: + +http://sites.google.com/site/gaviotachessengine/Home/endgame-tablebases-1 + +Alternatively, already compressed tablebase files (ready to go!) can be +downloaded from + +http://www.olympuschess.com/egtb/gaviota/ (Many thanks to Josh Shriver) + +"tbprobe" is distributed here as a tablebase probing example. The current API +is relatively "low level" to optimize performance. We hope the small program +tbprobe is self explanatory. A more complete and detailed documentation may be +released later. + +We plan to support an interface with a FEN notation; thus, it is expected +that some other functions maybe added to this API. + +Four different types of compression are included. It is possible that in the +future some other compression schemes could be provided, but only if they +represent a serious improvement in speed or memory size. To maximize +backward compatibility between versions of programs and TBs, it is strongly +recommended that engine developers always support at least scheme 4 (tb_CP4), +which is considered the default at this point. For that reason, it is +suggested that testers always have a set of TBs compressed with scheme 4. + +This API is designed to be multithreading friendly. Regions where different +threads could access data from this API were protected with a mutex to avoid +problems. + +-------------------------- How to use this API ------------------------------ + +To include this code in any engine or GUI, the following files should be +compiled and linked: + +gtb-probe.c +gtb-dec.c +gtb-att.c +sysport/sysport.c +compression/wrap.c +compression/huffman/hzip.c +compression/liblzf/lzf_c.c +compression/liblzf/lzf_d.c +compression/zlib/zcompress.c +compression/zlib/uncompr.c +compression/zlib/inflate.c +compression/zlib/deflate.c +compression/zlib/adler32.c +compression/zlib/crc32.c +compression/zlib/infback.c +compression/zlib/inffast.c +compression/zlib/inftrees.c +compression/zlib/trees.c +compression/zlib/zutil.c +compression/lzma/LzmaEnc.c +compression/lzma/LzmaDec.c +compression/lzma/Alloc.c +compression/lzma/LzFind.c +compression/lzma/Lzma86Enc.c +compression/lzma/Lzma86Dec.c +compression/lzma/Bra86.c + +The following files will be "included" +gtb-probe.h +gtb-dec.h +gtb-att.h +gtb-types.h + +plus all the *.h files in the folders, so set the proper -I flags: +sysport/ +compression/ +compression/huffman/ +compression/liblzf/ +compression/zlib/ +compression/lzma/ + +The following libraries should be linked in Linux +-lpthread +-lm + +In Windows, the appropriate MT (multithreaded library should be linked too) + +These switches should be set in the compiler +-D NDEBUG +-D Z_PREFIX + +The first one removes the assert code, and the second +one makes sure that some names in the zlib library will not +collision with names in other compression libraries. + +-------------------------- COMPILATION EXAMPLE ------------------------------ + +The file compile.sh is an example of how tbprobe can be +compiled in Linux using gcc. + +Rakefile.rb is the ruby version of Makefile. You have to install 'rake' +to execute it. This is what I use but you don't have to. It is provided +out of laziness. I should probably remove it. + +------------------ COMPILING A STATIC LIBRARY (optional) -------------------- + +Aaron Becker wrote a Makefile to compile a static library --> libgtb.a +I just applied this modification from his fork. +For now, this for Linux only. Type 'make' to compile it. +Some people may find this approach more convenient since the library +has to be compiled only once. Of course, this library needs to be included +at linking time, when you compile your own program + +---------------------------- For UCI Authors -------------------------------- + +Generally, UCI (Universal Chess Interface) GUIs use standard labels for +Tablebase paths and cache sizes. For instance, NalimovPath and NalimovCache +are used for the Nalimov tablebases. Therefore, engine authors are strongly +encouraged (Please!) to follow a common standard to simplify the life of GUI +developers and users. For that reason, it is suggested to implement as +parameters: GaviotaTbPath and GaviotaTbCache in their communication with a +UCI graphical user interface. + +----------------------------------------------------------------------------- + +Good luck with the tablebases! + +Miguel + +***************************************************************************** diff --git a/src/db/gaviota/gtb/sysport/sysport.c b/src/db/gaviota/gtb/sysport/sysport.c new file mode 100644 index 00000000..f25541f4 --- /dev/null +++ b/src/db/gaviota/gtb/sysport/sysport.c @@ -0,0 +1,276 @@ +#include +#include +#include +#include "sysport.h" + +/**** CLOCK *************************************************************************/ + +#if defined(USECLOCK) + + #include + extern myclock_t myclock(void) {return (myclock_t)clock();} + extern myclock_t ticks_per_sec (void) {return CLOCKS_PER_SEC;} + +#elif defined(USEWINCLOCK) + + #define WIN32_LEAN_AND_MEAN + #include + extern myclock_t myclock(void) {return (myclock_t)GetTickCount();} + extern myclock_t ticks_per_sec (void) {return 1000;} + + +#elif defined(USELINCLOCK) + + #include + extern myclock_t myclock(void) + { + struct timeval tv; + gettimeofday(&tv, NULL); + return (myclock_t)tv.tv_sec * 1000 + (myclock_t)tv.tv_usec/1000; + } + extern myclock_t ticks_per_sec (void) {return 1000;} + +#else + + #error No Clock specified in compilation + +#endif + +/**** PATH NAMES *************************************************************************/ + +#if defined(GCCLINUX) + extern int isfoldersep (int x) { return x == '/';} +#elif defined(MVSC) + extern int isfoldersep (int x) { return x == '\\' || x == ':';} +#else + extern int isfoldersep (int x) { return x == '/' || x == '\\' || x == ':';} +#endif + +/**** Maximum Files Open *****************************************************************/ + +#if defined(__MINGW32__) || defined(__MINGW64__) + extern int mysys_fopen_max (void) { return FOPEN_MAX;} +#elif defined(GCCLINUX) + #include + #if 0 + struct rlimit { + rlim_t rlim_cur; /* Soft limit */ + rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */ + }; + #endif + extern int mysys_fopen_max (void) + { + int ok; + struct rlimit rl; + ok = 0 == getrlimit(RLIMIT_NOFILE, &rl); + if (ok) + return (int)rl.rlim_cur; + else + return FOPEN_MAX; + } +#elif defined(MVSC) + extern int mysys_fopen_max (void) { return FOPEN_MAX;} +#else + extern int mysys_fopen_max (void) { return FOPEN_MAX;} +#endif + + +#if defined(MULTI_THREADED_INTERFACE) +/**** THREADS ****************************************************************************/ + +/* +| +| POSIX +| +\*-------------------------*/ +#if defined (POSIX_THREADS) + +#include + +extern int /* boolean */ +mythread_create (/*@out@*/ mythread_t *thread, routine_t start_routine, void *arg, /*@out@*/ int *ret_error) +{ + const pthread_attr_t *attr = NULL; /* default attributes */ + int ret; + ret = pthread_create (thread, attr, start_routine, arg); + *ret_error = ret; + return 0 == ret; +} + +extern int /* boolean */ +mythread_join (mythread_t thread) +{ + void *p; /* value return from pthread_exit, not used */ + int ret = pthread_join (thread, &p); + return 0 == ret; +} + +extern void +mythread_exit (void) +{ + pthread_exit (NULL); +} + + +extern const char * +mythread_create_error (int err) +{ + const char *s; + switch (err) { + case 0 : s = "Success"; break; + case EAGAIN: s = "EAGAIN" ; break; + case EINVAL: s = "EINVAL" ; break; + case EPERM : s = "EPERM" ; break; + default : s = "Unknown error"; break; + } + return s; +} + +extern void mythread_mutex_init (mythread_mutex_t *m) { pthread_mutex_init (m,NULL);} +extern void mythread_mutex_destroy (mythread_mutex_t *m) { pthread_mutex_destroy(m) ;} +extern void mythread_mutex_lock (mythread_mutex_t *m) { pthread_mutex_lock (m) ;} +extern void mythread_mutex_unlock (mythread_mutex_t *m) { pthread_mutex_unlock (m) ;} + +#ifdef SPINLOCKS +extern void mythread_spinx_init (mythread_spinx_t *m) { pthread_spin_init (m,0);} /**/ +extern void mythread_spinx_destroy (mythread_spinx_t *m) { pthread_spin_destroy(m) ;} /**/ +extern void mythread_spinx_lock (mythread_spinx_t *m) { pthread_spin_lock (m) ;} /**/ +extern void mythread_spinx_unlock (mythread_spinx_t *m) { pthread_spin_unlock (m) ;} /**/ +#else +extern void mythread_spinx_init (mythread_spinx_t *m) { pthread_mutex_init (m,NULL);} /**/ +extern void mythread_spinx_destroy (mythread_spinx_t *m) { pthread_mutex_destroy(m) ;} /**/ +extern void mythread_spinx_lock (mythread_spinx_t *m) { pthread_mutex_lock (m) ;} /**/ +extern void mythread_spinx_unlock (mythread_spinx_t *m) { pthread_mutex_unlock (m) ;} /**/ +#endif + +/* semaphores */ +extern int /* boolean */ +mysem_init (mysem_t *sem, unsigned int value) + { return -1 != sem_init (sem, 0 /*not shared with processes*/, value);} + +extern int /* boolean */ +mysem_wait (mysem_t *sem) + { return 0 == sem_wait (sem);} + +extern int /* boolean */ +mysem_post (mysem_t *sem) + { return 0 == sem_post (sem);} + +extern int /* boolean */ +mysem_destroy (mysem_t *sem) + { return 0 == sem_destroy (sem);} + +/* +| +| NT_THREADS +| +\*-------------------------*/ +#elif defined(NT_THREADS) + +#define WIN32_LEAN_AND_MEAN +#include +#include + +extern int /* boolean */ +mythread_create (/*@out@*/ mythread_t *thread, routine_t start_routine, void *arg, /*@out@*/ int *ret_error) +{ + static unsigned int thread_id; + mythread_t t; + int /* boolean */ is_ok; + + t = (mythread_t) _beginthreadex (NULL, 0, start_routine, arg, 0, &thread_id ); + is_ok = (t != 0); + *thread = t; + *ret_error = is_ok? 0: errno; + return is_ok; +} + +extern int /* boolean */ +mythread_join (mythread_t thread) +{ + unsigned long int ret; + ret = WaitForSingleObject (thread, INFINITE); + CloseHandle(thread); + return ret != WAIT_FAILED; +} + +extern void +mythread_exit (void) +{ + return; +} + +extern const char * +mythread_create_error (int err) +{ + const char *s; + switch (err) { + case 0 : s = "Success"; break; + case EAGAIN: s = "EAGAIN" ; break; + case EINVAL: s = "EINVAL" ; break; + case EPERM : s = "EPERM" ; break; + default : s = "Unknown error"; break; + } + return s; +} + +extern void mythread_mutex_init (mythread_mutex_t *m) { *m = CreateMutex(0, FALSE, 0) ;} +extern void mythread_mutex_destroy (mythread_mutex_t *m) { CloseHandle(*m) ;} +extern void mythread_mutex_lock (mythread_mutex_t *m) { WaitForSingleObject(*m, INFINITE) ;} +extern void mythread_mutex_unlock (mythread_mutex_t *m) { ReleaseMutex(*m) ;} + +extern void mythread_spinx_init (mythread_spinx_t *m) { InitializeCriticalSection(m) ;} /**/ +extern void mythread_spinx_destroy (mythread_spinx_t *m) { DeleteCriticalSection(m) ;} /**/ +extern void mythread_spinx_lock (mythread_spinx_t *m) { EnterCriticalSection (m) ;} /**/ +extern void mythread_spinx_unlock (mythread_spinx_t *m) { LeaveCriticalSection (m) ;} /**/ + +/* semaphores */ +extern int /* boolean */ +mysem_init (mysem_t *sem, unsigned int value) +{ + mysem_t h = + CreateSemaphore( + NULL, /* cannot be inherited */ + value, /* Initial Count */ + 256, /* Maximum Count */ + NULL /* Name --> NULL, not shared among threads */ + ); + + if (h != NULL) *sem = h; + + return h != NULL; +} + +extern int /* boolean */ +mysem_wait (mysem_t *sem) +{ + HANDLE h = *sem; + return WAIT_FAILED != WaitForSingleObject (h, INFINITE); +} + +extern int /* boolean */ +mysem_post (mysem_t *sem) +{ + HANDLE h = *sem; + return 0 != ReleaseSemaphore(h, 1, NULL); +} + +extern int /* boolean */ +mysem_destroy (mysem_t *sem) +{ + return 0 != CloseHandle( *sem); +} + +/**** THREADS ****************************************************************************/ +#else + #error Definition of threads not present +#endif + +/* MULTI_THREADED_INTERFACE */ +#endif + + + + + + diff --git a/src/db/gaviota/gtb/sysport/sysport.h b/src/db/gaviota/gtb/sysport/sysport.h new file mode 100644 index 00000000..b6f98f8d --- /dev/null +++ b/src/db/gaviota/gtb/sysport/sysport.h @@ -0,0 +1,249 @@ +#if !defined(H_SYSPOR) +#define H_SYSPOR + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + +/* +| Define +| MONOTHREAD: if SMP functions are not going to be used nor linked with -lpthread +| +*/ + +#ifdef _MSC_VER + #include +#else + #include "unistd.h" +#endif + +#ifdef _MSC_VER + #if !defined(MVSC) + #define MVSC + #endif +#endif + +#if defined(__linux__) || defined(__GNUC__) + #if !defined(GCCLINUX) + #define GCCLINUX + #endif +#endif + + +/* +| +| To allow multithreaded functions, MULTI_THREADED_INTERFACE should be defined +| +\*--------------------------------------------------------------------------------*/ + + +#if defined(CYGWIN) + + #define USECLOCK + #define MULTI_THREADED_INTERFACE + #undef NT_THREADS + #define POSIX_THREADS + #define GCCLINUX_INTEGERS + +#elif defined(MINGW) + + #define USEWINCLOCK + #define MULTI_THREADED_INTERFACE + #define NT_THREADS + #undef POSIX_THREADS + #define GCCLINUX_INTEGERS + +#elif defined(GCCLINUX) + + #define USELINCLOCK + #define MULTI_THREADED_INTERFACE + #undef NT_THREADS + #define POSIX_THREADS + #define GCCLINUX_INTEGERS + +#elif defined(MVSC) + + #define USEWINCLOCK + #define MULTI_THREADED_INTERFACE + #define NT_THREADS + #undef POSIX_THREADS + #define MSWINDOWS_INTEGERS + +#else + + #error COMPILER NOT DEFINED + +#endif + + + +#if defined(MONOTHREAD) + #undef MULTI_THREADED_INTERFACE +#endif + + + +#if defined(GCCLINUX) + + #define U64(x) (x##ull) + +#elif defined(MVSC) + + #define U64(x) (x##ui64) + +#else + #error OS not defined properly +#endif + + +#if defined(GCCLINUX) +/* + typedef unsigned long long int uint64_t; + typedef long long int int64_t; + typedef unsigned char uint8_t; + typedef unsigned short int uint16_t; + typedef unsigned int uint32_t; +*/ + + #include + +#elif defined(MVSC) + + typedef unsigned char uint8_t; + typedef unsigned short int uint16_t; + typedef unsigned int uint32_t; + typedef unsigned __int64 uint64_t; + + typedef signed char int8_t; + typedef short int int16_t; + typedef int int32_t; + typedef __int64 int64_t; + +#else + #error OS not defined properly for 64 bit integers +#endif + + +/*----------------- + PATH NAMES +------------------*/ + +#if defined(GCCLINUX) + #define FOLDERSEP "/" +#elif defined(MVSC) + #define FOLDERSEP "\\" +#else + #define FOLDERSEP "/" +#endif + +/* path names */ +extern int isfoldersep (int x); + +/*----------------- + FOPEN MAX +------------------*/ + +extern int mysys_fopen_max (void); + +/*------------ + TIMER +-------------*/ + +typedef int64_t myclock_t; + +extern myclock_t myclock(void); +extern myclock_t ticks_per_sec (void); + +#define MYCLOCKS_PER_SEC (ticks_per_sec()) +#define GET_TICK (myclock()) + + +/*********************************************************************/ +#if defined(MULTI_THREADED_INTERFACE) + +/*------------ + THREADS +-------------*/ + +#if defined (POSIX_THREADS) + + #include + #include + + #define THREAD_CALL + + typedef void * thread_return_t; + typedef pthread_t mythread_t; + typedef thread_return_t (THREAD_CALL *routine_t) (void *); + typedef pthread_mutex_t mythread_mutex_t; + + #ifdef SPINLOCKS + typedef pthread_spinlock_t mythread_spinx_t; + #else + typedef pthread_mutex_t mythread_spinx_t; + #endif + + typedef sem_t mysem_t; + + +#elif defined(NT_THREADS) + + #define WIN32_LEAN_AND_MEAN + + #include + #include + + #define THREAD_CALL __stdcall + + typedef unsigned thread_return_t; + typedef HANDLE mythread_t; + typedef thread_return_t (THREAD_CALL *routine_t) (void *); + typedef HANDLE mythread_mutex_t; + + #define SPINLOCKS + + #ifdef SPINLOCKS + typedef CRITICAL_SECTION mythread_spinx_t; + #else + typedef HANDLE mythread_spinx_t; + #endif + + typedef HANDLE mysem_t; + +#else + #error Definition of threads not present +#endif + + + +extern int /*boolean*/ mythread_create (/*@out@*/ mythread_t *thread, routine_t start_routine, void *arg, /*@out@*/ int *ret_error); +extern int /*boolean*/ mythread_join (mythread_t thread); +extern void mythread_exit (void); +extern const char * mythread_create_error (int err); + +extern void mythread_mutex_init (mythread_mutex_t *m); +extern void mythread_mutex_destroy (mythread_mutex_t *m); +extern void mythread_mutex_lock (mythread_mutex_t *m); +extern void mythread_mutex_unlock (mythread_mutex_t *m); + +extern void mythread_spinx_init (mythread_spinx_t *m); /**/ +extern void mythread_spinx_destroy (mythread_spinx_t *m); /**/ +extern void mythread_spinx_lock (mythread_spinx_t *m); /**/ +extern void mythread_spinx_unlock (mythread_spinx_t *m); /**/ + +/* semaphores*/ +extern int /*boolean*/ mysem_init (mysem_t *sem, unsigned int value); +extern int /*boolean*/ mysem_wait (mysem_t *sem); +extern int /*boolean*/ mysem_post (mysem_t *sem); +extern int /*boolean*/ mysem_destroy (mysem_t *sem); +#endif + + +#if defined(MINGW) +#undef GCCLINUX +#define MSVC +#endif + + +/* end MULTI_THREADED_INTERFACE*/ +#endif + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ diff --git a/src/db/gaviota/gtb/version.h b/src/db/gaviota/gtb/version.h new file mode 100644 index 00000000..b292dd74 --- /dev/null +++ b/src/db/gaviota/gtb/version.h @@ -0,0 +1,2 @@ +#define VERSION "0.4" + diff --git a/src/db/gaviota/gtb/version.txt b/src/db/gaviota/gtb/version.txt new file mode 100644 index 00000000..bd73f470 --- /dev/null +++ b/src/db/gaviota/gtb/version.txt @@ -0,0 +1 @@ +0.4 diff --git a/src/db/syzygy/SYZYGY.h b/src/db/syzygy/SYZYGY.h index f57e0f0c..e54fbcb8 100644 --- a/src/db/syzygy/SYZYGY.h +++ b/src/db/syzygy/SYZYGY.h @@ -35,10 +35,8 @@ class SYZYGY : public Singleton { public: int SZtbProbeWDL(const _Tchessboard &chessboard, const int side, const int tot) const { if (getInstalledPieces() >= tot) { - BENCH(times->start("syzygyTime")) - auto a = SZtbProbeWDL(chessboard, side); - BENCH(times->stop("syzygyTime")) - return a; + BENCH_AUTO_CLOSE("syzygyTime") + return SZtbProbeWDL(chessboard, side); } return TB_RESULT_FAILED; } @@ -50,7 +48,7 @@ class SYZYGY : public Singleton { if (promotion == 2) return 'r'; if (promotion == 3) return 'b'; if (promotion == 4) return 'n'; - return GenMoves::NO_PROMOTION; + return NO_PROMOTION; } unsigned SZtbProbeRoot(const u64, const u64, const _Tchessboard &c, const bool turn, unsigned *); @@ -87,6 +85,6 @@ class SYZYGY : public Singleton { SYZYGY(); - static u64 decode(u64 d) ; + static u64 decode(u64 d); }; diff --git a/src/db/syzygy/tbcore.c b/src/db/syzygy/tbcore.c index bfd0e9a5..6f4be7b3 100644 --- a/src/db/syzygy/tbcore.c +++ b/src/db/syzygy/tbcore.c @@ -22,7 +22,7 @@ #ifndef _WIN32 -#include +#include "unistd.h" #include #endif @@ -61,14 +61,22 @@ #ifdef TB_CUSTOM_BSWAP32 #define internal_bswap32(x) TB_CUSTOM_BSWAP32(x) #else +#ifdef _MSC_VER +#define internal_bswap32(x) _byteswap_ulong(x) +#else #define internal_bswap32(x) __builtin_bswap32(x) #endif +#endif #ifdef TB_CUSTOM_BSWAP64 #define internal_bswap64(x) TB_CUSTOM_BSWAP64(x) #else +#ifdef _MSC_VER +#define internal_bswap64(x) _byteswap_uint64(x) +#else #define internal_bswap64(x) __builtin_bswap64(x) #endif +#endif static int initialized = 0; static int num_paths = 0; diff --git a/src/def.h b/src/def.h index 855f4ad9..f87b3b8d 100644 --- a/src/def.h +++ b/src/def.h @@ -23,38 +23,16 @@ static constexpr int MAX_PLY = 96; typedef unsigned char uchar; typedef long long unsigned u64; -typedef u64 _Tchessboard[16]; +typedef u64 _Tchessboard[13]; typedef struct { - u64 allPieces; - u64 kingAttackers[2]; - u64 allPiecesSide[2]; - u64 allPiecesNoPawns[2]; - u64 posKingBit[2]; - int kingSecurity[2]; - uchar posKing[2]; -} _Tboard; - - -typedef union { - u64 u; - struct s { - char promotionPiece; - char pieceFrom; - uchar capturedPiece; - uchar from; - uchar to; - char side; - uchar type; - } s; + uchar promotionPiece; + uchar pieceFrom; + uchar capturedPiece; + uchar from; + uchar to; + uchar side; + uchar type; + uchar _align_; } _Tmove; -typedef struct { - _Tmove *moveList; - int size; -} _TmoveP; - -typedef struct { - int cmove; - _Tmove argmove[MAX_PLY]; -} _TpvLine; diff --git a/src/js/Uci.h b/src/js/Uci.h index a0cb2499..f77fc274 100644 --- a/src/js/Uci.h +++ b/src/js/Uci.h @@ -20,7 +20,7 @@ #include "../IterativeDeeping.h" #include -#include +#include "unistd.h" class Uci { public: diff --git a/src/js/main.cpp b/src/js/main.cpp index 77b8bb84..efd2ee35 100644 --- a/src/js/main.cpp +++ b/src/js/main.cpp @@ -18,7 +18,7 @@ #include "Uci.h" #include "../perft/Perft.h" -#include +#include "unistd.h" Uci *u = NULL; diff --git a/src/lib/ARM/32/libgtb.a b/src/lib/ARM/32/libgtb.a deleted file mode 100644 index 2f9e8a18..00000000 Binary files a/src/lib/ARM/32/libgtb.a and /dev/null differ diff --git a/src/lib/ARM/64/libgtb.a b/src/lib/ARM/64/libgtb.a deleted file mode 100644 index b45efba7..00000000 Binary files a/src/lib/ARM/64/libgtb.a and /dev/null differ diff --git a/src/lib/Linux/32/libgtb.a b/src/lib/Linux/32/libgtb.a deleted file mode 100644 index d5c13a1c..00000000 Binary files a/src/lib/Linux/32/libgtb.a and /dev/null differ diff --git a/src/lib/Linux/64/libgtb.a b/src/lib/Linux/64/libgtb.a deleted file mode 100644 index 6df7c67e..00000000 Binary files a/src/lib/Linux/64/libgtb.a and /dev/null differ diff --git a/src/lib/OSX/64/libgtb.a b/src/lib/OSX/64/libgtb.a deleted file mode 100644 index a240ab28..00000000 Binary files a/src/lib/OSX/64/libgtb.a and /dev/null differ diff --git a/src/lib/Windows/32/libgtb.a b/src/lib/Windows/32/libgtb.a deleted file mode 100644 index 6ea8370b..00000000 Binary files a/src/lib/Windows/32/libgtb.a and /dev/null differ diff --git a/src/lib/Windows/64/libgtb.a b/src/lib/Windows/64/libgtb.a deleted file mode 100644 index 5b556631..00000000 Binary files a/src/lib/Windows/64/libgtb.a and /dev/null differ diff --git a/src/lib/gtb-probe.h b/src/lib/gtb-probe.h deleted file mode 100755 index d42b197d..00000000 --- a/src/lib/gtb-probe.h +++ /dev/null @@ -1,252 +0,0 @@ -/* -This Software is distributed with the following X11 License, -sometimes also known as MIT license. - -Copyright (c) 2010 Miguel A. Ballicora - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. -*/ - -#if !defined(H_GTBPROBE) -#define H_GTBPROBE -#ifdef __cplusplus -extern "C" { -#endif -/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - -#include - -#define tb_MAXPATHLEN 1024 - -/*----------------------------------*\ -| CONSTANTS -\*----------------------------------*/ - -enum TB_mask_values { - tb_RESMASK = 3, tb_INFOMASK = 7, tb_PLYSHIFT = 3 -}; - -enum TB_return_values { - tb_DRAW = 0, - tb_WMATE = 1, - tb_BMATE = 2, - tb_FORBID = 3, - tb_UNKNOWN = 7 -}; - -enum TB_pieces { - tb_NOPIECE, tb_PAWN, tb_KNIGHT, tb_BISHOP, tb_ROOK, tb_QUEEN, tb_KING -}; - -enum TB_sides { - tb_WHITE_TO_MOVE, tb_BLACK_TO_MOVE -}; - -enum TB_squares { - tb_A1, tb_B1, tb_C1, tb_D1, tb_E1, tb_F1, tb_G1, tb_H1, - tb_A2, tb_B2, tb_C2, tb_D2, tb_E2, tb_F2, tb_G2, tb_H2, - tb_A3, tb_B3, tb_C3, tb_D3, tb_E3, tb_F3, tb_G3, tb_H3, - tb_A4, tb_B4, tb_C4, tb_D4, tb_E4, tb_F4, tb_G4, tb_H4, - tb_A5, tb_B5, tb_C5, tb_D5, tb_E5, tb_F5, tb_G5, tb_H5, - tb_A6, tb_B6, tb_C6, tb_D6, tb_E6, tb_F6, tb_G6, tb_H6, - tb_A7, tb_B7, tb_C7, tb_D7, tb_E7, tb_F7, tb_G7, tb_H7, - tb_A8, tb_B8, tb_C8, tb_D8, tb_E8, tb_F8, tb_G8, tb_H8, - tb_NOSQUARE -}; - -enum TB_castling { - tb_NOCASTLE = 0, - tb_WOO = 8, - tb_WOOO = 4, - tb_BOO = 2, - tb_BOOO = 1 -}; - -enum TB_compression_scheme { - tb_UNCOMPRESSED, tb_CP1, tb_CP2, tb_CP3, tb_CP4 -}; - -/*----------------------------------*\ -| FUNCTIONS -\*----------------------------------*/ - -extern char *tb_init(int verbosity, int compression_scheme, const char **paths); - -extern char *tb_restart(int verbosity, int compression_scheme, const char **paths); - -extern void tb_done(void); - -extern int /*bool*/ tb_probe_hard - (unsigned stm, - unsigned epsq, - unsigned castles, - const unsigned *inp_wSQ, - const unsigned *inp_bSQ, - const unsigned char *inp_wPC, - const unsigned char *inp_bPC, - /*@out@*/ unsigned *tbinfo, - /*@out@*/ unsigned *plies); - -extern int /*bool*/ tb_probe_soft - (unsigned stm, - unsigned epsq, - unsigned castles, - const unsigned *inp_wSQ, - const unsigned *inp_bSQ, - const unsigned char *inp_wPC, - const unsigned char *inp_bPC, - /*@out@*/ unsigned *tbinfo, - /*@out@*/ unsigned *plies); - -extern int /*bool*/ tb_probe_WDL_hard - (unsigned stm, - unsigned epsq, - unsigned castles, - const unsigned *inp_wSQ, - const unsigned *inp_bSQ, - const unsigned char *inp_wPC, - const unsigned char *inp_bPC, - /*@out@*/ unsigned *tbinfo); - -extern int /*bool*/ tb_probe_WDL_soft - (unsigned stm, - unsigned epsq, - unsigned castles, - const unsigned *inp_wSQ, - const unsigned *inp_bSQ, - const unsigned char *inp_wPC, - const unsigned char *inp_bPC, - /*@out@*/ unsigned *tbinfo); - -extern int /*bool*/ tb_is_initialized(void); - -/* -| tb_availability() returns 0 if no TBs available -| Otherwise, the following bits are turned 'on' if... -| ---------------------------------- -| bit: meaning -| ---------------------------------- -| 0: at least one 3-pc TB is present -| 1: 3-pc TBs are complete -| 2: at least one 4-pc TB is present -| 3: 4-pc TBs are complete -| 4: at least one 5-pc TB is present -| 5: 5-pc TBs are complete -| 6: at least one 6-pc TB is present -| 7: 6-pc TBs are complete -| Example: if 63 is returned, it means all 3-4-5-pc TBs are present -| Bits 6 and 7 will be always off, of course, until 6-piece TBs -| are supported. -*/ - -extern unsigned int tb_availability(void); - -/* -| tb_indexmemory ()returns -| how much memory has been allocated for indexes -*/ - -extern size_t tb_indexmemory(void); - -/*----------------------------------*\ -| cache -\*----------------------------------*/ - -extern int /*bool*/ tbcache_init(size_t cache_mem, int wdl_fraction); -extern int /*bool*/ tbcache_restart(size_t cache_mem, int wdl_fraction); -extern void tbcache_done(void); -extern int /*bool*/ tbcache_is_on(void); -extern void tbcache_flush(void); - -/*----------------------------------*\ -| STATS -\*----------------------------------*/ - -/* -| For maximum portability, some stats are provided -| in two 32 bits integers rather than a single 64 bit number. -| For intance, prob_hard_hits[0] contains the less significant 32 bits -| (0 to 31), and prob_hard_hits[1] the most significant ones (32 to 63). -| The 64-bit number can be recreated like this: -| uint64_t x; -| x = (uint64_t)probe_hard_hits[0]|((uint64_t)probe_hard_hits[1]<<32); -| The user has the responsibility to combine the numbers and use the -| proper 64 bit integers. -*/ - -struct TB_STATS { - long unsigned int wdl_easy_hits[2]; - /* hits that were found in own wdl cache */ - long unsigned int wdl_hard_prob[2]; - /* hard probes to the wdl cache: if fail, they will go to HD */ - long unsigned int wdl_soft_prob[2]; - /* soft probes to the wdl cache: if fail, they won't go to HD */ - size_t wdl_cachesize; - /* size allocated for wdl cache */ - double wdl_occupancy; - /* % of slots filled in wdl cache */ - - long unsigned int dtm_easy_hits[2]; - /* hits that were found in own dtm cache */ - long unsigned int dtm_hard_prob[2]; - /* hard probes to the dtm cache: if fail, they will go to HD */ - long unsigned int dtm_soft_prob[2]; - /* soft probes to the dtm cache: if fail, they won't go to HD */ - size_t dtm_cachesize; - /* size allocated for dtm cache */ - double dtm_occupancy; - /* % of slots filled in dtm cache */ - - long unsigned int total_hits[2]; - /* succesful probes */ - long unsigned int memory_hits[2]; - /* succesful probes to memory */ - long unsigned int drive_hits[2]; - /* succesful probes to the Hard drive */ - long unsigned int drive_miss[2]; - /* failing probes to the Hard drive */ - long unsigned int bytes_read[2]; - /* bytes read from Hard drive */ - long unsigned int files_opened; - /* number of files newly opened */ - double memory_efficiency; /* % hits from memory over total hits */ -}; - -extern void tbstats_reset(void); -extern void tbstats_get(struct TB_STATS *stats); - - -/*----------------------------------*\ -| PATH MANAGEMENT -\*----------------------------------*/ - -extern const char **tbpaths_init(void); -extern const char **tbpaths_add(const char **ps, const char *newpath); -extern const char **tbpaths_done(const char **ps); - -extern const char *tbpaths_getmain(void); - -/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/main.cpp b/src/main.cpp index 8cecfdcb..0b1f51ea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,23 +36,20 @@ 2| 15 14 13 12 11 10 09 08 1| 07 06 05 04 03 02 01 00 ...a b c d e f g h - */ using namespace constants; int main(int argc, char **argv) { - ASSERT(sizeof(Hash::_Thash) == 16); - ASSERT(sizeof(_Tmove) == 8); -#if defined(FULL_TEST) + assert(sizeof(Hash::_Thash) == 16); + assert(sizeof(_Tmove) == 8); +#ifdef FULL_TEST testing::InitGoogleTest(&argc, argv); - if (RUN_ALL_TESTS())return 1; - return 0; + return RUN_ALL_TESTS(); #endif GetOpt::parse(argc, argv); - return 0; } diff --git a/src/namespaces/String.h b/src/namespaces/String.h new file mode 100644 index 00000000..99dc72b6 --- /dev/null +++ b/src/namespaces/String.h @@ -0,0 +1,119 @@ +/* + Cinnamon UCI chess engine + Copyright (C) Giuseppe Cannella + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +using namespace std; + +class String { +private: + String() {} + +public: + +// template +// static String(T d, const string tohex = "") { +// stringstream ss; +// if (tohex == "int64tohex") { +// stringstream ss2; +// ss2 << std::hex << d; +// ss << "0x"; +// for (unsigned i = 0; i < 16 - ss2.str().length(); i++) +// ss << "0"; +// ss << std::hex << d << "ULL"; +// } else if (tohex == "int32tohex") { +// stringstream ss2; +// ss2 << std::hex << d; +// ss << "0x"; +// for (unsigned i = 0; i < 8 - ss2.str().length(); i++) +// ss << "0"; +// ss << std::hex << d; +// } else { +// ss << d; +// } +// value = ss.str(); +// } + + static bool isNumber(const string &value) { + for(const char& c : value) { + if(!isdigit(c))return false; + } + return true; + } + + static const string trim(string &value) { + string value1 = trimLeft(value); + return trimRight(value1); + } + + static const string trimLeft(string &value) { + const std::string WHITESPACE = " \n\r\t\f\v"; + size_t start = value.find_first_not_of(WHITESPACE); + if (start == std::string::npos) { + return ""; + } else { + value = value.substr(start); + return value; + } + } + + static const string trimRight(string &value) { + const std::string WHITESPACE = " \n\r\t\f\v"; + size_t end = value.find_last_not_of(WHITESPACE); + if (end == std::string::npos) return ""; + else { + value = value.substr(0, end + 1); + return value; + } + } + + static const string replace(string &value, const char c1, const char c2) { + for (unsigned i = 0; i < value.size(); i++) { + if (value.at(i) == c1) { + value.at(i) = c2; + } + } + return value; + } + + static const string replace(string &v, const string &s1, const string &s2) { + unsigned long a; + + while ((a = v.find(s1)) != string::npos) { + v.string::replace(a, s1.size(), s2); + } + return v; + } + + static const string toUpper(string &v) { + transform(v.begin(), v.end(), v.begin(), ::toupper); + return v; + } + + static const string toLower(string &v) { + transform(v.begin(), v.end(), v.begin(), ::tolower); + return v; + } + +}; diff --git a/src/namespaces/bits.h b/src/namespaces/bits.h index b674b518..f3aad6f4 100644 --- a/src/namespaces/bits.h +++ b/src/namespaces/bits.h @@ -21,61 +21,33 @@ #include "../util/bench/Time.h" #include "../util/FileUtil.h" -#include "debug.h" +#include "../util/bench/Bench.h" #include "../def.h" #include "constants.h" #include +#include + +#ifdef _MSC_VER +#include +#endif -using namespace _debug; using namespace constants; namespace _def { using namespace std; -#define RESET_LSB(bits) (bits&=bits-1) - -#if defined(CLOP) || defined(DEBUG_MODE) -#define STATIC_CONST -#else -#define STATIC_CONST static constexpr -#endif - -#define _assert(a) if(!(a)){ print_stacktrace();cout<(to)){cout<<"ASSERT_RANGE: "<>32); - } +#define bitCount(bits) __builtin_popcountll(bits) #endif #else @@ -90,28 +62,22 @@ namespace _def { #ifdef HAS_BSF -#ifdef HAS_64BIT +#ifdef _MSC_VER - static inline int BITScanForward(const u64 bits) { - size_t idx; - __asm__("bsfq %1, %0": "=r"(idx): "rm"(bits)); - return idx; + static int BITScanForward(u64 x) { + unsigned long index; + _BitScanForward64(&index, x); + return (int)index; } - static inline int BITScanReverse(const u64 bits) { - size_t idx; - __asm__("bsrq %1, %0": "=r"(idx): "rm"(bits)); - return idx; + static int BITScanReverse(u64 x) { + unsigned long index; + _BitScanReverse64(&index, x); + return (int)index; } - #else - static inline int BITScanForward(const u64 bits) { - return ((unsigned) bits) ? __builtin_ffs(bits) - 1 : __builtin_ffs(bits >> 32) + 31; - } - - static inline int BITScanReverse(const u64 bits) { - return ((unsigned)(bits >> 32)) ? 63 - __builtin_clz(bits >> 32) : 31 - __builtin_clz(bits); - } +#define BITScanForward(bits) __builtin_ctzll(bits) +#define BITScanReverse(bits) (63 - __builtin_clzll(bits)) #endif #else @@ -144,17 +110,13 @@ namespace _def { #endif - template + template static inline u64 shiftForward(const u64 bits) { - ASSERT(shift == 7 || shift == 8 || shift == 9); - + assert(shift == 7 || shift == 8 || shift == 9); const auto a = side == WHITE ? bits << shift : bits >> shift; - if (shift == 7) - return a & NO_FILE_LEFT[side]; - if (shift == 9) - return a & NO_FILE_RIGHT[side]; + if (shift == 7) return a & NO_FILE_LEFT[side]; + if (shift == 9) return a & NO_FILE_RIGHT[side]; return a; - } static inline int BITScanForwardUnset(const u64 bb) { diff --git a/src/namespaces/board.cpp b/src/namespaces/board.cpp index 28d5637d..70a7387e 100644 --- a/src/namespaces/board.cpp +++ b/src/namespaces/board.cpp @@ -18,41 +18,31 @@ #include "board.h" -u64 board::colors(const int pos) { - if (POW2[pos] & 0x55aa55aa55aa55aaULL)return 0x55aa55aa55aa55aaULL; +[[gnu::pure]]u64 board::colors(const int pos) { + if (POW2(pos) & 0x55aa55aa55aa55aaULL)return 0x55aa55aa55aa55aaULL; return 0xaa55aa55aa55aa55ULL; } #ifdef DEBUG_MODE -u64 board::getBitmap(const int side, const _Tchessboard &chessboard) { +u64 board::getBitmap(const uchar side, const _Tchessboard &chessboard) { return side ? getBitmap(chessboard) : getBitmap(chessboard); } -int board::getPieceAt(int side, const u64 bitmapPos, const _Tchessboard &chessboard) { +int board::getPieceAt(uchar side, const u64 bitmapPos, const _Tchessboard &chessboard) { return side == WHITE ? getPieceAt(bitmapPos, chessboard) : getPieceAt (bitmapPos, chessboard); } #endif -int board::getSide(const _Tchessboard &chessboard) { - return chessboard[SIDETOMOVE_IDX]; -} - u64 board::performRankFileCaptureAndShift(const int position, const u64 enemies, const u64 allpieces) { ASSERT_RANGE(position, 0, 63) const u64 rankFile = Bitboard::getRankFile(position, allpieces); return (rankFile & enemies) | (rankFile & ~allpieces); } - -int board::getDiagShiftCount(const int position, const u64 allpieces) { - ASSERT_RANGE(position, 0, 63); - return bitCount(Bitboard::getDiagonalAntiDiagonal(position, allpieces) & ~allpieces); -} - bool board::checkInsufficientMaterial(const int nPieces, const _Tchessboard &chessboard) { //regexp: KN?B*KB* switch (nPieces) { @@ -84,60 +74,40 @@ bool board::checkInsufficientMaterial(const int nPieces, const _Tchessboard &che } u64 board::getDiagShiftAndCapture(const int position, const u64 enemies, const u64 allpieces) { - ASSERT_RANGE(position, 0, 63); + ASSERT_RANGE(position, 0, 63) u64 nuovo = Bitboard::getDiagonalAntiDiagonal(position, allpieces); return (nuovo & enemies) | (nuovo & ~allpieces); } -u64 board::getMobilityQueen(const int position, const u64 enemies, const u64 allpieces) { - ASSERT_RANGE(position, 0, 63) - return performRankFileCaptureAndShift(position, enemies, allpieces) + - getDiagShiftAndCapture(position, enemies, allpieces); -} - u64 board::getMobilityRook(const int position, const u64 enemies, const u64 friends) { ASSERT_RANGE(position, 0, 63) return performRankFileCaptureAndShift(position, enemies, enemies | friends); } -bool board::isCastleRight_WhiteKing(const _Tchessboard &chessboard) { - return chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_WHITE_MASK; -} - -bool board::isCastleRight_BlackKing(const _Tchessboard &chessboard) { - return chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_BLACK_MASK; +[[gnu::pure]]bool board::isCastleRight_WhiteKing(const uchar RIGHT_CASTLE) { + return RIGHT_CASTLE & RIGHT_KING_CASTLE_WHITE_MASK; } -bool board::isCastleRight_WhiteQueen(const _Tchessboard &chessboard) { - return chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_WHITE_MASK; +[[gnu::pure]]bool board::isCastleRight_BlackKing(const uchar RIGHT_CASTLE) { + return RIGHT_CASTLE & RIGHT_KING_CASTLE_BLACK_MASK; } -bool board::isCastleRight_BlackQueen(const _Tchessboard &chessboard) { - return chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_BLACK_MASK; +[[gnu::pure]]bool board::isCastleRight_WhiteQueen(const uchar RIGHT_CASTLE) { + return RIGHT_CASTLE & RIGHT_QUEEN_CASTLE_WHITE_MASK; } -char board::decodeBoard(string a) { - for (int i = 0; i < 64; i++) { - if (!a.compare(BOARD[i])) return i; - } - error(a); - ASSERT(0); - return -1; +[[gnu::pure]]bool board::isCastleRight_BlackQueen(const uchar RIGHT_CASTLE) { + return RIGHT_CASTLE & RIGHT_QUEEN_CASTLE_BLACK_MASK; } -int board::getFile(const char cc) { +[[gnu::pure]]int board::getFile(const char cc) { return 104 - tolower(cc); } bool board::isOccupied(const uchar pos, const u64 allpieces) { - return allpieces & POW2[pos]; -} - - -string board::getCell(const int file, const int rank) { - return BOARD[FILE_AT[file] * 8 + rank]; + return allpieces & POW2(pos); } bool board::isPieceAt(const uchar pieces, const uchar pos, const _Tchessboard &chessboard) { - return chessboard[pieces] & POW2[pos]; + return chessboard[pieces] & POW2(pos); } diff --git a/src/namespaces/board.h b/src/namespaces/board.h index 1822196c..c5bad1da 100644 --- a/src/namespaces/board.h +++ b/src/namespaces/board.h @@ -22,33 +22,32 @@ #pragma once #include "constants.h" -#include "../util/bench/Times.h" #include "../util/Bitboard.h" using namespace constants; class board { +private: + board() {} public: - static u64 colors(const int pos); + [[gnu::pure]] static u64 colors(const int pos); static bool isOccupied(const uchar pos, const u64 allpieces); - static int getFile(const char cc); + [[gnu::pure]] static int getFile(const char cc); static bool checkInsufficientMaterial(const int nPieces, const _Tchessboard &chessboard); static u64 performRankFileCaptureAndShift(const int position, const u64 enemies, const u64 allpieces); - static int getSide(const _Tchessboard &chessboard); - - template + template static u64 getPinned(const u64 allpieces, const u64 friends, const int kingPosition, const _Tchessboard &chessboard) { - BENCH(Times::getInstance().start("pinTime")) + BENCH_AUTO_CLOSE("getPinned") u64 result = 0; - ASSERT_RANGE(kingPosition, 0, 63); + ASSERT_RANGE(kingPosition, 0, 63) const u64 *s = LINK_SQUARE[kingPosition]; - constexpr int xside = side ^1; + constexpr int xside = X(side); u64 attacked = DIAGONAL_ANTIDIAGONAL[kingPosition] & (chessboard[QUEEN_BLACK + xside] | chessboard[BISHOP_BLACK + xside]); attacked |= @@ -57,41 +56,33 @@ class board { const int pos = BITScanForward(attacked); const u64 b = *(s + pos) & allpieces; #ifdef DEBUG_MODE - u64 x = *(s + pos) & (allpieces & NOTPOW2[kingPosition]); - ASSERT(b == x); + u64 x = *(s + pos) & (allpieces & NOTPOW2(kingPosition)); + assert(b == x); #endif if (!(b & (b - 1))) { result |= b & friends; } } - BENCH(Times::getInstance().stop("pinTime")) return result; } static u64 getDiagShiftAndCapture(const int position, const u64 enemies, const u64 allpieces); - static int getDiagShiftCount(const int position, const u64 allpieces); - - static bool isCastleRight_WhiteKing(const _Tchessboard &chessboard); - - static u64 getMobilityQueen(const int position, const u64 enemies, const u64 allpieces); + [[gnu::pure]] static bool isCastleRight_WhiteKing(const uchar RIGHT_CASTLE); static u64 getMobilityRook(const int position, const u64 enemies, const u64 friends); - static bool isCastleRight_BlackKing(const _Tchessboard &chessboard); - - static bool isCastleRight_WhiteQueen(const _Tchessboard &chessboard); + [[gnu::pure]] static bool isCastleRight_BlackKing(const uchar RIGHT_CASTLE); - static bool isCastleRight_BlackQueen(const _Tchessboard &chessboard); + [[gnu::pure]]static bool isCastleRight_WhiteQueen(const uchar RIGHT_CASTLE); - static char decodeBoard(string a); - - static string getCell(const int file, const int rank); + [[gnu::pure]]static bool isCastleRight_BlackQueen(const uchar RIGHT_CASTLE); static bool isPieceAt(const uchar pieces, const uchar pos, const _Tchessboard &chessboard); - template + template static u64 getBitmap(const _Tchessboard &chessboard) { + BENCH_AUTO_CLOSE("getBitmap") return chessboard[PAWN_BLACK + side] | chessboard[ROOK_BLACK + side] | chessboard[BISHOP_BLACK + side] | chessboard[KNIGHT_BLACK + side] | chessboard[KING_BLACK + side] | chessboard[QUEEN_BLACK + side]; } @@ -103,8 +94,9 @@ class board { chessboard[KNIGHT_WHITE] | chessboard[KING_WHITE] | chessboard[QUEEN_WHITE]; } - template + template static int getPieceAt(const u64 bitmapPos, const _Tchessboard &chessboard) { + BENCH_AUTO_CLOSE("getPieceAt") if ((chessboard[PAWN_BLACK + side] & bitmapPos))return PAWN_BLACK + side; if ((chessboard[ROOK_BLACK + side] & bitmapPos))return ROOK_BLACK + side; if ((chessboard[BISHOP_BLACK + side] & bitmapPos))return BISHOP_BLACK + side; @@ -116,103 +108,112 @@ class board { #ifdef DEBUG_MODE - static u64 getBitmap(const int side, const _Tchessboard &chessboard); + static u64 getBitmap(const uchar side, const _Tchessboard &chessboard); - static int getPieceAt(int side, const u64 bitmapPos, const _Tchessboard &chessboard); + static int getPieceAt(uchar side, const u64 bitmapPos, const _Tchessboard &chessboard); #endif - template + template static u64 getAttackers(const int position, const u64 allpieces, const _Tchessboard &chessboard) { - BENCH(Times::getInstance().start("getAttackers")) - ASSERT_RANGE(position, 0, 63); - ASSERT_RANGE(side, 0, 1); - + BENCH_AUTO_CLOSE("getAttackers") + ASSERT_RANGE(position, 0, 63) + ASSERT_RANGE(side, 0, 1) + constexpr int xside = X(side); ///knight - u64 attackers = KNIGHT_MASK[position] & chessboard[KNIGHT_BLACK + (side ^ 1)]; - if (exitOnFirst && attackers) { - BENCH(Times::getInstance().stop("getAttackers")) - return attackers; - } + u64 attackers = KNIGHT_MASK[position] & chessboard[KNIGHT_BLACK + xside]; + ///king - attackers |= NEAR_MASK1[position] & chessboard[KING_BLACK + (side ^ 1)]; - if (exitOnFirst && attackers) { - BENCH(Times::getInstance().stop("getAttackers")) - return attackers; - } + attackers |= NEAR_MASK1[position] & chessboard[KING_BLACK + xside]; + ///pawn - attackers |= PAWN_FORK_MASK[side][position] & chessboard[PAWN_BLACK + (side ^ 1)]; - if (exitOnFirst && attackers) { - BENCH(Times::getInstance().stop("getAttackers")) - return attackers; - } + attackers |= PAWN_FORK_MASK[side][position] & chessboard[PAWN_BLACK + xside]; + ///bishop queen - u64 enemies = chessboard[BISHOP_BLACK + (side ^ 1)] | chessboard[QUEEN_BLACK + (side ^ 1)]; - u64 nuovo = Bitboard::getDiagonalAntiDiagonal(position, allpieces) & enemies; - for (; nuovo; RESET_LSB(nuovo)) { - const int bound = BITScanForward(nuovo); - attackers |= POW2[bound]; - if (exitOnFirst && attackers) { - BENCH(Times::getInstance().stop("getAttackers")) - return attackers; - } + u64 enemies = chessboard[BISHOP_BLACK + xside] | chessboard[QUEEN_BLACK + xside]; + u64 n = Bitboard::getDiagonalAntiDiagonal(position, allpieces) & enemies; + for (; n; RESET_LSB(n)) { + attackers |= POW2(BITScanForward(n)); } - enemies = chessboard[ROOK_BLACK + (side ^ 1)] | chessboard[QUEEN_BLACK + (side ^ 1)]; - nuovo = Bitboard::getRankFile(position, allpieces) & enemies; - for (; nuovo; RESET_LSB(nuovo)) { - const int bound = BITScanForward(nuovo); - attackers |= POW2[bound]; - if (exitOnFirst && attackers) { - BENCH(Times::getInstance().stop("getAttackers")) - return attackers; - } + enemies = chessboard[ROOK_BLACK + xside] | chessboard[QUEEN_BLACK + xside]; + n = Bitboard::getRankFile(position, allpieces) & enemies; + for (; n; RESET_LSB(n)) { + attackers |= POW2(BITScanForward(n)); } - BENCH(Times::getInstance().stop("getAttackers")) + return attackers; } - template + static bool isAttacked(const uchar side, const int position, const u64 allpieces, const _Tchessboard &chessboard) { + if (side == WHITE)return isAttacked < WHITE > (position, allpieces, chessboard); + return isAttacked < BLACK > (position, allpieces, chessboard); + } + + template static bool isAttacked(const int position, const u64 allpieces, const _Tchessboard &chessboard) { - return getAttackers(position, allpieces, chessboard); + BENCH_AUTO_CLOSE("isAttacked") + ASSERT_RANGE(position, 0, 63) + ASSERT_RANGE(side, 0, 1) + constexpr int xside = X(side); + ///knight + if (KNIGHT_MASK[position] & chessboard[KNIGHT_BLACK + xside]) { + return true; + } + + ///king + if (NEAR_MASK1[position] & chessboard[KING_BLACK + xside]) { + return true; + } + ///pawn + if (PAWN_FORK_MASK[side][position] & chessboard[PAWN_BLACK + xside]) { + return true; + } + + u64 enemies = chessboard[BISHOP_BLACK + xside] | chessboard[QUEEN_BLACK + xside]; + if ((DIAGONAL_ANTIDIAGONAL[position] & enemies)) { + ///bishop queen + if (Bitboard::getDiagonalAntiDiagonal(position, allpieces) & enemies) { + return true; + } + } + + enemies = chessboard[ROOK_BLACK + xside] | chessboard[QUEEN_BLACK + xside]; + if (!(RANK_FILE[position] & enemies)) return false; + if (Bitboard::getRankFile(position, allpieces) & enemies) { + return true; + } + return false; } - template + template static bool anyAttack(u64 sq, const u64 allpieces, const _Tchessboard &chessboard) { for (; sq; RESET_LSB(sq)) { - const int position = BITScanForward(sq); - if (getAttackers(position, allpieces, chessboard))return true; + if (isAttacked(BITScanForward(sq), allpieces, chessboard))return true; } return false; } - template + template static bool inCheck1(const _Tchessboard &chessboard) { return isAttacked(BITScanForward(chessboard[KING_BLACK + side]), getBitmap(chessboard) | getBitmap(chessboard), chessboard); } - template - static u64 getBitmapNoPawns(const _Tchessboard &chessboard) { - BENCH(Times::getInstance().start("getBitmapNoPawns")) - auto a = chessboard[ROOK_BLACK + side] | chessboard[BISHOP_BLACK + side] | chessboard[KNIGHT_BLACK + side] | - chessboard[KING_BLACK + side] | chessboard[QUEEN_BLACK + side]; - BENCH(Times::getInstance().stop("getBitmapNoPawns")) - return a; + template + static u64 getBitmapNoPawnsNoKing(const _Tchessboard &chessboard) { + BENCH_AUTO_CLOSE("getBitmapNoPawns") + return chessboard[ROOK_BLACK + side] | chessboard[BISHOP_BLACK + side] | chessboard[KNIGHT_BLACK + side] | + chessboard[QUEEN_BLACK + side]; } - template + template static u64 getPiecesNoKing(const _Tchessboard &chessboard) { + BENCH_AUTO_CLOSE("getPiecesNoKing") return chessboard[ROOK_BLACK + side] | chessboard[BISHOP_BLACK + side] | chessboard[KNIGHT_BLACK + side] | chessboard[PAWN_BLACK + side] | chessboard[QUEEN_BLACK + side]; } - template - static int getNpiecesNoPawnNoKing(const _Tchessboard &chessboard) { - return bitCount( - chessboard[ROOK_BLACK + side] | chessboard[BISHOP_BLACK + side] | chessboard[KNIGHT_BLACK + side] | - chessboard[QUEEN_BLACK + side]); - } }; diff --git a/src/namespaces/constants.h b/src/namespaces/constants.h index a7f64fdc..62519685 100644 --- a/src/namespaces/constants.h +++ b/src/namespaces/constants.h @@ -22,33 +22,68 @@ #include #include #include +#include using namespace std; namespace constants { - static const string NAME = "Cinnamon 2.3.4"; + static const string NAME = "Cinnamon 2.4"; static const string STARTPOS = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; static constexpr int BLACK = 0; static constexpr int WHITE = 1; + +#ifdef TUNING +#define STATIC_CONST +#else +#define STATIC_CONST static constexpr +#endif + +#define _assert(a) if(!(a)){ cout<(to)){cout<<"ASSERT_RANGE: "< BOARD = {"h1", "g1", "f1", "e1", "d1", "c1", "b1", "a1", "h2", "g2", "f2", "e2", "d2", "c2", "b2", "a2", "h3", "g3", @@ -237,8 +323,74 @@ namespace constants { static constexpr array BISHOP_HOME = {0x24ULL, 0x2400000000000000ULL}; static constexpr array KNIGHT_HOME = {0x4200000000000000ULL, 0x42ULL}; - static constexpr array RANK_1_7 = {0xff00ULL, 0xff000000000000ULL}; - + static constexpr array RANK_2_7 = {0xff000000000000ULL,0xff00ULL}; + static constexpr array RANK_1_8 = {0xff00000000000000ULL,0xffULL}; + /* + static constexpr uchar DISTANCE[64][64]{{0,1,2,3,4,5,6,7,1,1,2,3,4,5,6,7,2,2,2,3,4,5,6,7,3,3,3,3,4,5,6,7,4,4,4,4,4,5,6,7,5,5,5,5,5,5,6,7,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7}, + {1,0,1,2,3,4,5,6,1,1,1,2,3,4,5,6,2,2,2,2,3,4,5,6,3,3,3,3,3,4,5,6,4,4,4,4,4,4,5,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7}, + {2,1,0,1,2,3,4,5,2,1,1,1,2,3,4,5,2,2,2,2,2,3,4,5,3,3,3,3,3,3,4,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7}, + {3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7}, + {4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7}, + {5,4,3,2,1,0,1,2,5,4,3,2,1,1,1,2,5,4,3,2,2,2,2,2,5,4,3,3,3,3,3,3,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7}, + {6,5,4,3,2,1,0,1,6,5,4,3,2,1,1,1,6,5,4,3,2,2,2,2,6,5,4,3,3,3,3,3,6,5,4,4,4,4,4,4,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7}, + {7,6,5,4,3,2,1,0,7,6,5,4,3,2,1,1,7,6,5,4,3,2,2,2,7,6,5,4,3,3,3,3,7,6,5,4,4,4,4,4,7,6,5,5,5,5,5,5,7,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7}, + {1,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,1,1,2,3,4,5,6,7,2,2,2,3,4,5,6,7,3,3,3,3,4,5,6,7,4,4,4,4,4,5,6,7,5,5,5,5,5,5,6,7,6,6,6,6,6,6,6,7}, + {1,1,1,2,3,4,5,6,1,0,1,2,3,4,5,6,1,1,1,2,3,4,5,6,2,2,2,2,3,4,5,6,3,3,3,3,3,4,5,6,4,4,4,4,4,4,5,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6}, + {2,1,1,1,2,3,4,5,2,1,0,1,2,3,4,5,2,1,1,1,2,3,4,5,2,2,2,2,2,3,4,5,3,3,3,3,3,3,4,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6}, + {3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6}, + {4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6}, + {5,4,3,2,1,1,1,2,5,4,3,2,1,0,1,2,5,4,3,2,1,1,1,2,5,4,3,2,2,2,2,2,5,4,3,3,3,3,3,3,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6}, + {6,5,4,3,2,1,1,1,6,5,4,3,2,1,0,1,6,5,4,3,2,1,1,1,6,5,4,3,2,2,2,2,6,5,4,3,3,3,3,3,6,5,4,4,4,4,4,4,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6}, + {7,6,5,4,3,2,1,1,7,6,5,4,3,2,1,0,7,6,5,4,3,2,1,1,7,6,5,4,3,2,2,2,7,6,5,4,3,3,3,3,7,6,5,4,4,4,4,4,7,6,5,5,5,5,5,5,7,6,6,6,6,6,6,6}, + {2,2,2,3,4,5,6,7,1,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,1,1,2,3,4,5,6,7,2,2,2,3,4,5,6,7,3,3,3,3,4,5,6,7,4,4,4,4,4,5,6,7,5,5,5,5,5,5,6,7}, + {2,2,2,2,3,4,5,6,1,1,1,2,3,4,5,6,1,0,1,2,3,4,5,6,1,1,1,2,3,4,5,6,2,2,2,2,3,4,5,6,3,3,3,3,3,4,5,6,4,4,4,4,4,4,5,6,5,5,5,5,5,5,5,6}, + {2,2,2,2,2,3,4,5,2,1,1,1,2,3,4,5,2,1,0,1,2,3,4,5,2,1,1,1,2,3,4,5,2,2,2,2,2,3,4,5,3,3,3,3,3,3,4,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5}, + {3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5}, + {4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5}, + {5,4,3,2,2,2,2,2,5,4,3,2,1,1,1,2,5,4,3,2,1,0,1,2,5,4,3,2,1,1,1,2,5,4,3,2,2,2,2,2,5,4,3,3,3,3,3,3,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5}, + {6,5,4,3,2,2,2,2,6,5,4,3,2,1,1,1,6,5,4,3,2,1,0,1,6,5,4,3,2,1,1,1,6,5,4,3,2,2,2,2,6,5,4,3,3,3,3,3,6,5,4,4,4,4,4,4,6,5,5,5,5,5,5,5}, + {7,6,5,4,3,2,2,2,7,6,5,4,3,2,1,1,7,6,5,4,3,2,1,0,7,6,5,4,3,2,1,1,7,6,5,4,3,2,2,2,7,6,5,4,3,3,3,3,7,6,5,4,4,4,4,4,7,6,5,5,5,5,5,5}, + {3,3,3,3,4,5,6,7,2,2,2,3,4,5,6,7,1,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,1,1,2,3,4,5,6,7,2,2,2,3,4,5,6,7,3,3,3,3,4,5,6,7,4,4,4,4,4,5,6,7}, + {3,3,3,3,3,4,5,6,2,2,2,2,3,4,5,6,1,1,1,2,3,4,5,6,1,0,1,2,3,4,5,6,1,1,1,2,3,4,5,6,2,2,2,2,3,4,5,6,3,3,3,3,3,4,5,6,4,4,4,4,4,4,5,6}, + {3,3,3,3,3,3,4,5,2,2,2,2,2,3,4,5,2,1,1,1,2,3,4,5,2,1,0,1,2,3,4,5,2,1,1,1,2,3,4,5,2,2,2,2,2,3,4,5,3,3,3,3,3,3,4,5,4,4,4,4,4,4,4,5}, + {3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4}, + {4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4}, + {5,4,3,3,3,3,3,3,5,4,3,2,2,2,2,2,5,4,3,2,1,1,1,2,5,4,3,2,1,0,1,2,5,4,3,2,1,1,1,2,5,4,3,2,2,2,2,2,5,4,3,3,3,3,3,3,5,4,4,4,4,4,4,4}, + {6,5,4,3,3,3,3,3,6,5,4,3,2,2,2,2,6,5,4,3,2,1,1,1,6,5,4,3,2,1,0,1,6,5,4,3,2,1,1,1,6,5,4,3,2,2,2,2,6,5,4,3,3,3,3,3,6,5,4,4,4,4,4,4}, + {7,6,5,4,3,3,3,3,7,6,5,4,3,2,2,2,7,6,5,4,3,2,1,1,7,6,5,4,3,2,1,0,7,6,5,4,3,2,1,1,7,6,5,4,3,2,2,2,7,6,5,4,3,3,3,3,7,6,5,4,4,4,4,4}, + {4,4,4,4,4,5,6,7,3,3,3,3,4,5,6,7,2,2,2,3,4,5,6,7,1,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,1,1,2,3,4,5,6,7,2,2,2,3,4,5,6,7,3,3,3,3,4,5,6,7}, + {4,4,4,4,4,4,5,6,3,3,3,3,3,4,5,6,2,2,2,2,3,4,5,6,1,1,1,2,3,4,5,6,1,0,1,2,3,4,5,6,1,1,1,2,3,4,5,6,2,2,2,2,3,4,5,6,3,3,3,3,3,4,5,6}, + {4,4,4,4,4,4,4,5,3,3,3,3,3,3,4,5,2,2,2,2,2,3,4,5,2,1,1,1,2,3,4,5,2,1,0,1,2,3,4,5,2,1,1,1,2,3,4,5,2,2,2,2,2,3,4,5,3,3,3,3,3,3,4,5}, + {4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3,4}, + {4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4,3,3,3,3,3,3,3}, + {5,4,4,4,4,4,4,4,5,4,3,3,3,3,3,3,5,4,3,2,2,2,2,2,5,4,3,2,1,1,1,2,5,4,3,2,1,0,1,2,5,4,3,2,1,1,1,2,5,4,3,2,2,2,2,2,5,4,3,3,3,3,3,3}, + {6,5,4,4,4,4,4,4,6,5,4,3,3,3,3,3,6,5,4,3,2,2,2,2,6,5,4,3,2,1,1,1,6,5,4,3,2,1,0,1,6,5,4,3,2,1,1,1,6,5,4,3,2,2,2,2,6,5,4,3,3,3,3,3}, + {7,6,5,4,4,4,4,4,7,6,5,4,3,3,3,3,7,6,5,4,3,2,2,2,7,6,5,4,3,2,1,1,7,6,5,4,3,2,1,0,7,6,5,4,3,2,1,1,7,6,5,4,3,2,2,2,7,6,5,4,3,3,3,3}, + {5,5,5,5,5,5,6,7,4,4,4,4,4,5,6,7,3,3,3,3,4,5,6,7,2,2,2,3,4,5,6,7,1,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,1,1,2,3,4,5,6,7,2,2,2,3,4,5,6,7}, + {5,5,5,5,5,5,5,6,4,4,4,4,4,4,5,6,3,3,3,3,3,4,5,6,2,2,2,2,3,4,5,6,1,1,1,2,3,4,5,6,1,0,1,2,3,4,5,6,1,1,1,2,3,4,5,6,2,2,2,2,3,4,5,6}, + {5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,3,3,3,3,3,3,4,5,2,2,2,2,2,3,4,5,2,1,1,1,2,3,4,5,2,1,0,1,2,3,4,5,2,1,1,1,2,3,4,5,2,2,2,2,2,3,4,5}, + {5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3,4}, + {5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4,3,2,2,2,2,2,3}, + {5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,4,3,3,3,3,3,3,5,4,3,2,2,2,2,2,5,4,3,2,1,1,1,2,5,4,3,2,1,0,1,2,5,4,3,2,1,1,1,2,5,4,3,2,2,2,2,2}, + {6,5,5,5,5,5,5,5,6,5,4,4,4,4,4,4,6,5,4,3,3,3,3,3,6,5,4,3,2,2,2,2,6,5,4,3,2,1,1,1,6,5,4,3,2,1,0,1,6,5,4,3,2,1,1,1,6,5,4,3,2,2,2,2}, + {7,6,5,5,5,5,5,5,7,6,5,4,4,4,4,4,7,6,5,4,3,3,3,3,7,6,5,4,3,2,2,2,7,6,5,4,3,2,1,1,7,6,5,4,3,2,1,0,7,6,5,4,3,2,1,1,7,6,5,4,3,2,2,2}, + {6,6,6,6,6,6,6,7,5,5,5,5,5,5,6,7,4,4,4,4,4,5,6,7,3,3,3,3,4,5,6,7,2,2,2,3,4,5,6,7,1,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,1,1,2,3,4,5,6,7}, + {6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,4,4,4,4,4,4,5,6,3,3,3,3,3,4,5,6,2,2,2,2,3,4,5,6,1,1,1,2,3,4,5,6,1,0,1,2,3,4,5,6,1,1,1,2,3,4,5,6}, + {6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,3,3,3,3,3,3,4,5,2,2,2,2,2,3,4,5,2,1,1,1,2,3,4,5,2,1,0,1,2,3,4,5,2,1,1,1,2,3,4,5}, + {6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3,4}, + {6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,1,1,2,3}, + {6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,4,3,3,3,3,3,3,5,4,3,2,2,2,2,2,5,4,3,2,1,1,1,2,5,4,3,2,1,0,1,2,5,4,3,2,1,1,1,2}, + {6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,5,4,4,4,4,4,4,6,5,4,3,3,3,3,3,6,5,4,3,2,2,2,2,6,5,4,3,2,1,1,1,6,5,4,3,2,1,0,1,6,5,4,3,2,1,1,1}, + {7,6,6,6,6,6,6,6,7,6,5,5,5,5,5,5,7,6,5,4,4,4,4,4,7,6,5,4,3,3,3,3,7,6,5,4,3,2,2,2,7,6,5,4,3,2,1,1,7,6,5,4,3,2,1,0,7,6,5,4,3,2,1,1}, + {7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,7,5,5,5,5,5,5,6,7,4,4,4,4,4,5,6,7,3,3,3,3,4,5,6,7,2,2,2,3,4,5,6,7,1,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7}, + {7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,4,4,4,4,4,4,5,6,3,3,3,3,3,4,5,6,2,2,2,2,3,4,5,6,1,1,1,2,3,4,5,6,1,0,1,2,3,4,5,6}, + {7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,3,3,3,3,3,3,4,5,2,2,2,2,2,3,4,5,2,1,1,1,2,3,4,5,2,1,0,1,2,3,4,5}, + {7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3,4}, + {7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,2,2,2,2,2,3,4,3,2,1,1,1,2,3,4,3,2,1,0,1,2,3}, + {7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,4,3,3,3,3,3,3,5,4,3,2,2,2,2,2,5,4,3,2,1,1,1,2,5,4,3,2,1,0,1,2}, + {7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,5,4,4,4,4,4,4,6,5,4,3,3,3,3,3,6,5,4,3,2,2,2,2,6,5,4,3,2,1,1,1,6,5,4,3,2,1,0,1}, + {7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,7,6,5,5,5,5,5,5,7,6,5,4,4,4,4,4,7,6,5,4,3,3,3,3,7,6,5,4,3,2,2,2,7,6,5,4,3,2,1,1,7,6,5,4,3,2,1,0}}; +*/ static constexpr array INV_FEN = { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, @@ -274,6 +426,15 @@ namespace constants { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff }; + static constexpr array RANK_FILE_DIAG_ANTIDIAG ={0x81412111090503feULL, 0x2824222120a07fdULL, 0x404844424150efbULL, 0x8080888492a1cf7ULL, 0x10101011925438efULL, 0x2020212224a870dfULL, 0x404142444850e0bfULL, 0x8182848890a0c07fULL, + 0x412111090503fe03ULL, 0x824222120a07fd07ULL, 0x4844424150efb0eULL, 0x80888492a1cf71cULL, 0x101011925438ef38ULL, 0x20212224a870df70ULL, 0x4142444850e0bfe0ULL, 0x82848890a0c07fc0ULL, + 0x2111090503fe0305ULL, 0x4222120a07fd070aULL, 0x844424150efb0e15ULL, 0x888492a1cf71c2aULL, 0x1011925438ef3854ULL, 0x212224a870df70a8ULL, 0x42444850e0bfe050ULL, 0x848890a0c07fc0a0ULL, + 0x11090503fe030509ULL, 0x22120a07fd070a12ULL, 0x4424150efb0e1524ULL, 0x88492a1cf71c2a49ULL, 0x11925438ef385492ULL, 0x2224a870df70a824ULL, 0x444850e0bfe05048ULL, 0x8890a0c07fc0a090ULL, + 0x90503fe03050911ULL, 0x120a07fd070a1222ULL, 0x24150efb0e152444ULL, 0x492a1cf71c2a4988ULL, 0x925438ef38549211ULL, 0x24a870df70a82422ULL, 0x4850e0bfe0504844ULL, 0x90a0c07fc0a09088ULL, + 0x503fe0305091121ULL, 0xa07fd070a122242ULL, 0x150efb0e15244484ULL, 0x2a1cf71c2a498808ULL, 0x5438ef3854921110ULL, 0xa870df70a8242221ULL, 0x50e0bfe050484442ULL, 0xa0c07fc0a0908884ULL, + 0x3fe030509112141ULL, 0x7fd070a12224282ULL, 0xefb0e1524448404ULL, 0x1cf71c2a49880808ULL, 0x38ef385492111010ULL, 0x70df70a824222120ULL, 0xe0bfe05048444241ULL, 0xc07fc0a090888482ULL, + 0xfe03050911214181ULL, 0xfd070a1222428202ULL, 0xfb0e152444840404ULL, 0xf71c2a4988080808ULL, 0xef38549211101010ULL, 0xdf70a82422212020ULL, 0xbfe0504844424140ULL, 0x7fc0a09088848281ULL}; + static constexpr array RANK_BOUND = { 0x0000000000000002ULL, 0x0000000000000005ULL, 0x000000000000000aULL, 0x0000000000000014ULL, 0x0000000000000028ULL, 0x0000000000000050ULL, 0x00000000000000a0ULL, 0x0000000000000040ULL, @@ -365,7 +526,7 @@ namespace constants { static constexpr array FILE_AT = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7}; - +#ifndef USE_BMI2 static constexpr array RANK_ATx8 = {0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x0ULL, 0x8ULL, 0x8ULL, 0x8ULL, 0x8ULL, 0x8ULL, 0x8ULL, 0x8ULL, 0x8ULL, 0x10ULL, 0x10ULL, 0x10ULL, 0x10ULL, 0x10ULL, 0x10ULL, 0x10ULL, 0x10ULL, 0x18ULL, 0x18ULL, @@ -373,7 +534,7 @@ namespace constants { 0x20ULL, 0x20ULL, 0x28ULL, 0x28ULL, 0x28ULL, 0x28ULL, 0x28ULL, 0x28ULL, 0x28ULL, 0x28ULL, 0x30ULL, 0x30ULL, 0x30ULL, 0x30ULL, 0x30ULL, 0x30ULL, 0x30ULL, 0x30ULL, 0x38ULL, 0x38ULL, 0x38ULL, 0x38ULL, 0x38ULL, 0x38ULL, 0x38ULL, 0x38ULL}; - +#endif static constexpr array RANK_AT = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7}; @@ -411,37 +572,6 @@ namespace constants { 0x0101010101010101ULL, 0x0202020202020202ULL, 0x0404040404040404ULL, 0x0808080808080808ULL, 0x1010101010101010ULL, 0x2020202020202020ULL, 0x4040404040404040ULL, 0x8080808080808080ULL }; - static constexpr u64 POW2[64] = - {0x1ULL, 0x2ULL, 0x4ULL, 0x8ULL, 0x10ULL, 0x20ULL, 0x40ULL, 0x80ULL, 0x100ULL, 0x200ULL, 0x400ULL, 0x800ULL, - 0x1000ULL, 0x2000ULL, 0x4000ULL, 0x8000ULL, 0x10000ULL, 0x20000ULL, 0x40000ULL, 0x80000ULL, 0x100000ULL, - 0x200000ULL, 0x400000ULL, 0x800000ULL, 0x1000000ULL, 0x2000000ULL, 0x4000000ULL, 0x8000000ULL, 0x10000000ULL, - 0x20000000ULL, 0x40000000ULL, 0x80000000ULL, 0x100000000ULL, 0x200000000ULL, 0x400000000ULL, 0x800000000ULL, - 0x1000000000ULL, 0x2000000000ULL, 0x4000000000ULL, 0x8000000000ULL, 0x10000000000ULL, 0x20000000000ULL, - 0x40000000000ULL, 0x80000000000ULL, 0x100000000000ULL, 0x200000000000ULL, 0x400000000000ULL, 0x800000000000ULL, - 0x1000000000000ULL, 0x2000000000000ULL, 0x4000000000000ULL, 0x8000000000000ULL, 0x10000000000000ULL, - 0x20000000000000ULL, 0x40000000000000ULL, 0x80000000000000ULL, 0x100000000000000ULL, 0x200000000000000ULL, - 0x400000000000000ULL, 0x800000000000000ULL, 0x1000000000000000ULL, 0x2000000000000000ULL, - 0x4000000000000000ULL, 0x8000000000000000ULL}; - - static constexpr array NOTPOW2 = - {0xfffffffffffffffeULL, 0xfffffffffffffffdULL, 0xfffffffffffffffbULL, 0xfffffffffffffff7ULL, - 0xffffffffffffffefULL, 0xffffffffffffffdfULL, 0xffffffffffffffbfULL, 0xffffffffffffff7fULL, - 0xfffffffffffffeffULL, 0xfffffffffffffdffULL, 0xfffffffffffffbffULL, 0xfffffffffffff7ffULL, - 0xffffffffffffefffULL, 0xffffffffffffdfffULL, 0xffffffffffffbfffULL, 0xffffffffffff7fffULL, - 0xfffffffffffeffffULL, 0xfffffffffffdffffULL, 0xfffffffffffbffffULL, 0xfffffffffff7ffffULL, - 0xffffffffffefffffULL, 0xffffffffffdfffffULL, 0xffffffffffbfffffULL, 0xffffffffff7fffffULL, - 0xfffffffffeffffffULL, 0xfffffffffdffffffULL, 0xfffffffffbffffffULL, 0xfffffffff7ffffffULL, - 0xffffffffefffffffULL, 0xffffffffdfffffffULL, 0xffffffffbfffffffULL, 0xffffffff7fffffffULL, - 0xfffffffeffffffffULL, 0xfffffffdffffffffULL, 0xfffffffbffffffffULL, 0xfffffff7ffffffffULL, - 0xffffffefffffffffULL, 0xffffffdfffffffffULL, 0xffffffbfffffffffULL, 0xffffff7fffffffffULL, - 0xfffffeffffffffffULL, 0xfffffdffffffffffULL, 0xfffffbffffffffffULL, 0xfffff7ffffffffffULL, - 0xffffefffffffffffULL, 0xffffdfffffffffffULL, 0xffffbfffffffffffULL, - 0xffff7fffffffffffULL, 0xfffeffffffffffffULL, 0xfffdffffffffffffULL, 0xfffbffffffffffffULL, - 0xfff7ffffffffffffULL, 0xffefffffffffffffULL, 0xffdfffffffffffffULL, 0xffbfffffffffffffULL, - 0xff7fffffffffffffULL, 0xfeffffffffffffffULL, 0xfdffffffffffffffULL, 0xfbffffffffffffffULL, - 0xf7ffffffffffffffULL, 0xefffffffffffffffULL, 0xdfffffffffffffffULL, 0xbfffffffffffffffULL, - 0x7fffffffffffffffULL}; - static constexpr u64 LINES[64][64]{ {0x0ULL, 0xffULL, 0xffULL, 0xffULL, 0xffULL, 0xffULL, 0xffULL, 0xffULL, 0x101010101010101ULL, @@ -1508,4 +1638,10 @@ namespace constants { 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0}}}; +#ifdef MVSC +#define FOLDERSEP "\\" +#else +#define FOLDERSEP "/" +#endif + } diff --git a/src/namespaces/debug.h b/src/namespaces/debug.h deleted file mode 100644 index 2a2999e6..00000000 --- a/src/namespaces/debug.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Cinnamon UCI chess engine - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#pragma once - -#if defined(_WIN32) || !defined(DEBUG_MODE) || defined(JS_MODE) - -namespace _debug { - - static inline void print_stacktrace() { } -} -#else - -#include -#include - -namespace _debug { - - /// (c) 2008, Timo Bingmann from http://idlebox.net/ - /// published under the WTFPL v2.0 - // Print a demangled stack backtrace of the caller function to FILE* out. - static inline void print_stacktrace(FILE *out = stdout, unsigned int max_frames = 512) { - fprintf(out, "stack trace:\n"); - // storage array for stack trace address data - void **addrlist = (void **) malloc(max_frames + 1); - // retrieve current stack addresses - int addrlen = backtrace(addrlist, max_frames + 1); - if (addrlen == 0) { - fprintf(out, " \n"); - free(addrlist); - return; - } - // resolve addresses into strings containing "filename(function+address)", - // this array must be free()-ed - char **symbollist = backtrace_symbols(addrlist, addrlen); - // allocate string which will be filled with the demangled function name - size_t funcnamesize = 256; - char *funcname = (char *) malloc(funcnamesize); - // iterate over the returned symbol lines. skip the first, it is the - // address of this function. - for (int i = 1; i < addrlen; i++) { - char *begin_name = 0, *begin_offset = 0, *end_offset = 0; - // find parentheses and +address offset surrounding the mangled name: - // ./module(function+0x15c) [0x8048a6d] - for (char *p = symbollist[i]; *p; ++p) { - if (*p == '(') { - begin_name = p; - } else if (*p == '+') { - begin_offset = p; - } else if (*p == ')' && begin_offset) { - end_offset = p; - break; - } - } - if (begin_name && begin_offset && end_offset && begin_name < begin_offset) { - *begin_name++ = '\0'; - *begin_offset++ = '\0'; - *end_offset = '\0'; - // mangled name is now in [begin_name, begin_offset) and caller - // offset in [begin_offset, end_offset). now apply - // __cxa_demangle(): - int status; - char *ret = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status); - if (status == 0) { - funcname = ret; // use possibly realloc()-ed string - fprintf(out, " %s+%s\n", funcname, begin_offset); - } else { - // demangling failed. Output function name as a C function with - // no arguments. - fprintf(out, " %s : %s()+%s\n", symbollist[i], begin_name, begin_offset); - } - } else { - // couldn't parse the line? print the whole line. - fprintf(out, " %s\n", symbollist[i]); - } - } - free(funcname); - free(symbollist); - free(addrlist); - } -} - -#endif diff --git a/src/namespaces/random.inc b/src/namespaces/random.inc index 1e07de63..89f82cf3 100644 --- a/src/namespaces/random.inc +++ b/src/namespaces/random.inc @@ -1,4 +1,71 @@ -static constexpr u64 RANDOM_KEY[15][64] = { +static constexpr u64 RANDOM_KEY[16][64] = { +{ + +0xbab84dfcca7a5751ull, +0xd36db76b5122e81bull, +0x9db50ea32bb448cfull, +0x010e7d96133b601eull, +0xd339a301a4c4d993ull, +0x670d3a1898511cdcull, +0x49c36f2a0d0de531ull, +0x05573106ebeb4448ull, +0x07eb460b7be523faull, +0x97c16733262d257full, +0xd57168bc83d48297ull, +0xe115aa501d675a49ull, +0xc83fd3e08f438d7aull, +0x7e76b3ceab0f60a5ull, +0xad04961d4eccf55eull, +0xa594e54ec84d1ca9ull, +0xda0a661f3fd1e438ull, +0x9c8c27108d4e2652ull, +0x6130bd5600454c11ull, +0xfed385ea9e1b05f2ull, +0x8b4bdf895d48cc70ull, +0xb92f82b02400b2d8ull, +0xa04244282cb817b4ull, +0xe5bbafe1796ffd8cull, +0xea154754e8157a1aull, +0x08e2558ff86fe30dull, +0x0ae17929227792caull, +0x396934d4a0f4d1d8ull, +0x147b5a941c871959ull, +0xee3d72df0a9d8664ull, +0x2429065c3f659db8ull, +0x9a61130b6db44b91ull, +0x9d366c51341f58abull, +0x6f62cb00df9dfdfaull, +0x2402977c85d0ef6full, +0xd1d3d247fe8dc002ull, +0xb4a15a55d798ef3dull, +0xf436f8574f7d1e2bull, +0x845b0cb6930c500full, +0x41e7dc5a0b1d279eull, +0x034971e723902b92ull, +0x4c9eb2358c591149ull, +0x5c6e93aea3a819ffull, +0x61fc1c4fdacf04aeull, +0xafcc48194c9a8367ull, +0x9933d53792ba7ef6ull, +0x82a4880b3229091cull, +0x3cbdb0f25f0f3c6cull, +0x180fabbe872f80e3ull, +0xd41733bad22abe77ull, +0x8209150305ea5448ull, +0xf2ab660033e000c4ull, +0xccf5a2dae0bb8995ull, +0xe07695635f60e0cbull, +0xa05b670af1b8a99dull, +0xd0534cbf64d49966ull, +0x6d6ddfa5a4e1c282ull, +0x2cffc6c1507e821aull, +0x884a11ca7e1c292cull, +0xa6c60ba7163eea44ull, +0x9b18f686da63dee9ull, +0x28bf8ce72c229eb1ull, +0xfbf9cc7ad33273aaull, +0x9e6cb64001bad6a0ull +}, { 0x9D39247E33776D41ULL, 0x2AF7398005AAA5C7ULL, 0x44DB015024623547ULL, 0x9C15F73E62A76AE2ULL, 0x75834465489C0C89ULL, 0x3290AC3A203001BFULL, 0x0FBBAD1F61042279ULL, 0xE83A908FF2FB60CAULL, diff --git a/src/perft/Perft.cpp b/src/perft/Perft.cpp index 05738497..0f2e2576 100644 --- a/src/perft/Perft.cpp +++ b/src/perft/Perft.cpp @@ -23,11 +23,9 @@ _ThashPerft **Perft::hash = nullptr; bool Perft::dumping; void Perft::dump() { - if (dumping || dumpFile.empty() || !hash) { - return; - } + if (depthHashFile > perftRes.depth) return; + if (dumping || dumpFile.empty() || !hash) return; dumping = true; - cout << endl << "Dump hash table in " << dumpFile << " file..." << flush; ofstream f; string tmpFile = dumpFile + ".tmp"; @@ -38,6 +36,9 @@ void Perft::dump() { } sleepAll(true); + f << NAME; + f.put(10); + f << "1"; //version f.put(10); f << fen; f.put(10); @@ -60,26 +61,33 @@ bool Perft::load() { } ifstream f; string fen1; - int nCpuHash, depthHash; - u64 mbSizeHash; + string perftVersion; + int nCpuHash; + if (!FileUtil::fileExists(dumpFile)) { return false; } f.open(dumpFile, ios_base::in | ios_base::binary); cout << endl << "load hash table from " << dumpFile << " file.." << endl; - string detailType; - getline(f, detailType); + getline(f, fen1);//name + getline(f, perftVersion); getline(f, fen1); - f.read(reinterpret_cast(&depthHash), sizeof(int)); - if (depthHash > perftRes.depth) { - fatal("error depth < hash depth"); - f.close(); - std::exit(0); - }; + cout << " Fen: " << fen1 << endl; + cout << " Perft version: " << perftVersion << endl; + + cout << " Depth: " << perftRes.depth << endl; + cout << flush; + f.read(reinterpret_cast(&depthHashFile), sizeof(int)); +// if (depthHash > perftRes.depth) { +// fatal("File wrong, depth < hash depth") +// f.close(); +// std::exit(1); +// } f.read(reinterpret_cast(&nCpuHash), sizeof(int)); - f.read(reinterpret_cast(&mbSizeHash), sizeof(u64)); - + f.read(reinterpret_cast(&mbSize), sizeof(u64)); + cout << " Hash size (MB): " << mbSize << endl; + cout << flush; alloc(); if (fen.empty()) { fen = fen1; @@ -87,12 +95,9 @@ bool Perft::load() { if (!perftRes.nCpu) { perftRes.nCpu = nCpuHash; } - cout << " fen: " << fen << endl; - cout << " mbSize: " << mbSize << endl; - cout << " depth: " << perftRes.depth << endl; - cout << " nCpu: " << perftRes.nCpu << endl; +// cout << " #cpu: " << perftRes.nCpu << endl; - for (int i = 1; i <= depthHash; i++) { + for (int i = 1; i <= depthHashFile; i++) { f.read(reinterpret_cast(hash[i]), perftRes.sizeAtDepth[i] * sizeof(_ThashPerft)); } f.close(); @@ -117,12 +122,12 @@ void Perft::dealloc() const { void Perft::alloc() { dealloc(); hash = (_ThashPerft **) calloc(perftRes.depth + 1, sizeof(_ThashPerft *)); - _assert(hash); - const u64 k = 1024 * 1024 * mbSize / POW2[perftRes.depth]; + _assert(hash) + const u64 k = 1024 * 1024 * mbSize / POW2(perftRes.depth); for (int i = 1; i <= perftRes.depth; i++) { - perftRes.sizeAtDepth[i] = k * POW2[i - 1] / sizeof(_ThashPerft); + perftRes.sizeAtDepth[i] = k * POW2(i - 1) / sizeof(_ThashPerft); hash[i] = (_ThashPerft *) calloc(perftRes.sizeAtDepth[i], sizeof(_ThashPerft)); - _assert(hash[i]); + _assert(hash[i]) DEBUG(cout << "alloc hash[" << i << "] " << perftRes.sizeAtDepth[i] * sizeof(_ThashPerft) << endl) @@ -168,7 +173,7 @@ void Perft::run() { p->loadFen(fen); } p->setPerft(true); - int side = board::getSide(p->getChessboard()) ? 1 : 0; + uchar side = p->sideToMove; p->display(); cout << "fen:\t\t\t" << fen << endl; @@ -176,7 +181,7 @@ void Perft::run() { cout << "#cpu:\t\t\t" << perftRes.nCpu << endl; cout << "cache size:\t\t" << mbSize << endl; cout << "dump file:\t\t" << dumpFile << endl; - cout << "chess960:\t\t" << chess960 << endl; + cout << "chess960:\t\t" << (chess960 ? "true" : "false") << endl; cout << endl << Time::getLocalTime() << " start perft test..." << endl; Timer t2(minutesToDump * 60); @@ -203,7 +208,7 @@ void Perft::run() { count = listcount; delete (p); p = nullptr; - ASSERT(perftRes.nCpu > 0); + assert(perftRes.nCpu > 0); int block = listcount / perftRes.nCpu; int i, s = 0; setNthread(perftRes.nCpu); @@ -221,15 +226,16 @@ void Perft::run() { void Perft::endRun() { time.stop(); - int t = time.getMill() / 1000; - + const double t = time.getMill() / 1000.0; cout << endl << endl << "Perft moves: " << perftRes.totMoves; - cout << " in " << t << " seconds"; - if (t) { - cout << " (" << (perftRes.totMoves / t) / 1000 - ((perftRes.totMoves / t) / 1000) % 1000 << - "k nodes per seconds" << ")"; + if (t > 60 * 60) cout << " in " << (t / 60.0) << " minutes"; + else cout << " in " << t << " seconds"; + + if ((perftRes.totMoves / t) / 1000.0 <= 1000.0) + cout << " (" << round((perftRes.totMoves / t) / 1000.0) << " K nodes per seconds" << ")"; + cout << " (" << round((perftRes.totMoves / t) / 1000000.0) << " M nodes per seconds" << ")"; } cout << endl; dump(); @@ -237,11 +243,6 @@ void Perft::endRun() { cerr << flush; -#ifdef BENCH_MODE - - Times *times = &Times::getInstance(); - times->print(); - -#endif + BENCH_PRINT() } diff --git a/src/perft/Perft.h b/src/perft/Perft.h index abdfe216..ef377260 100644 --- a/src/perft/Perft.h +++ b/src/perft/Perft.h @@ -22,14 +22,14 @@ #include #include #include -#include +#include "../unistd.h" #include "../util/Timer.h" #include "PerftThread.h" #include "../threadPool/ThreadPool.h" #include "_TPerftRes.h" #include -class Perft : public Thread, public ThreadPool, public Singleton { +class Perft : public Thread, protected ThreadPool, public Singleton { friend class Singleton; public: @@ -57,15 +57,15 @@ class Perft : public Thread, public ThreadPool, public Singl } private: - Perft() : ThreadPool(1) {}; + Perft() : ThreadPool(1) {} _TPerftRes perftRes; Time time; string fen; string dumpFile; - u64 mbSize; + int mbSize; bool chess960; - + int depthHashFile; void alloc(); void dealloc() const; @@ -76,11 +76,12 @@ class Perft : public Thread, public ThreadPool, public Singl static void ctrlChandler(int s) { if (dumping) { - cout << "dumping hash... " << endl; + cout << "dumping hash... " << endl << flush; return; } - Perft::getInstance().dump(); if (s < 0)cout << s; + Perft::getInstance().dump(); + cout << "exit" << endl << endl; exit(0); } diff --git a/src/perft/PerftThread.cpp b/src/perft/PerftThread.cpp index c398dfdb..efb7057d 100644 --- a/src/perft/PerftThread.cpp +++ b/src/perft/PerftThread.cpp @@ -33,18 +33,17 @@ void PerftThread::setParam(const string &fen1, const int from1, const int to1, _ unsigned PerftThread::perft(const string &fen, const int depth) { loadFen(fen); - if (board::getSide(chessboard)) return search(depth); + if (sideToMove) return search(depth); return search(depth); } vector PerftThread::getSuccessorsFen(const string &fen1, const int depth) { loadFen(fen1); - if (board::getSide(chessboard)) return getSuccessorsFen(depth); + if (sideToMove) return getSuccessorsFen(depth); return getSuccessorsFen(depth); } - -template +template vector PerftThread::getSuccessorsFen(const int depthx) { if (depthx == 0) { vector a; @@ -58,9 +57,8 @@ vector PerftThread::getSuccessorsFen(const int depthx) { _Tmove *move; incListId(); u64 friends = board::getBitmap(chessboard); - u64 enemies = board::getBitmap(chessboard); + u64 enemies = board::getBitmap(chessboard); generateCaptures(enemies, friends); - generateMoves(friends | enemies); listcount = getListSize(); if (!listcount) { @@ -70,13 +68,14 @@ vector PerftThread::getSuccessorsFen(const int depthx) { } for (int ii = 0; ii < listcount; ii++) { move = getMove(ii); - u64 keyold = chessboard[ZOBRISTKEY_IDX]; + const u64 keyold = chessboard[ZOBRISTKEY_IDX]; + const uchar oldEnpassant = enPassant; makemove(move, false, false); - setSide(side ^ 1); - vector bb = getSuccessorsFen(depthx - 1); + setSide(X(side)); + vector bb = getSuccessorsFen(depthx - 1); n_perft.insert(n_perft.end(), bb.begin(), bb.end()); - takeback(move, keyold, false); - setSide(side ^ 1); + takeback(move, keyold, oldEnpassant, false); + setSide(X(side)); } decListId(); @@ -84,14 +83,24 @@ vector PerftThread::getSuccessorsFen(const int depthx) { } -template +template u64 PerftThread::search(const int depthx) { checkWait(); - if (depthx == 0) { - return 1; + if (depthx == 0) return 1; + + if (depthx == 1) { + const u64 friends = board::getBitmap(chessboard); + const u64 enemies = board::getBitmap(chessboard); + incListId(); + generateCaptures(enemies, friends); + generateMoves(enemies | friends); + + const int listcount = getListSize(); + decListId(); + return listcount; } u64 zobristKeyR; - u64 n_perft = 0; + u64 nPerft = 0; _ThashPerft *phashe = nullptr; if (useHash) { @@ -100,36 +109,31 @@ u64 PerftThread::search(const int depthx) { const auto k = phashe->key; const auto d = phashe->nMoves; if (zobristKeyR == (k ^ d)) { - partialTot += d; return d; } } - int listcount; - _Tmove *move; + incListId(); - u64 friends = board::getBitmap(chessboard); - u64 enemies = board::getBitmap(chessboard); + const u64 friends = board::getBitmap(chessboard); + const u64 enemies = board::getBitmap(chessboard); generateCaptures(enemies, friends); - generateMoves(friends | enemies); - listcount = getListSize(); - if (!listcount) { - decListId(); - return 0; - } + const int listcount = getListSize(); + _Tmove *move; for (int ii = 0; ii < listcount; ii++) { move = getMove(ii); - u64 keyold = chessboard[ZOBRISTKEY_IDX]; + const u64 keyold = chessboard[ZOBRISTKEY_IDX]; + const uchar oldEnpassant = enPassant; makemove(move, false, false); - n_perft += search(depthx - 1); - takeback(move, keyold, false); + nPerft += search(depthx - 1); + takeback(move, keyold, oldEnpassant, false); } decListId(); if (useHash) { - phashe->key = (zobristKeyR ^ n_perft); - phashe->nMoves = n_perft; + phashe->key = (zobristKeyR ^ nPerft); + phashe->nMoves = nPerft; } - return n_perft; + return nPerft; } void PerftThread::endRun() { @@ -141,19 +145,22 @@ void PerftThread::run() { _Tmove *move; incListId(); resetList(); - const u64 friends = chessboard[SIDETOMOVE_IDX] ? board::getBitmap(chessboard) : board::getBitmap(chessboard); - const u64 enemies = chessboard[SIDETOMOVE_IDX] ? board::getBitmap(chessboard) : board::getBitmap(chessboard); - generateCaptures(chessboard[SIDETOMOVE_IDX], enemies, friends); - generateMoves(chessboard[SIDETOMOVE_IDX], friends | enemies); + const u64 friends = sideToMove ? board::getBitmap(chessboard) : board::getBitmap( + chessboard); + const u64 enemies = sideToMove ? board::getBitmap(chessboard) : board::getBitmap( + chessboard); + generateCaptures(sideToMove, enemies, friends); + generateMoves(sideToMove, friends | enemies); makeZobristKey(); const u64 keyold = chessboard[ZOBRISTKEY_IDX]; + const uchar oldEnpassant = enPassant; for (int ii = from; ii <= to - 1; ii++) { u64 n_perft; move = getMove(ii); makemove(move, false, false); bool fhash = Perft::hash != nullptr; - bool side = (chessboard[SIDETOMOVE_IDX] ^ 1); + bool side = X(sideToMove); if (fhash) { n_perft = side == WHITE ? search(tPerftRes->depth - 1) : search( @@ -163,30 +170,23 @@ void PerftThread::run() { tPerftRes->depth - 1); } - takeback(move, keyold, false); + takeback(move, keyold, oldEnpassant, false); - char x = FEN_PIECE[chessboard[SIDETOMOVE_IDX] ? board::getPieceAt(POW2[move->s.from], chessboard) - : board::getPieceAt(POW2[move->s.from], chessboard)]; - if (x == 'p' || x == 'P') { - x = ' '; - } - char y; - if (move->s.capturedPiece != SQUARE_EMPTY) { - y = '*'; - } else { - y = '-'; - } + char x = FEN_PIECE[sideToMove ? board::getPieceAt(POW2(move->from), chessboard) + : board::getPieceAt(POW2(move->from), chessboard)]; + x = toupper(x); + if (x == 'P') x = ' '; + const char y = (move->capturedPiece != SQUARE_EMPTY) ? '*' : '-'; if (fhash)spinlockPrint.lock(); cout << endl; string h; - if ((decodeBoardinv(move->s.type, move->s.to, chessboard[SIDETOMOVE_IDX])).length() > 2) { - - h = decodeBoardinv(move->s.type, move->s.to, chessboard[SIDETOMOVE_IDX]); + if ((decodeBoardinv(move->type, move->to, sideToMove)).length() > 2) { + h = decodeBoardinv(move->type, move->to, sideToMove); } else { - h = h + x + decodeBoardinv(move->s.type, move->s.from, chessboard[SIDETOMOVE_IDX]) + y - + decodeBoardinv(move->s.type, move->s.to, chessboard[SIDETOMOVE_IDX]); + h = h + x + decodeBoardinv(move->type, move->from, sideToMove) + y + + decodeBoardinv(move->type, move->to, sideToMove); } cout << setw(6) << h; cout << setw(20) << n_perft; @@ -202,6 +202,3 @@ void PerftThread::run() { PerftThread::~PerftThread() { } -u64 PerftThread::getPartial() { - return partialTot; -} diff --git a/src/perft/PerftThread.h b/src/perft/PerftThread.h index 36e9d0d4..fdfbcbe3 100644 --- a/src/perft/PerftThread.h +++ b/src/perft/PerftThread.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include "../unistd.h" #include "../util/Timer.h" class PerftThread: public Thread, public GenMoves { @@ -40,8 +40,6 @@ class PerftThread: public Thread, public GenMoves { void endRun(); - u64 getPartial(); - unsigned perft(const string &fen, const int depth); vector getSuccessorsFen(const string &fen1, const int depth); @@ -51,14 +49,13 @@ class PerftThread: public Thread, public GenMoves { static Spinlock spinlockPrint; u64 tot = 0; - template + template u64 search(const int depthx); int from, to; _TPerftRes *tPerftRes; - u64 partialTot = 0; - template + template vector getSuccessorsFen(const int depthx); }; diff --git a/src/test/eval.cpp b/src/test/eval.cpp index 7d6b1b82..bf3b2de0 100644 --- a/src/test/eval.cpp +++ b/src/test/eval.cpp @@ -24,9 +24,9 @@ TEST(eval, eval1) { SearchManager &searchManager = Singleton::getInstance(); searchManager.loadFen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); - int score = searchManager.getScore(WHITE, false); + int score = searchManager.getScore(WHITE); EXPECT_EQ(5, score); - score = searchManager.getScore(BLACK, false); + score = searchManager.getScore(BLACK); EXPECT_EQ(-5, score); } diff --git a/src/test/fileUtil.cpp b/src/test/fileUtil.cpp index 8c88da67..f54c7231 100644 --- a/src/test/fileUtil.cpp +++ b/src/test/fileUtil.cpp @@ -20,8 +20,11 @@ #include -TEST(FileUtilTest, getFileName) { +TEST(FileUtilTest, getFileName1) { ASSERT_EQ("c.txt", FileUtil::getFileName("c:\\a\\b\\c.txt")); +} + +TEST(FileUtilTest, getFileName2) { ASSERT_EQ("c.txt", FileUtil::getFileName("/a/b/c.txt")); } diff --git a/src/test/perft.cpp b/src/test/perft.cpp index ea908550..9568f081 100644 --- a/src/test/perft.cpp +++ b/src/test/perft.cpp @@ -21,7 +21,23 @@ #include #include "../perft/Perft.h" +TEST(perftTest, one) { + Perft *perft = &Perft::getInstance(); + perft->setParam(STARTPOS, 1, 1, 0, "",false); + perft->start(); + perft->join(); + ASSERT_EQ(20, perft->getResult()); +} + TEST(perftTest, oneCore) { + Perft *perft = &Perft::getInstance(); + perft->setParam("4k2r/3bbp2/p1p1p1p1/4B3/4n2r/PP3B2/2P2P1P/R3K2R w KQk - 0 13", 4, 1, 0, "",false); + perft->start(); + perft->join(); + ASSERT_EQ(1360065, perft->getResult()); +} + +TEST(perftTest, oneCore2) { Perft *perft = &Perft::getInstance(); perft->setParam("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1", 3, 1, 0, "",false); perft->start(); @@ -38,7 +54,6 @@ TEST(perftTest, twoCore) { ASSERT_EQ(97862, perft->getResult()); } -#ifdef FULL_TEST TEST(perftTest, fullTest) { Perft *perft = &Perft::getInstance(); perft->setParam("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1", 6, 4, 1000, "",false); @@ -47,5 +62,4 @@ TEST(perftTest, fullTest) { ASSERT_EQ(8031647685, perft->getResult()); } -#endif #endif \ No newline at end of file diff --git a/src/test/pin.cpp b/src/test/pin.cpp index 9800187c..1f21ad36 100644 --- a/src/test/pin.cpp +++ b/src/test/pin.cpp @@ -21,7 +21,7 @@ #include #include "../IterativeDeeping.h" -TEST(pin, test1) { +TEST(pin, pin1) { IterativeDeeping it; SearchManager &searchManager = Singleton::getInstance(); u64 friends, enemies, p; @@ -30,49 +30,49 @@ TEST(pin, test1) { it.loadFen("r3k2r/p1ppqpb1/Bn2pnp1/3PN3/1p2P3/2N2Q2/PPPB1PpP/R3K2R w KQkq - 0 1"); friends = searchManager.getBitmap(0, BLACK); enemies = searchManager.getBitmap(0, WHITE); - kingPosition = BITScanForward(searchManager.getChessboard(0)[KING_BLACK]); + kingPosition = BITScanForward(searchManager.getChessboard()[KING_BLACK]); p = searchManager.getPinned(enemies | friends, friends, kingPosition); EXPECT_EQ(0, p); it.loadFen("rnbq1bnr/pppppkpp/8/5p2/4P2P/5Q2/PPPP1PP1/RNB1KBNR b KQ - 0 1"); friends = searchManager.getBitmap(0, BLACK); enemies = searchManager.getBitmap(0, WHITE); - kingPosition = BITScanForward(searchManager.getChessboard(0)[KING_BLACK]); + kingPosition = BITScanForward(searchManager.getChessboard()[KING_BLACK]); p = searchManager.getPinned(enemies | friends, friends, kingPosition); EXPECT_EQ(0x400000000ULL, p); it.loadFen("r3k2r/p1ppqpb1/1n2pnp1/3PN3/1p2P3/2Nb1Q1p/PPPBBPPP/R4K1R w kq - 0 1"); friends = searchManager.getBitmap(0, WHITE); enemies = searchManager.getBitmap(0, BLACK); - kingPosition = BITScanForward(searchManager.getChessboard(0)[KING_WHITE]); + kingPosition = BITScanForward(searchManager.getChessboard()[KING_WHITE]); p = searchManager.getPinned(enemies | friends, friends, kingPosition); EXPECT_EQ(0x800ULL, p); it.loadFen("rn4k1/pp3ppp/2B5/3p4/3P4/8/PPPBb3/RN5K w - - 0 1"); friends = searchManager.getBitmap(0, WHITE); enemies = searchManager.getBitmap(0, BLACK); - kingPosition = BITScanForward(searchManager.getChessboard(0)[KING_WHITE]); + kingPosition = BITScanForward(searchManager.getChessboard()[KING_WHITE]); p = searchManager.getPinned(enemies | friends, friends, kingPosition); EXPECT_EQ(0, p); it.loadFen("rnK3nk/ppB2pp1/1bp1P3/b4q2/6p1/2P4b/PP2PP1P/RN3BNR w - - 0 1"); friends = searchManager.getBitmap(0, WHITE); enemies = searchManager.getBitmap(0, BLACK); - kingPosition = BITScanForward(searchManager.getChessboard(0)[KING_WHITE]); + kingPosition = BITScanForward(searchManager.getChessboard()[KING_WHITE]); p = searchManager.getPinned(enemies | friends, friends, kingPosition); EXPECT_EQ(0x80000000000ULL, p); it.loadFen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); friends = searchManager.getBitmap(0, WHITE); enemies = searchManager.getBitmap(0, BLACK); - kingPosition = BITScanForward(searchManager.getChessboard(0)[KING_WHITE]); + kingPosition = BITScanForward(searchManager.getChessboard()[KING_WHITE]); p = searchManager.getPinned(enemies | friends, friends, kingPosition); EXPECT_EQ(0, p); it.loadFen("r3k2r/p1pp1pb1/1n2pnp1/3PN3/1p2P3/2Nb1q1p/PPPBBPPP/R4K1R w kq - 0 1"); friends = searchManager.getBitmap(0, WHITE); enemies = searchManager.getBitmap(0, BLACK); - kingPosition = BITScanForward(searchManager.getChessboard(0)[KING_WHITE]); + kingPosition = BITScanForward(searchManager.getChessboard()[KING_WHITE]); p = searchManager.getPinned(enemies | friends, friends, kingPosition); EXPECT_EQ(0xc00ULL, p); diff --git a/src/test/search.cpp b/src/test/search.cpp index 253bab90..2270abda 100644 --- a/src/test/search.cpp +++ b/src/test/search.cpp @@ -22,15 +22,15 @@ #include "../IterativeDeeping.h" #include "../def.h" - TEST(search, test0) { + const set v = {"e3g5", "f6g5"}; IterativeDeeping it; it.loadFen("8/pp6/5p1k/2P3Pp/P1P4K/4q1PP/8/6Q1 b - - 0 35"); SearchManager &searchManager = Singleton::getInstance(); searchManager.setMaxTimeMillsec(250); it.start(); it.join(); - EXPECT_EQ("e3g5", it.getBestmove()); + EXPECT_TRUE(v.end() != v.find(it.getBestmove())); } TEST(search, test1) { @@ -61,17 +61,37 @@ TEST(search, test2) { EXPECT_NE("d6d3", it.getBestmove()); } -TEST(search, twoCore) { - const set v = {"d2d4", "e2e4", "e2e3", "b1c3", "g1f3"}; +TEST(search, fourCore) { + const set v = {"c2c3", "d2d3", "d2d4", "e2e4", "e2e3", "b1c3", "g1f3", "g2g3", "g2g4", "f2f4"}; IterativeDeeping it; - it.setNthread(2); SearchManager &searchManager = Singleton::getInstance(); searchManager.setMaxTimeMillsec(250); + searchManager.setNthread(4); it.setMaxDepth(MAX_PLY); it.start(); it.join(); - cout << "twoCore res: " << it.getBestmove() << endl; + cout << "fourCore res: " << it.getBestmove() << endl; EXPECT_TRUE(v.end() != v.find(it.getBestmove())); } +TEST(search, ep) { + IterativeDeeping it; + it.loadFen("7r/1pk5/p3p1p1/2PqPp2/1P3PKb/P3Q2P/5B1P/2R5 w - f6 0 40"); + it.start(); + it.join(); + EXPECT_EQ("e5f6", it.getBestmove()); +} + +TEST(search, enpassant) { + IterativeDeeping it; + it.loadFen("4r1k1/8/8/8/3pP3/8/3Q1K2/8 b - e3 0 27"); + SearchManager &searchManager = Singleton::getInstance(); + searchManager.setMaxTimeMillsec(1000); + it.setMaxDepth(5); + it.start(); + it.join(); + EXPECT_EQ("d4e3", it.getBestmove()); +} + + #endif \ No newline at end of file diff --git a/src/test/stalemate.cpp b/src/test/stalemate.cpp new file mode 100644 index 00000000..4ffdedd8 --- /dev/null +++ b/src/test/stalemate.cpp @@ -0,0 +1,55 @@ +/* + Cinnamon UCI chess engine + Copyright (C) Giuseppe Cannella + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#if defined(FULL_TEST) + +#include +#include "../def.h" +#include "../IterativeDeeping.h" + +namespace makemove { + string go(const string &fen) { + IterativeDeeping it; + it.loadFen(fen); + SearchManager &searchManager = Singleton::getInstance(); + searchManager.setMaxTimeMillsec(250); + it.start(); + it.join(); + return it.getBestmove(); + } +} + +TEST(search, stalemate1) { + EXPECT_NE("c2f2", makemove::go("8/8/8/3K4/8/3N4/2Q5/7k w - - 9 67")); +} + +TEST(search, stalemate2) { EXPECT_NE("c7d6", makemove::go("4k3/2Q5/6K1/8/5N2/8/8/8 w - - 15 67")); } + +TEST(search, stalemate3) { + EXPECT_NE("b3c2", makemove::go("8/8/8/8/3K4/1Q6/8/k7 w - - 15 222")); +} + +TEST(search, stalemate4) { + EXPECT_NE("d3f4", makemove::go("8/8/7p/5k1P/5P2/3n4/7K/4q3 b - - 1 72")); +} + +TEST(search, stalemate5) { + EXPECT_NE("f4f3", makemove::go("8/6p1/6kp/8/5p2/6q1/8/5K2 b - - 5 43")); +} + +#endif \ No newline at end of file diff --git a/src/test/string.cpp b/src/test/string.cpp index 302e4614..62a60f9f 100644 --- a/src/test/string.cpp +++ b/src/test/string.cpp @@ -19,41 +19,37 @@ #if defined(FULL_TEST) #include +#include "../namespaces/String.h" TEST(StringTest, trim) { - String s(" hello "); - ASSERT_EQ("hello", s.trim()); -} - -TEST(StringTest, endsWith) { - String s("hello"); - ASSERT_TRUE(s.endsWith("lo")); + string s(" hello "); + auto ff = String::trim(s); + ASSERT_EQ("hello", String::trim(s)); } TEST(StringTest, trimLeft) { - String s(" hello "); - ASSERT_EQ("hello ", s.trimLeft()); + string s(" hello "); + ASSERT_EQ("hello ", String::trimLeft(s)); } TEST(StringTest, trimRight) { - String s(" hello "); - ASSERT_EQ(" hello", s.trimRight()); + string s(" hello "); + ASSERT_EQ(" hello", String::trimRight(s)); } - TEST(StringTest, replace) { - String s(" hello "); - ASSERT_EQ(" hexxo ", s.replace("l", "x")); + string s(" hello "); + ASSERT_EQ(" hexxo ", String::replace(s, "l", "x")); } TEST(StringTest, replaceChar) { - String s(" hello "); - ASSERT_EQ(" hexxo ", s.replace('l', 'x')); + string s(" hello "); + ASSERT_EQ(" hexxo ", String::replace(s, 'l', 'x')); } TEST(StringTest, toLower) { - String s("HELLO"); - ASSERT_EQ("hello", s.toLower()); + string s("HELLO"); + ASSERT_EQ("hello", String::toLower(s)); } #endif diff --git a/src/test/test.cpp b/src/test/test.cpp index a9106d56..5a4bfa5f 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -29,5 +29,6 @@ #include "gtb.cpp" #include "fileUtil.cpp" #include "string.cpp" +#include "stalemate.cpp" #endif diff --git a/src/threadPool/Mutex.h b/src/threadPool/Mutex.h deleted file mode 100644 index 5b94d006..00000000 --- a/src/threadPool/Mutex.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Cinnamon UCI chess engine - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#pragma once - - -#if defined(_WIN32) -//mutex on windows is slow -//https://msdn.microsoft.com/en-us/library/ms682530%28VS.85%29.aspx - -#include - - -class Mutex { -public: - Mutex() { InitializeCriticalSection(&cs); } - - ~Mutex() { DeleteCriticalSection(&cs); } - - void lock() { EnterCriticalSection(&cs); } - - void unlock() { LeaveCriticalSection(&cs); } - -private: - CRITICAL_SECTION cs; -}; - -#else - -#include - -class Mutex: public mutex { - -}; - -#endif \ No newline at end of file diff --git a/src/threadPool/Spinlock.h b/src/threadPool/Spinlock.h index 15e56e12..d7238722 100644 --- a/src/threadPool/Spinlock.h +++ b/src/threadPool/Spinlock.h @@ -1,89 +1,88 @@ -/* - https://github.com/gekomad/ThreadPool - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -// A shared Spinlock implementation - -#pragma once - -#include - -using namespace std; - -#ifdef _WIN32 -#include -#pragma intrinsic(_InterlockedExchange) -#define LOCK_TEST_AND_SET(_lock) _InterlockedExchange(&_lock, 1) -#define LOCK_RELEASE(_lock) _InterlockedExchange(&_lock, 0) -#else -#define LOCK_TEST_AND_SET(_lock) __sync_lock_test_and_set(&_lock, 1) -#define LOCK_RELEASE(_lock) __sync_lock_release(&_lock) -#endif - -class Spinlock { -private: - std::atomic_flag flag = ATOMIC_FLAG_INIT; - volatile long _write = 0; - volatile atomic_int _read = {0}; - - void _lock() { - while (true) { - if (!LOCK_TEST_AND_SET(_write)) - return; - while (_write); - } - } - -public: - Spinlock() : flag(ATOMIC_FLAG_INIT) { } - - inline void lock() { - while (flag.test_and_set(std::memory_order_acquire)); - } - - inline void unlock() { - flag.clear(std::memory_order_release); - } - - inline void lockWrite() { - bool w = false; - while (true) { - if (!w && !LOCK_TEST_AND_SET(_write)) { - w = true; - } - if (w && !_read) { - return; - } - while ((!w && _write) || _read); - } - } - - inline void unlockWrite() { - LOCK_RELEASE(_write); - } - - inline void lockRead() { - lockWrite(); - _read++; - unlockWrite(); - } - - inline void unlockRead() { - _read--; - } -}; +/* + https://github.com/gekomad/ThreadPool + Copyright (C) Giuseppe Cannella + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +// A shared Spinlock implementation + +#pragma once + +#include +using namespace std; + +#ifdef _MSC_VER +#include +#pragma intrinsic(_InterlockedExchange) +#define LOCK_TEST_AND_SET(_lock) _InterlockedExchange(&_lock, 1) +#define LOCK_RELEASE(_lock) _InterlockedExchange(&_lock, 0) +#else +#define LOCK_TEST_AND_SET(_lock) __sync_lock_test_and_set(&_lock, 1) +#define LOCK_RELEASE(_lock) __sync_lock_release(&_lock) +#endif + +class Spinlock { +private: + std::atomic_flag flag = ATOMIC_FLAG_INIT; + volatile long _write = 0; + volatile atomic_int _read = { 0 }; + + void _lock() { + while (true) { + if (!LOCK_TEST_AND_SET(_write)) + return; + while (_write); + } + } + +public: + Spinlock() { } + + inline void lock() { + while (flag.test_and_set(std::memory_order_acquire)); + } + + inline void unlock() { + flag.clear(std::memory_order_release); + } + + inline void lockWrite() { + bool w = false; + while (true) { + if (!w && !LOCK_TEST_AND_SET(_write)) { + w = true; + } + if (w && !_read) { + return; + } + while ((!w && _write) || _read); + } + } + + inline void unlockWrite() { + LOCK_RELEASE(_write); + } + + inline void lockRead() { + lockWrite(); + _read++; + unlockWrite(); + } + + inline void unlockRead() { + _read--; + } +}; diff --git a/src/threadPool/Thread.h b/src/threadPool/Thread.h index 0c7b4ee3..751844d6 100644 --- a/src/threadPool/Thread.h +++ b/src/threadPool/Thread.h @@ -69,7 +69,7 @@ class Thread { } void start() { - ASSERT(!isJoinable()); + assert(!isJoinable()); theThread = thread(&Thread::_run, this); } diff --git a/src/threadPool/ThreadPool.h b/src/threadPool/ThreadPool.h index 880a588f..593867f8 100644 --- a/src/threadPool/ThreadPool.h +++ b/src/threadPool/ThreadPool.h @@ -20,14 +20,12 @@ #include "Thread.h" #include -#include +#include "../unistd.h" #include "ObserverThread.h" #include "../namespaces/bits.h" #include -#include "../namespaces/debug.h" #include "../util/logger.h" -using namespace _debug; using namespace _def; template, T>::value, T>::type> @@ -66,7 +64,7 @@ class ThreadPool: public ObserverThread { joinAll(); removeAllThread(); nThread = t; - ASSERT(threadsBits == 0); + assert(threadsBits == 0); for (int i = 0; i < nThread; i++) { T *x = new T(); x->setId(i); @@ -107,7 +105,7 @@ class ThreadPool: public ObserverThread { } T &getThread(int i) const { - ASSERT(i < nThread); + assert(i < nThread); return *threadPool[i]; } @@ -121,15 +119,15 @@ class ThreadPool: public ObserverThread { T &getThread() { int i = BITScanForwardUnset(threadsBits); threadPool[i]->join(); - ASSERT(!(threadsBits & POW2[i])); - threadsBits |= POW2[i]; + assert(!(threadsBits & POW2(i))); + threadsBits |= POW2(i); return *threadPool[i]; } void releaseThread(const int threadID) { - ASSERT_RANGE(threadID, 0, 63); - ASSERT(threadsBits & POW2[threadID]); - threadsBits &= ~POW2[threadID]; + ASSERT_RANGE(threadID, 0, 63) + assert(threadsBits & POW2(threadID)); + threadsBits &= ~POW2(threadID); cv.notify_all(); debug("ThreadPool::releaseThread #", threadID); } @@ -150,7 +148,7 @@ class ThreadPool: public ObserverThread { delete s; } threadPool.clear(); - ASSERT(threadsBits == 0); + assert(threadsBits == 0); } }; diff --git a/src/unistd.h b/src/unistd.h new file mode 100644 index 00000000..3e99e10f --- /dev/null +++ b/src/unistd.h @@ -0,0 +1,5 @@ +#pragma once + +#ifndef _MSC_VER +#include +#endif \ No newline at end of file diff --git a/src/util/Bitboard.cpp b/src/util/Bitboard.cpp index 889a87ca..0f87f158 100644 --- a/src/util/Bitboard.cpp +++ b/src/util/Bitboard.cpp @@ -39,37 +39,37 @@ Bitboard::Bitboard() { int b = max(i, j); MASK_BIT_SET[i][i] = 0; for (int e = a; e <= b; e++) { - u64 r = (RANK[i] | POW2[i]) & (RANK[j] | POW2[j]); + u64 r = (RANK[i] | POW2(i)) & (RANK[j] | POW2(j)); if (r) { - MASK_BIT_SET[i][j] |= POW2[e] & r; + MASK_BIT_SET[i][j] |= POW2(e) & r; } else { - r = (FILE_[i] | POW2[i]) & (FILE_[j] | POW2[j]); + r = (FILE_[i] | POW2(i)) & (FILE_[j] | POW2(j)); if (r) { - MASK_BIT_SET[i][j] |= POW2[e] & r; + MASK_BIT_SET[i][j] |= POW2(e) & r; } else { - r = (DIAGONAL[i] | POW2[i]) & (DIAGONAL[j] | POW2[j]); + r = (DIAGONAL[i] | POW2(i)) & (DIAGONAL[j] | POW2(j)); if (r) { - MASK_BIT_SET[i][j] |= POW2[e] & r; + MASK_BIT_SET[i][j] |= POW2(e) & r; } else { - r = (ANTIDIAGONAL[i] | POW2[i]) & (ANTIDIAGONAL[j] | POW2[j]); + r = (ANTIDIAGONAL[i] | POW2(i)) & (ANTIDIAGONAL[j] | POW2(j)); if (r) { - MASK_BIT_SET[i][j] |= POW2[e] & r; + MASK_BIT_SET[i][j] |= POW2(e) & r; } } } } } if (i == j) { - MASK_BIT_SET[i][i] &= NOTPOW2[i]; + MASK_BIT_SET[i][i] &= NOTPOW2(i); } } } for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { tmpStruct->MASK_BIT_SET_NOBOUND_TMP[i][j] = MASK_BIT_SET[i][j]; - tmpStruct->MASK_BIT_SET_NOBOUND_TMP[i][j] &= NOTPOW2[i]; - tmpStruct->MASK_BIT_SET_NOBOUND_TMP[i][j] &= NOTPOW2[j]; - MASK_BIT_SET[i][j] &= NOTPOW2[i]; + tmpStruct->MASK_BIT_SET_NOBOUND_TMP[i][j] &= NOTPOW2(i); + tmpStruct->MASK_BIT_SET_NOBOUND_TMP[i][j] &= NOTPOW2(j); + MASK_BIT_SET[i][j] &= NOTPOW2(i); } } @@ -174,12 +174,12 @@ u64 Bitboard::performColumnCapture(const int position, const u64 allpieces) { u64 k = 0; u64 x = allpieces & FILE_[position]; q = x & _bitboardTmp::MASK_BIT_UNSET_UP[position]; - if (q && allpieces & POW2[BITScanReverse(q)]) { - k |= POW2[BITScanReverse(q)]; + if (q && allpieces & POW2(BITScanReverse(q))) { + k |= POW2(BITScanReverse(q)); } q = x & _bitboardTmp::MASK_BIT_UNSET_DOWN[position]; - if (q && allpieces & POW2[BITScanForward(q)]) { - k |= POW2[BITScanForward(q)]; + if (q && allpieces & POW2(BITScanForward(q))) { + k |= POW2(BITScanForward(q)); } return k; } @@ -189,12 +189,12 @@ u64 Bitboard::performRankCapture(const int position, const u64 allpieces) { u64 k = 0; u64 x = allpieces & RANK[position]; q = x & _bitboardTmp::MASK_BIT_UNSET_LEFT[position]; - if (q && allpieces & POW2[BITScanReverse(q)]) { - k |= POW2[BITScanReverse(q)]; + if (q && allpieces & POW2(BITScanReverse(q))) { + k |= POW2(BITScanReverse(q)); } q = x & _bitboardTmp::MASK_BIT_UNSET_RIGHT[position]; - if (q && allpieces & POW2[BITScanForward(q)]) { - k |= POW2[BITScanForward(q)]; + if (q && allpieces & POW2(BITScanForward(q))) { + k |= POW2(BITScanForward(q)); } return k; } @@ -205,15 +205,15 @@ u64 Bitboard::performAntiDiagCapture(const int position, const u64 allpieces) { u64 q = allpieces & _bitboardTmp::MASK_BIT_UNSET_RIGHT_UP[position]; if (q) { bound = BITScanReverse(q); - if (allpieces & POW2[bound]) { - k |= POW2[bound]; + if (allpieces & POW2(bound)) { + k |= POW2(bound); } } q = allpieces & _bitboardTmp::MASK_BIT_UNSET_RIGHT_DOWN[position]; if (q) { bound = BITScanForward(q); - if (allpieces & POW2[bound]) { - k |= POW2[bound]; + if (allpieces & POW2(bound)) { + k |= POW2(bound); } } return k; @@ -226,15 +226,15 @@ u64 Bitboard::performDiagCapture(const int position, const u64 allpieces) { u64 q = allpieces & _bitboardTmp::MASK_BIT_UNSET_LEFT_UP[position]; if (q) { bound = BITScanReverse(q); - if (allpieces & POW2[bound]) { - k |= POW2[bound]; + if (allpieces & POW2(bound)) { + k |= POW2(bound); } } q = allpieces & _bitboardTmp::MASK_BIT_UNSET_LEFT_DOWN[position]; if (q) { bound = BITScanForward(q); - if (allpieces & POW2[bound]) { - k |= POW2[bound]; + if (allpieces & POW2(bound)) { + k |= POW2(bound); } } @@ -290,7 +290,7 @@ vector Bitboard::getCombination(const vector elements) { v = combinations(elements, len); unsigned k = 0; for (int rr:v) { - bits |= POW2[rr]; + bits |= POW2(rr); if (++k == len) { res.push_back(bits); bits = 0; diff --git a/src/util/Bitboard.h b/src/util/Bitboard.h index b4fd05b2..f888b621 100644 --- a/src/util/Bitboard.h +++ b/src/util/Bitboard.h @@ -44,6 +44,7 @@ class Bitboard { Bitboard(); static inline u64 getRankFile(const int position, const u64 allpieces) { + BENCH_AUTO_CLOSE("getRankFile") // ........ 00000000 // ...q.... 00010000 // ........ 00010000 @@ -58,7 +59,7 @@ class Bitboard { } static inline u64 getDiagonalAntiDiagonal(const int position, const u64 allpieces) { - BENCH(Times::getInstance().start("getDiagonalAntiDiagonal")) + BENCH_AUTO_CLOSE("getDiagonalAntiDiagonal") // ........ 00010000 // q....... 10100000 // .B...... 00000000 @@ -68,10 +69,8 @@ class Bitboard { // ........ 00000100 // ........ 00000010 - auto a = BITBOARD_DIAGONAL[position][diagonalIdx(position, allpieces)] | - BITBOARD_ANTIDIAGONAL[position][antiDiagonalIdx(position, allpieces)]; - BENCH(Times::getInstance().stop("getDiagonalAntiDiagonal")) - return a; + return BITBOARD_DIAGONAL[position][diagonalIdx(position, allpieces)] | + BITBOARD_ANTIDIAGONAL[position][antiDiagonalIdx(position, allpieces)]; } private: @@ -121,7 +120,7 @@ class Bitboard { static uchar diagonalIdx(const int position, const u64 allpieces) { return (((allpieces & constants::DIAGONAL[position]) * MAGIC_KEY_DIAG_ANTIDIAG) >> 56) & 0xff; - }; + } static uchar antiDiagonalIdx(const int position, const u64 allpieces) { return (((allpieces & constants::ANTIDIAGONAL[position]) * MAGIC_KEY_DIAG_ANTIDIAG) >> 56) & 0xff; diff --git a/src/util/FileUtil.h b/src/util/FileUtil.h index bfd5bb50..c3ff8edc 100644 --- a/src/util/FileUtil.h +++ b/src/util/FileUtil.h @@ -19,22 +19,17 @@ #pragma once #include -#include "String.h" - +#include "../namespaces/String.h" #include #include - using namespace std; class FileUtil { public: static bool fileExists(const string &filename) { - struct stat info; - if (stat(filename.c_str(), &info) != 0) - return false; - return true; + return stat(filename.c_str(), &info) == 0; } static int fileSize(const string &filename) { @@ -42,13 +37,10 @@ class FileUtil { return in.tellg(); } - static string getFileName(string path) { - String s(path); - s.replace(':', '/'); - s.replace("\\", "/"); - s.replace("//", "/"); - path = s; - istringstream iss(path); + static string getFileName(const string &path) { + string pp = path; + auto p = String::replace(pp, '\\', '/'); + istringstream iss(p); string token; while (getline(iss, token, '/')); return token; diff --git a/src/util/IniFile.cpp b/src/util/IniFile.cpp index e73eb1c7..380448e6 100644 --- a/src/util/IniFile.cpp +++ b/src/util/IniFile.cpp @@ -15,48 +15,31 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - +#ifdef TUNING #include "IniFile.h" IniFile::IniFile(const string &fileName1) { fileName = fileName1; - if (FileUtil::fileSize(fileName) <= 0)return; - endFile = true; inData.open(fileName, std::ofstream::in); - if (inData.is_open()) { - endFile = false; - } else { - warn("file not found: ", fileName); + if (!inData.is_open()) { + cout << "file not found " << fileName << endl; + return; } + rgxLine.assign("^(.+?)=(.*)$"); rgxTag.assign("^\\[.+]$"); -} - -IniFile::~IniFile() { - if (endFile) { - inData.close(); - } -} - -string IniFile::getValue(const string &value) { - IniFile file(fileName); while (true) { - pair *parameters = file.get(); - if (!parameters)return ""; - if (parameters->first == value) { - return parameters->second; - } + pair *parameters = this->get(); + if (!parameters)break; + paramMap[parameters->first] = parameters->second; } + inData.close(); } pair *IniFile::get() { std::smatch match; string line; - while (!endFile) { - if (inData.eof()) { - endFile = true; - return nullptr; - } + while (!inData.eof()) { getline(inData, line); trace(line); if (line.empty())continue; @@ -67,7 +50,8 @@ pair *IniFile::get() { params.first = line; params.second = ""; } else if (std::regex_search(line2.begin(), line2.end(), match, rgxLine)) { - params.first = String(match[1]).trim(); + string x = string(match[1]); + params.first = String::trim(x); if (params.first.empty())continue; params.second = match[2]; } else { @@ -77,4 +61,5 @@ pair *IniFile::get() { } return nullptr; -} \ No newline at end of file +} +#endif diff --git a/src/util/IniFile.h b/src/util/IniFile.h index e7296d76..3adb865a 100644 --- a/src/util/IniFile.h +++ b/src/util/IniFile.h @@ -15,17 +15,16 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - +#ifdef TUNING #pragma once #include #include -#include "../namespaces/debug.h" #include "logger.h" #include "FileUtil.h" +#include using namespace std; -using namespace _debug; using namespace _logger; class IniFile { @@ -33,18 +32,15 @@ class IniFile { IniFile(const string &fileName1); - ~IniFile(); - - string getValue(const string &value); - - pair *get(); - + map paramMap; private: std::regex rgxLine; std::regex rgxTag; - bool endFile = true; ifstream inData; string fileName; pair params; -}; + pair *get(); + +}; +#endif diff --git a/src/util/Random.h b/src/util/Random.h index e7ec7c01..5407c26f 100644 --- a/src/util/Random.h +++ b/src/util/Random.h @@ -37,7 +37,7 @@ class Random { } static int getRandom(const int from, const int to) { -#ifdef _WIN32 +#if _WIN32 || _WIN64 std::chrono::nanoseconds ns = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()); std::mt19937 mt(static_cast(ns.count())); #else @@ -49,4 +49,4 @@ class Random { } }; -#endif \ No newline at end of file +#endif diff --git a/src/util/String.cpp b/src/util/String.cpp deleted file mode 100644 index 6a33fddb..00000000 --- a/src/util/String.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Cinnamon UCI chess engine - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "String.h" - -bool String::endsWith(const string &ending) const { - if (ending.size() > this->size()) return false; - return std::equal(ending.rbegin(), ending.rend(), this->rbegin()); -} - -String &String::trim() { - trimLeft(); - trimRight(); - return *this; -} - -String &String::trimLeft() { - this->erase(this->begin(), - std::find_if(this->begin(), this->end(), std::not1(std::ptr_fun(std::isspace)))); - return *this; -} - -String &String::trimRight() { - this->erase(std::find_if(this->rbegin(), this->rend(), std::not1(std::ptr_fun(std::isspace))).base(), - this->end()); - return *this; -} - -String &String::replace(const char c1, const char c2) { - for (unsigned i = 0; i < size(); i++) { - if (at(i) == c1) { - at(i) = c2; - } - } - return *this; -} - -String &String::replace(const string &s1, const string &s2) { - unsigned long a; - while ((a = find(s1)) != string::npos) { - string::replace(a, s1.size(), s2); - } - return *this; -} - -String &String::toUpper() { - transform(begin(), end(), begin(), ::toupper); - return *this; -} - -String &String::toLower() { - transform(begin(), end(), begin(), ::tolower); - return *this; -} \ No newline at end of file diff --git a/src/util/String.h b/src/util/String.h deleted file mode 100644 index b3917003..00000000 --- a/src/util/String.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - Cinnamon UCI chess engine - Copyright (C) Giuseppe Cannella - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#pragma once - -#include -#include -#include -#include -#include - -using namespace std; -#ifdef HAS_64BIT -//64 bit -typedef __int128_t i128; -#else -//32 bit - typedef unsigned long long i128; -#endif - -class String: public string { -public: - String(const string &s) : string(s) { }; - - String(const char *s) : string(s) { }; - - String() = default; - - bool endsWith(const string &ending) const; - - String &trim(); - - String &trimLeft(); - - String &trimRight(); - - String &replace(const char c1, const char c2); - - String &replace(const string &s1, const string &s2); - - String &toUpper(); - - String &toLower(); - - static string toString(const i128 value) { - i128 tmp = value < 0 ? -value : value; - - char buffer[128]; - int p = 0; - char *d = std::end(buffer); - do { - p++; - --d; - *d = "0123456789"[tmp % 10]; - tmp /= 10; - } while (tmp != 0); - if (value < 0) { - p++; - --d; - *d = '-'; - } - d[p] = 0; - return d; - } - - template - String(T d, const string tohex = "") { - stringstream ss; - if (tohex == "int64tohex") { - stringstream ss2; - ss2 << std::hex << d; - ss << "0x"; - for (unsigned i = 0; i < 16 - ss2.str().length(); i++) - ss << "0"; - ss << std::hex << d << "ULL"; - } - else if (tohex == "int32tohex") { - stringstream ss2; - ss2 << std::hex << d; - ss << "0x"; - for (unsigned i = 0; i < 8 - ss2.str().length(); i++) - ss << "0"; - ss << std::hex << d; - } - else { - ss << d; - } - assign(ss.str()); - } - - static int stoi(const string &s) { - if (s.empty())return 0; - return std::stoi(s); - } - -}; diff --git a/src/util/Timer.cpp b/src/util/Timer.cpp index 3e638ba3..4ed2b57d 100644 --- a/src/util/Timer.cpp +++ b/src/util/Timer.cpp @@ -18,7 +18,7 @@ #include "Timer.h" -Timer::Timer(int seconds1) { +Timer::Timer(const int seconds1) { seconds = seconds1; } diff --git a/src/util/Timer.h b/src/util/Timer.h index 7f8e56c2..9b8e6573 100644 --- a/src/util/Timer.h +++ b/src/util/Timer.h @@ -25,7 +25,7 @@ class Timer: public Thread { public: - Timer(int seconds1); + Timer(const int seconds1); void endRun(); diff --git a/src/util/bench/Bench.h b/src/util/bench/Bench.h new file mode 100644 index 00000000..41229924 --- /dev/null +++ b/src/util/bench/Bench.h @@ -0,0 +1,55 @@ +/* + Cinnamon UCI chess engine + Copyright (C) Giuseppe Cannella + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include +#include "Times.h" +#include + +#ifdef BENCH_MODE +#define BENCH_AUTO_CLOSE(name) (Bench(Times::getInstance(),name)); +#define BENCH_START(name) (Bench(Times::getInstance(),name)); +#define BENCH_SUBPROCESS(name,sub) (Times::getInstance().subProcess(name,sub)); +#define BENCH_STOP(name) (Times::getInstance().stop(name)); +#define BENCH_PRINT() (Times::getInstance().print()); +#else +#define BENCH_AUTO_CLOSE(name) +#define BENCH_START(name) +#define BENCH_SUBPROCESS(name, subProcess) +#define BENCH_STOP(name) +#define BENCH_PRINT() +#endif + +using namespace std; + +class Bench { +public: + Bench(Times &time, const string &name) { + this->time = &time; + this->name = name; + time.start(name); + } + + ~Bench() { + time->stop(name); + } +private: + string name; + Times *time; +}; diff --git a/src/util/bench/Time.h b/src/util/bench/Time.h index a1100ef8..c2bfc6ee 100644 --- a/src/util/bench/Time.h +++ b/src/util/bench/Time.h @@ -20,7 +20,7 @@ #include #include -#include "../String.h" +#include "../../namespaces/String.h" #include using namespace std; @@ -29,7 +29,7 @@ using namespace chrono; class Time { private: - int _count = 0; + long _count = 0; std::chrono::time_point _start; int64_t _totTime = 0; map subName; @@ -45,7 +45,7 @@ class Time { static constexpr int HOUR_IN_SECONDS = 60 * 60; static constexpr int HOUR_IN_MINUTES = 60; - int64_t getCount() const { return _count; } + long getCount() const { return _count; } void resetAndStart() { reset(); @@ -71,7 +71,7 @@ class Time { return _count == 0 ? 0 : _totTime / _count; } - pair avgWithSubProcessAndReset(const map times1) { + pair avgWithSubProcess(const map times1) { int64_t totTimeSubprocess = 0; for (auto & it : subName) { auto name1 = it.first; @@ -82,7 +82,6 @@ class Time { auto avgs = pair(0, 0); if (_count) avgs = pair((_totTime - totTimeSubprocess) / _count, _totTime / _count); - reset(); return avgs; } @@ -102,61 +101,11 @@ class Time { return elapsed.count(); } - static string - diffTimeToString(const high_resolution_clock::time_point start, const high_resolution_clock::time_point stop) { - string res; - unsigned t = Time::diffTime(stop, start) / 1000; - unsigned days = t / 60 / 60 / 24; - int hours = (t / 60 / 60) % 24; - int minutes = (t / 60) % 60; - int seconds = t % 60; - int millsec = Time::diffTime(stop, start) % 1000; - - if (days) { - res.append(String(days)).append(" days "); - } - if (days || hours) { - res.append(String(hours)).append(" hours "); - } - if (days || hours || minutes) { - res.append(String(minutes)).append(" minutes "); - } - if (!days) { - res.append(String(seconds)).append(" seconds "); - } - if (!days && !hours) { - res.append(String(millsec)).append(" millsec"); - } - return res; - } - static string getLocalTime() { time_t current = chrono::system_clock::to_time_t(chrono::system_clock::now()); auto a = string(ctime(¤t)); return a.substr(0, a.size() - 1); } - static string getLocalTimeNs() { - unsigned long ns = (unsigned long) (std::chrono::steady_clock::now().time_since_epoch().count()); - return getLocalTime() + " ns: " + to_string(ns); - } - - static int getYear() { - time_t t = time(nullptr); - tm *timePtr = localtime(&t); - return 1900 + timePtr->tm_year; - } - - static int getMonth() { - time_t t = time(nullptr); - tm *timePtr = localtime(&t); - return 1 + timePtr->tm_mon; - } - - static int getDay() { - time_t t = time(nullptr); - tm *timePtr = localtime(&t); - return timePtr->tm_mday; - } }; diff --git a/src/util/bench/Times.h b/src/util/bench/Times.h index 2bfd1f94..5be012cc 100644 --- a/src/util/bench/Times.h +++ b/src/util/bench/Times.h @@ -19,7 +19,6 @@ #pragma once #include -#include "../String.h" #include "Time.h" #include #include @@ -35,38 +34,52 @@ class Times { private: int latency; - - void calcLatency() { - start("test"); - stop("test"); - } + map times; Times() { - for (int i = 0; i < 100000; i++)calcLatency(); - auto a = avgAndReset("test"); + for (unsigned i = 0; i < 9999999; i++)calcLatency(); + auto a = avg("test"); latency = a.first; + dispose(); + } + + void dispose() { + for (auto it = times.begin(); it != times.end(); ++it) { + delete it->second; + } times.clear(); } - map times; + ~Times() { + dispose(); + } - inline void add(const string &name) { - if (nullptr == times[name]) times[name] = new Time(latency); + void calcLatency() { + start("test"); + stop("test"); } - ~Times() { - for (auto it = times.begin(); it != times.end(); ++it) { - delete it->second; - } + inline void add(const string &name) { + if (times.end() == times.find(name)) times[name] = new Time(latency); } public: + void reset() { + for (auto it = times.begin(); it != times.end(); ++it) it->second->reset(); + } void print() { + int64_t tot = 0; + for (auto it = times.begin(); it != times.end(); ++it) { + const auto count1 = it->second->getCount(); + const auto avg1 = avg(it->first); + tot += count1 * avg1.second; + } + for (auto it = times.begin(); it != times.end(); ++it) { const auto count1 = it->second->getCount(); long countP = count1; - const auto avg = avgAndReset(it->first); + const auto avg1 = avg(it->first); string m = " "; if (count1 > (1000 * 1000)) { countP /= (1000 * 1000); @@ -77,10 +90,11 @@ class Times { } cout << "info string bench " << it->first << setw(30 - it->first.length()) << countP << m << " times\t" << "avg ns:" << "\t" - << avg.second << flush; - if (avg.first != avg.second) - cout << (avg.second > 1000 ? "\t" : "\t\t") << "without subprocess: " << avg.first << flush; - int64_t a = count1 * avg.second; + << avg1.second << flush; + if (avg1.first != avg1.second) + cout << (avg1.second > 1000 ? "\t" : "\t\t") << "without subprocess: " << avg1.first << flush; + int64_t a = count1 * avg1.second; + int64_t aa = a; if (a > (1000 * 1000)) { a /= (1000 * 1000); m = "M"; @@ -88,10 +102,10 @@ class Times { a /= 1000; m = "K"; } - if (avg.first != avg.second) - cout << "\t\tTOT: " << a << m << flush; + if (avg1.first != avg1.second) + cout << "\t\tTOT: " << a << m << "\t" << (aa * 100 / tot) << "%" << flush; else - cout << "\t\t\t\t\t\t\t\t\tTOT: " << a << m << flush; + cout << "\t\t\t\t\t\t\t\t\tTOT: " << a << m << "\t" << (aa * 100 / tot) << "%" << flush; cout << endl; } } @@ -111,9 +125,9 @@ class Times { a->stop(); } - pair avgAndReset(const string &name) { + pair avg(const string &name) { Time *a = times[name]; if (a == nullptr)return pair(-1, -1); - return a->avgWithSubProcessAndReset(times); + return a->avgWithSubProcess(times); } }; diff --git a/src/util/getopt.h b/src/util/getopt.h new file mode 100644 index 00000000..cf80525b --- /dev/null +++ b/src/util/getopt.h @@ -0,0 +1,106 @@ +//https://gist.github.com/superwills/5815344 + +// Put this in a separate .h file (called "getopt.h"). +// The prototype for the header file is: + +/* +* Copyright (c) 1987, 1993, 1994 +* The Regents of the University of California. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. All advertising materials mentioning features or use of this software +* must display the following acknowledgement: +* This product includes software developed by the University of +* California, Berkeley and its contributors. +* 4. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ + +#include +#include + +int opterr = 1, /* if error message should be printed */ +optind = 1, /* index into parent argv vector */ +optopt, /* character checked for validity */ +optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int getopt1(int nargc, char *const nargv[], const char *ostr) { + const static string EMSG_str(""); + static char *place = (char *) EMSG_str.c_str(); /* option letter processing */ + const char *oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = (char *) EMSG_str.c_str(); + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = (char *) EMSG_str.c_str(); + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int) *place++) == (int) ':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int) '-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void) printf("illegal option -- %c\n", optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = (char *) EMSG_str.c_str(); + if (!*place) + ++optind; + } else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = (char *) EMSG_str.c_str(); + if (*ostr == ':') + return (BADARG); + if (opterr) + (void) printf("option requires an argument -- %c\n", optopt); + return (BADCH); + } else /* white space */ + optarg = nargv[optind]; + place = (char *) EMSG_str.c_str(); + ++optind; + } + return (optopt); /* dump back option letter */ +} \ No newline at end of file diff --git a/src/util/logger.h b/src/util/logger.h index 7d3f16e3..c5281c0f 100644 --- a/src/util/logger.h +++ b/src/util/logger.h @@ -29,14 +29,14 @@ using namespace std; namespace _logger { enum LOG_LEVEL { - _TRACE = 0, _DEBUG = 1, _INFO = 2, _WARN = 3, _ERROR = 4, _FATAL = 5, _OFF = 6 + _TRACE = 0, _DEBUG1 = 1, _INFO = 2, _WARN = 3, _ERROR = 4, _FATAL = 5, _OFF = 6 }; #if !defined DLOG_LEVEL #if defined DEBUG_MODE #define DLOG_LEVEL _TRACE #else -#define DLOG_LEVEL _OFF +#define DLOG_LEVEL _FATAL #endif #endif @@ -53,8 +53,8 @@ namespace _logger { template void _log(T t, Args... args) { _CoutSyncSpinlock.lock(); - cout << Time::getLocalTimeNs() << " " << LOG_LEVEL_STRING[type] << " "; - *this << Time::getLocalTimeNs() << " " << LOG_LEVEL_STRING[type] << " "; + cout << Time::getLocalTime() << " " << LOG_LEVEL_STRING[type] << " "; + *this << Time::getLocalTime() << " " << LOG_LEVEL_STRING[type] << " "; __log(t, args...); cout << endl; *this << endl; @@ -84,7 +84,7 @@ namespace _logger { static Logger &logger = Logger::getInstance(); -#ifdef _WIN32 +#if _WIN32 || _WIN64 #define FILE_SEPARATOR '\\' #else #define FILE_SEPARATOR '/' @@ -95,7 +95,7 @@ namespace _logger { #define LINE_INFO __FILENAME__,":",__LINE__," " #define trace(...) if (_TRACE >= DLOG_LEVEL) {logger._log( LINE_INFO,__VA_ARGS__);} -#define debug(...) if (_DEBUG >= DLOG_LEVEL) {logger._log( LINE_INFO,__VA_ARGS__);} +#define debug(...) if (_DEBUG1 >= DLOG_LEVEL) {logger._log( LINE_INFO,__VA_ARGS__);} #define info(...) if (_INFO >= DLOG_LEVEL) {logger._log ( LINE_INFO,__VA_ARGS__);} #define warn(...) if (_WARN >= DLOG_LEVEL) {logger._log ( LINE_INFO,__VA_ARGS__);} #define error(...) if (_ERROR >= DLOG_LEVEL) {logger._log( LINE_INFO,__VA_ARGS__);} diff --git a/src/util/tuning/Texel.h b/src/util/tuning/Texel.h new file mode 100644 index 00000000..23567660 --- /dev/null +++ b/src/util/tuning/Texel.h @@ -0,0 +1,184 @@ +/* + Cinnamon UCI chess engine + Copyright (C) Giuseppe Cannella + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef TUNING +#pragma once + +#include "Tune.h" +#include "../../def.h" +#include +#include + +class Texel : Tune { + +public: + static constexpr auto help = "Texel's Tuning Method\n\n" + " Download a big strong main.pgn file\n" + " pgn-extract -Tr0-1 main.pgn >win_black.pgn 2>/dev/null\n" + " pgn-extract -Tr1-0 main.pgn >win_white.pgn 2>/dev/null\n" + " pgn-extract -Tr1/2-1/2 main.pgn >draw.pgn 2>/dev/null\n" + "\n" + " pgn-extract -Wepd win_black.pgn >win_black.epd 2>/dev/null\n" + " pgn-extract -Wepd win_white.pgn >win_white.epd 2>/dev/null\n" + " pgn-extract -Wepd draw.pgn >draw.epd 2>/dev/null\n" + "\n" + " cat win_white.epd | awk -F \" \" '{print $1\" \"$2\" \"$3}' >foo;sort -u foo |grep \"k\" > win_white.epd\n" + " cat win_black.epd | awk -F \" \" '{print $1\" \"$2\" \"$3}' >foo;sort -u foo |grep \"k\" > win_black.epd\n" + " cat draw.epd | awk -F \" \" '{print $1\" \"$2\" \"$3}' >foo;sort -u foo |grep \"k\" > draw.epd\n" + " rm foo win_black.pgn win_white.pgn draw.pgn\n"; + + Texel(const string &path) { + this->path = path; + cout << "Texel's Tuning Method " << Time::getLocalTime() << " start" << endl; + set draw; + set black; + set white; + cout << "Fetch epd files..." << endl << flush; + + fetch(path + "/draw.epd", draw); + fetch(path + "/win_white.epd", white); + fetch(path + "/win_black.epd", black); + + cout << "ok" << flush << endl; + cout << "draw size: " << draw.size() << endl; + cout << "white size: " << white.size() << endl; + cout << "black size: " << black.size() << endl; + cout << "Purge fen..." << flush; + clean(draw, black, white); + + cout << "ok, new size:" << endl; + cout << "draw size: " << draw.size() << endl; + cout << "white size: " << white.size() << endl; + cout << "black size: " << black.size() << endl; + + cout << "Run tuning..." << flush; + set < FEN * > fens; + populateFens(white, fens, 1); + cout << "." << flush; + populateFens(black, fens, 0); + cout << "." << flush; + populateFens(draw, fens, 0.5); + cout << "." << flush; + draw.clear(); + white.clear(); + black.clear(); + + tune(fens); + + cout << endl << endl << Time::getLocalTime() << " end\n"; + for (auto itr = fens.begin(); itr != fens.end(); itr++) delete *itr; + fens.clear(); + } + +private: + string path; + + void populateFens(const set &s, set &fens, const double win) { + for (auto itr = s.begin(); itr != s.end(); itr++) { + const string fen = *itr; + FEN *x = new FEN(fen, win); + fens.insert(x); + } + } + + bool inCheck(string fen) { + const int side = searchManager.loadFen(fen); + if (side == WHITE) return board::inCheck1(searchManager.getChessboard()); + else return board::inCheck1(searchManager.getChessboard()); + } + + void clean(set &draw, set &black, set &white) { + set::iterator itr = draw.begin(); + set::iterator tmp; + + for (; itr != draw.end();) { + const auto check = inCheck(*itr); + if (check || white.find(*itr) != white.end() || black.find(*itr) != black.end()) { + white.erase(*itr); + black.erase(*itr); + tmp = itr; + ++tmp; + draw.erase(*itr); + itr = tmp; + } else itr++; + } + + itr = white.begin(); + for (; itr != white.end();) { + const auto check = inCheck(*itr); + if (check || black.find(*itr) != black.end()) { + black.erase(*itr); + draw.erase(*itr); + tmp = itr; + ++tmp; + white.erase(*itr); + itr = tmp; + } else itr++; + } + + itr = black.begin(); + for (; itr != black.end();) { + const auto check = inCheck(*itr); + if (check) { + white.erase(*itr); + draw.erase(*itr); + tmp = itr; + ++tmp; + black.erase(*itr); + itr = tmp; + } else itr++; + } + } + + void fetch(const string file, set &fens) { + if (!FileUtil::fileExists(file)) { + cout << "Unable to open file " << file << endl; + exit(1); + } + ifstream epdFile(file); + string line; + if (epdFile.is_open()) { + while (getline(epdFile, line)) fens.insert(line); + epdFile.close(); + } + } + + double E(const set &fens) { + constexpr double K = 1.13; + double currentError = 0.0; + for (auto itr = fens.begin(); itr != fens.end(); itr++) { + const FEN *fen = *itr; + searchManager.loadFen(fen->fen); + searchManager.setRunning(2); + searchManager.setRunningThread(true); + searchManager.setMaxTimeMillsec(2500); + const double score = searchManager.getQscore(); + if (abs(score) > _INFINITE - 1000) { + cout << "skip mate score " << score << endl; + continue; + } + const auto sigmoid = 1.0 / (1.0 + pow(10.0, -K * score / 400.0)); + const auto result = fen->win; + currentError += pow(result - sigmoid, 2.0); + } + return 1.0 / fens.size() * currentError; + } + +}; + +#endif diff --git a/src/util/tuning/Tune.h b/src/util/tuning/Tune.h new file mode 100644 index 00000000..c8e0e45c --- /dev/null +++ b/src/util/tuning/Tune.h @@ -0,0 +1,175 @@ +/* + Cinnamon UCI chess engine + Copyright (C) Giuseppe Cannella + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef TUNING +#pragma once + +#include "../../def.h" +#include +#include + +class Tune { + +protected: + constexpr static int N_PARAM = 20; + SearchManager &searchManager = Singleton::getInstance(); + const string iniFile = "tuning.ini"; + + struct FEN { + string fen; + double win; // 1=WHITE, 0=BLACK, 0.5=DRAW + int score; + + FEN(string f, int w) : fen(f), win(w) {} + + FEN(string f, int w, int sc) : fen(f), win(w), score(sc) {} + }; + + virtual double E(const set &fens) = 0; + + struct PARAMS { + private : + int startValue; + public: + int getStartValue() const { return startValue; } + + string name; + + PARAMS(string n, const SearchManager &searchManager) : name(n) { startValue = searchManager.getParameter(n); } + + void print(SearchManager &searchManager) const { + printf("\nname: %s, startValue: %d, newValue: %d", name.c_str(), startValue, + searchManager.getParameter(name)); + if (startValue != searchManager.getParameter(name))cout << " (*)"; + } + }; + + void saveParams(const array ¶ms) { + cout << endl << Time::getLocalTime() << " save parameters to " << iniFile << endl; + ofstream myfile; + myfile.open(iniFile); + myfile << "#" << Time::getLocalTime() << endl; + for (auto ¶m:params) { + myfile << param.name << "=" << searchManager.getParameter(param.name) << endl; + } + myfile.close(); + } + + void loadParams() { + cout << "\nload parameters from " << iniFile << endl; + map map = IniFile(iniFile).paramMap; + for (std::map::iterator it = map.begin(); it != map.end(); ++it) { + std::cout << it->first << " => " << it->second << endl; + searchManager.setParameter(it->first, stoi(it->second)); + } + } + + void tune(const set &fens) { + searchManager.setMaxTimeMillsec(2500); + cout.precision(17); + + loadParams(); + const array params{ + PARAMS("ATTACK_KING", searchManager), + PARAMS("BISHOP_ON_QUEEN", searchManager), + PARAMS("BACKWARD_PAWN", searchManager), + PARAMS("DOUBLED_ISOLATED_PAWNS", searchManager), + PARAMS("PAWN_IN_7TH", searchManager), + PARAMS("PAWN_IN_PROMOTION", searchManager), + PARAMS("PAWN_NEAR_KING", searchManager), + PARAMS("PAWN_BLOCKED", searchManager), + PARAMS("UNPROTECTED_PAWNS", searchManager), + PARAMS("FRIEND_NEAR_KING", searchManager), + PARAMS("BONUS2BISHOP", searchManager), + PARAMS("BISHOP_PAWN_ON_SAME_COLOR", searchManager), + PARAMS("OPEN_FILE_Q", searchManager), + PARAMS("ROOK_7TH_RANK", searchManager), + PARAMS("KNIGHT_PINNED", searchManager), + PARAMS("ROOK_PINNED", searchManager), + PARAMS("BISHOP_PINNED", searchManager), + PARAMS("QUEEN_PINNED", searchManager), + PARAMS("ROOK_IN_7", searchManager), + PARAMS("QUEEN_IN_7", searchManager) + }; + bool fullImproved; + int cycle = 1; + double bestError; + do { + cout << "***************************************** Cycle #" << (cycle++) << " " << Time::getLocalTime() + << " *****************************************" << endl << flush; + fullImproved = false; + const double startError = E(fens); + for (auto ¶m:params) param.print(searchManager); + cout << "\nstartError: " << startError << endl << flush; + bestError = startError; + for (auto ¶m:params) { + int bestValue = -1; + for (int dir = 0; dir < 2; dir++) { + if (!dir)cout << "\nUP "; else cout << "\nDOWN "; + cout << Time::getLocalTime() << endl << flush; + + auto oldValue = searchManager.getParameter(param.name); + int newValue; + if (dir == 0) newValue = searchManager.getParameter(param.name) + 1; + else { + if (searchManager.getParameter(param.name) <= 0)continue; + else newValue = searchManager.getParameter(param.name) - 1; + } + searchManager.setParameter(param.name, newValue); + + double currentError; + + int eq = 0; + while (true) { + currentError = E(fens); + cout << param.name << " try value: " << newValue << "\terror: " << currentError + << "\tbestError: " + << bestError; + if (currentError < bestError)cout << "\t(improved)"; + else if (currentError > bestError)cout << "\t(got worse)"; + else cout << "\t(same)"; + cout << endl << flush; + if (currentError <= bestError && eq < 3) { + if (currentError == bestError) eq++; else eq = 0; + if (currentError < bestError) { + bestValue = newValue; + bestError = currentError; + fullImproved = true; + } + if (dir == 0) newValue++; else { if (newValue <= 0)break; else newValue--; } + searchManager.setParameter(param.name, newValue); + } else break; + } + searchManager.setParameter(param.name, oldValue); + if (bestValue >= 0) { + cout << "\n** Improved. ** bestError: " << bestError << " bestValue " << bestValue << " was " + << param.getStartValue() << flush; + searchManager.setParameter(param.name, bestValue); + for (auto ¶m:params) param.print(searchManager); + saveParams(params); + assert(E(fens) == bestError); + } else cout << "\n** Not improved. **" << flush; + } + } + } while (fullImproved); + for (auto ¶m:params) param.print(searchManager); + saveParams(params); + } +}; + +#endif diff --git a/test.html b/test.html new file mode 100644 index 00000000..484e780d --- /dev/null +++ b/test.html @@ -0,0 +1,1399 @@ + + +Cinnamon chess engine - Tests + + +

Cinnamon chess engine - Tests

+ +
+
+ + + + + + + + +
+
+
+

Cinnamon 2.4

+Linux - Intel i7-9750H CPU @ 2.60GHz gcc 9.3.0 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd293/300
kaufman.epd23/25
zugzwang.epd2/5
bk.epd16/24
mate.epd52/71
+ +

perft depth 6 one cpu no hash

+ ./cinnamon -perft -d6 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

50 sec.

+ +

perft depth 5 one cpu no hash

+ ./cinnamon -perft -d5 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

1.20 sec.

+ +


perft
depth 6 8 cpu 2 GB hash

+ ./cinnamon -perft -d6 -c8 -h2000 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

3.41 sec.

+ +

perft depth 5 one cpu no hash

+ ./cinnamon -perft -d5 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

1.13 sec.

+ +


perft
depth 6 8 cpu 2 GB hash

+ ./cinnamon -perft -d6 -c8 -h2000 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

3.608 sec.

+

Cinnamon 2.3.4

+Linux - Intel i7-9750H CPU @ 2.60GHz gcc 9.3.0 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd284/300
kaufman.epd23/25
zugzwang.epd2/5
bk.epd17/24
mate.epd53/71
+ +

perft depth 6 one cpu no hash

+ ./cinnamon -perft -d6 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

153 sec.

+ +

perft depth 5 one cpu no hash

+ ./cinnamon -perft -d5 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

3 sec.

+ +


perft
depth 6 8 cpu 2 GB hash

+ ./cinnamon -perft -d6 -c8 -h2000 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

8 sec.

+ +

perft depth 5 one cpu no hash

+ ./cinnamon -perft -d5 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

4 sec.

+ +


perft
depth 6 8 cpu 2 GB hash

+ ./cinnamon -perft -d6 -c8 -h2000 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

9 sec.

+

Cinnamon 2.2a

+Linux - Intel i7-9750H CPU @ 2.60GHz gcc 9.3.0 +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd278/300
kaufman.epd23/25
zugzwang.epd2/5
bk.epd17/24
mate.epd55/71
+ +

perft depth 5 one cpu no hash

+ ./cinnamon -perft -d5 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

4 sec.

+ +


perft
depth 6 8 cpu 2 GB hash

+ ./cinnamon -perft -d6 -c8 -h2000 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

9 sec.

+ +

Cinnamon 2.2a

+Linux - Intel Xeon W3540 gcc 7.3.0 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd278/300
arasan12.epd15/215
sbd.epd55/134
kaufman.epd21/25
zugzwang.epd1/5
bk.epd16/24
mate.epd48/71
BT2450.epd + 2276
+ +
+  tc = 0/0:9+0.05 - 1 cpu
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
cinnamon 2.2a34245919655%-1927%
cinnamon 2.1-34425919645%1927%
+
+ tc = 0/0:9+0.05 - 4 cpu
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
cinnamon 2.2a34241627255%-3421%
cinnamon 2.1-34421627245%3421%
+
+ + +

perft depth 5 one cpu no hash

+ ./cinnamon -perft -d5 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq + -"

+ +

8 sec.

+ +


perft
depth 6 8 cpu 2 GB hash

+ ./cinnamon -perft -d6 -c8 -h2000 + -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

22 sec.

+ + +

Cinnamon 2.1

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved (Xeon + W3540) +
wac.epd 277/300
arasan12.epd 13/215
sbd.epd 52/134
kaufman.epd 22/25
zugzwang.epd 3/5
bk.epd 16/24
mate.epd 57/71
BT2450.epd + 2282
+ +
+  tc = 0/0:9+0.05 - 1 cpu
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
cinnamon 2.134245919659%-3421%
cinnamon 2.0-34425919641%3421%
+
+ tc = 0/0:9+0.05 - 4 cpu
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
cinnamon 2.1 (4 + core) + 49323398064%-4926%
cinnamon 2.0 (1 + core) + -49
233398036%4926%
+
+ + +

perft depth 5 one cpu no hash

+ ./cinnamon -perft -d5 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq + -"

+ +

8 sec. Linux - Intel Xeon W3540 gcc 7.3.0

+ +


perft
depth 6 8 cpu 2 GB hash

+ ./cinnamon -perft -d6 -c8 -h2000 + -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

22 sec. Intel Xeon W3540 Linux gcc 7.3.0

+ + +

Cinnamon 2.0

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved (Xeon + W3540) +
wac.epd 276/300
arasan12.epd 14/215
sbd.epd 46/134
kaufman.epd 20/25
zugzwang.epd 3/5
bk.epd 17/24
mate.epd 57/71
BT2450.epd + 2240
+ + +
4 core
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved (Xeon + W3540) +
wac.epd277/300
arasan12.epd14/215
sbd.epd45/134
kaufman.epd21/25
zugzwang.epd3/5
bk.epd18/24
mate.epd58/71
+ BT2450.epd + 2220
+
+  tc = 40/4 - 1 cpu
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-games + scoreoppo.draws
cinnamon 2.0205944758960% + 198933%
cinnamon 1.2b1989 + 44785740%205933%
+
+ tc = 40/4 - 4 cpu
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-games + scoreoppo.draws
cinnamon 2.0 (4 + core) + 209466323666%198933%
cinnamon 1.2b (1 + core) + 1989
+
66323634%209433%
+
+ tc = 40/4 - 4 cpu
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-games + scoreoppo.draws
cinnamon 2.0 (4 + core) +
+
6
+
5
+
466266%
+
33%
cinnamon 2.0 (1 + core) +
+
5
+
6
+
466234%
+

+
33%
+ +
+
+ +

perft depth 5 one cpu no hash

+ ./cinnamon -perft -d5 -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq + -"

+ +

11 sec. Linux - Intel Xeon W3540 gcc 4.9.2

+ +

11 sec. Windows 7 - Intel Xeon W3540 gcc 5.1.0

+ +


perft
depth 6 8 cpu 2 GB hash

+ ./cinnamon -perft -d6 -c8 -h2000 + -f"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"

+ +

29 sec. Intel Xeon W3540 Linux gcc 4.9.2

+ +

30 sec. Intel Xeon W3540 Windows 7 gcc 5.1.0

+ + +

cinnamon 1.2a/1.2b

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved (i5 M430) + Solved (Xeon + W3540) +
wac.epd 273/300 271/300
arasan12.epd 15/215 14/215
sbd.epd 46/134 48/134
kaufman.epd 20/25 19/25
zugzwang.epd 2/5 2/5
bk.epd 16/24 17/24
mate.epd 55/71 58/71
BT2450.epd + -2180
+
+  tc = 40/4, no tablebase, no open book
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
cinnamon 1.2a/1.2b + 14
+
5
+
5
+
4740 54%
+
-14% + 32%
cinnamon 1.1c -14
+
5
+
5
+
4740 46%
+
14%
+
32%
+

 tc = 40/4, tablebase, open book
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
cinnamon 1.2a/1.2b + 21
+
6
+
5
+
4244 56%
+
-21% + 28%
cinnamon 1.1c -21
+
5
+
6
+
4244 44%
+
21%
+
28%
+
+
+ +

perft one cpu no hash fen

+ ./cinnamon -perft -d 5 -f "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w + KQkq -"

+ +

19 sec. Intel i5 CPU M 430 2.27GHz Linux 3.2.0-57-generic gcc 4.8.2

+ +

12 sec. Intel Xeon W3540 Linux 3.13.0-37-generic gcc 4.8.2

+ +


perft
8 cpu 2 GB hash

+ ./cinnamon -perft -d 5 -f "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w + KQkq -"

+ +

? Intel Xeon W3540 Linux 3.13.0-37-generic gcc 4.8.2

+ +

cinnamon 1.1c

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd 277/300
arasan12.epd 16/215
sbd.epd 40/134
kaufman.epd 20/25
zugzwang.epd 3/5
bk.epd 17/24
mate.epd 57/71
BT2450.epd + 2252
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
cinnamon 1.1c
+

+

+
4000
+

+
61%
cinnamon 1.0
+

+

+
4000
+

+
39%
+

perft depth 5 one cpu no hash fen + r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -

+ +

on i5 CPU M 430 2.27GHz Linux 3.2.0-48-generic gcc 4.8.1

+ +

17 sec.

+ +

cinnamon 1.0

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd 277/300
arasan12.epd 17/215
sbd.epd 67/134
kaufman.epd 17/25
zugzwang.epd 2/5
bk.epd 14/24
mate.epd 56/71
BT2450.epd 2222
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
cinnamon 1.04966800065%-4941%
butterfly 0.6-4966800035%4941%
+

perft depth 5 one cpu no hash fen + r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -

+ +

on i5 CPU M 430 2.27GHz Linux 3.2.0-48-generic gcc 4.8.1

+ +

22 sec.

+ +

butterfly 0.6

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd 273/300
arasan12.epd 14/215
sbd.epd 40/134
kaufman.epd 13/25
zugzwang.epd 2/5
bk.epd 12/24
mate.epd 56/71
BT2450.epd 1847
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
butterfly 0.64066791964%-4055%
butterfly 0.5-4066791936%4055%
+

perft depth 5 one cpu no hash fen + r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -

+ +

on i5 CPU M 430 2.27GHz Linux 3.2.0-48-generic gcc 4.8.1

+ +

28 sec.

+ +

butterfly 0.5

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd 266/300
arasan12.epd 16/215
sbd.epd 39/134
kaufman.epd 8/25
zugzwang.epd 3/5
bk.epd 12/24
mate.epd 67/71
BT2450 1806
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
butterfly 0.53266682062%-3265%
butterfly 0.4-3266682038%3265%
+

perft depth 5 one cpu no hash fen + r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -

+ +

on i5 CPU M 430 2.27GHz Linux 3.2.0-48-generic gcc 4.8.1

+ +

23 sec.

+ +

butterfly 0.4

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd 239/300
arasan12.epd 22/215
sbd.epd 38/134
kaufman.epd 7/25
zugzwang.epd 3/5
bk.epd 9/24
mate.epd 67/71
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rank NameElo+-gamesscoreoppo.draws
butterfly 0.44866799166%-4852%
butterfly 0.3.3-4866799134%4852%
+

perft depth 5 one cpu no hash fen + r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -

+ +

on i5 CPU M 430 2.27GHz Linux 3.2.0-48-generic gcc 4.8.1

+ +

32 sec.

+ +

butterfly 0.3.3

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test file (5 sec) + Solved
wac.epd 228/300
arasan12.epd 20/215
sbd.epd 40/134
kaufman.epd 6/25
zugzwang.epd 3/5
bk.epd 9/24
mate.epd 66/71
+

perft depth 5 one cpu no hash fen + r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -

+ +

on i5 CPU M 430 2.27GHz Linux 3.2.0-48-generic gcc 4.8.1

+ +

31 sec.

+
+
+
+ + +
+
+ +