- /* 
-     Protector -- a UCI chess engine 
-   
-     Copyright (C) 2009-2010 Raimund Heid (Raimund_Heid@yahoo.com) 
-   
-     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 <http://www.gnu.org/licenses/>. 
-   
- */ 
-   
- #include "tablebase.h" 
- #include "protector.h" 
- #include "io.h" 
- #include <assert.h> 
-   
- #ifdef INCLUDE_TABLEBASE_ACCESS 
-   
- #ifndef _MSC_VER 
- #include <pthread.h> 
- pthread_spinlock_t lock; 
- #else // _MSC_VER 
- bool lock = 0; // Pierre-Marie Baty -- Win32 thread locking 
- __declspec(dllimport) void __stdcall Sleep (unsigned long Timeout); // Pierre-Marie Baty -- for Sleep() 
- #endif // !_MSC_VER 
- volatile int tbAccessCount = 0; 
-   
- #define MAX_PIECES_PER_SIDE 3 
- #define NO_EP 127 
-   
- bool tbAvailable = FALSE; 
- typedef unsigned long long INDEX; 
- typedef unsigned int squaret; 
-   
- char *cache = 0; 
-   
- #define TB_FASTCALL             /* __fastcall */ 
-   
- typedef INDEX(*PfnCalcIndex) (squaret *, squaret *, squaret, int fInverse); 
-   
- extern int IInitializeTb(char *pszPath); 
- extern int FTbSetCacheSize(void *pv, unsigned long cbSize); 
- extern void VTbCloseFiles(void); 
- extern int IDescFindFromCounters(int *piCount); 
- extern int FRegisteredFun(int iTb, int side); 
- extern PfnCalcIndex PfnIndCalcFun(int iTb, int side); 
- extern int TB_FASTCALL L_TbtProbeTable(int iTb, int side, INDEX indOffset); 
-   
- #define pageL       65536 
- #define tbbe_ssL    ((pageL-4)/2) 
- #define bev_broken  (tbbe_ssL+1)        /* illegal or busted */ 
- #define bev_mi1     tbbe_ssL    /* mate in 1 move */ 
- #define bev_mimin   1           /* mate in max moves */ 
- #define bev_draw    0           /* draw */ 
- #define bev_limax   (-1)        /* mated in max moves */ 
- #define bev_li0     (-tbbe_ssL) /* mated in 0 moves */ 
-   
- #define PfnIndCalc PfnIndCalcFun 
-   
- int setTablebaseCacheSize(unsigned int size) 
- { 
-    unsigned long numBytes = (unsigned long) size * 1024 * 1024; 
-   
-    if (cache != 0) 
-    { 
-    } 
-   
-   
-    if (cache == 0) 
-    { 
-       logDebug("### Could not allocate tablebase cache (%lu bytes). ###\n", 
-                numBytes); 
-   
-       return -1; 
-    } 
-   
-    if (FTbSetCacheSize(cache, numBytes) == 0) 
-    { 
-       logDebug("### Could not set tablebase cache size (%lu bytes). ###\n", 
-                numBytes); 
-   
-       cache = 0; 
-   
-       return -2; 
-    } 
-   
-    /* logDebug("table base cache size set to %lu\n", numBytes); */ 
-   
-    return 0; 
- } 
-   
- int initializeTablebase(const char *path) 
- { 
-    int result = IInitializeTb((char *) path); 
-   
-    if (result > 0) 
-    { 
-       if (setTablebaseCacheSize(4) != 0) 
-       { 
-          closeTablebaseFiles(); 
-   
-          return -1; 
-       } 
-   
-       /* logDebug("Tablebases found at %s\n", path); */ 
-    } 
-    else 
-    { 
-       logDebug("### Error while looking for tablebases in %s ###\n", path); 
-    } 
-   
-    tbAvailable = (bool) (result > 0); 
-   
-    return (result > 0 ? 0 : -1); 
- } 
-   
- void closeTablebaseFiles() 
- { 
-    VTbCloseFiles(); 
- } 
-   
- static void initializePieceData(const Bitboard * pieces, int *pieceCount, 
-                                 unsigned int *pieceLocation) 
- { 
-    Bitboard tmp = *pieces; 
-    Square square; 
-   
-    *pieceCount = 0; 
-   
-    ITERATE_BITBOARD(&tmp, square) 
-    { 
-       *(pieceLocation++) = square; 
-       (*pieceCount)++; 
-    } 
- } 
-   
- static int getMateValue(int fullMoves) 
- { 
-    if (fullMoves > 0) 
-    { 
-       return 1 - VALUE_MATED - 2 * fullMoves; 
-    } 
-    else 
-    { 
-       return VALUE_MATED - 2 * fullMoves; 
-    } 
- } 
-   
- int probeTablebase(const Position * position) 
- { 
-    int pieceCount[10]; 
-    unsigned int whitePieces[MAX_PIECES_PER_SIDE * 5 + 1]; 
-    unsigned int blackPieces[MAX_PIECES_PER_SIDE * 5 + 1]; 
-    unsigned int *pwhite, *pblack; 
-    int tableNr, fInvert, tableValue, fullMoves; 
-    Color color; 
-    INDEX index; 
-    Square enPassantSquare = (Square) NO_EP; 
-   
-    initializePieceData(&position->piecesOfType[WHITE_PAWN], &pieceCount[0], 
-                        &whitePieces[0 * MAX_PIECES_PER_SIDE]); 
-    initializePieceData(&position->piecesOfType[WHITE_KNIGHT], &pieceCount[1], 
-                        &whitePieces[1 * MAX_PIECES_PER_SIDE]); 
-    initializePieceData(&position->piecesOfType[WHITE_BISHOP], &pieceCount[2], 
-                        &whitePieces[2 * MAX_PIECES_PER_SIDE]); 
-    initializePieceData(&position->piecesOfType[WHITE_ROOK], &pieceCount[3], 
-                        &whitePieces[3 * MAX_PIECES_PER_SIDE]); 
-    initializePieceData(&position->piecesOfType[WHITE_QUEEN], &pieceCount[4], 
-                        &whitePieces[4 * MAX_PIECES_PER_SIDE]); 
-   
-    initializePieceData(&position->piecesOfType[BLACK_PAWN], &pieceCount[5], 
-                        &blackPieces[0 * MAX_PIECES_PER_SIDE]); 
-    initializePieceData(&position->piecesOfType[BLACK_KNIGHT], &pieceCount[6], 
-                        &blackPieces[1 * MAX_PIECES_PER_SIDE]); 
-    initializePieceData(&position->piecesOfType[BLACK_BISHOP], &pieceCount[7], 
-                        &blackPieces[2 * MAX_PIECES_PER_SIDE]); 
-    initializePieceData(&position->piecesOfType[BLACK_ROOK], &pieceCount[8], 
-                        &blackPieces[3 * MAX_PIECES_PER_SIDE]); 
-    initializePieceData(&position->piecesOfType[BLACK_QUEEN], &pieceCount[9], 
-                        &blackPieces[4 * MAX_PIECES_PER_SIDE]); 
-   
-    tableNr = IDescFindFromCounters(pieceCount); 
-   
-    if (tableNr == 0) 
-    { 
-       return TABLEBASE_ERROR; 
-    } 
-   
-    whitePieces[5 * MAX_PIECES_PER_SIDE] = position->king[WHITE]; 
-    blackPieces[5 * MAX_PIECES_PER_SIDE] = position->king[BLACK]; 
-   
-    if (tableNr > 0) 
-    { 
-       color = position->activeColor; 
-       fInvert = 0; 
-       pwhite = whitePieces; 
-       pblack = blackPieces; 
-    } 
-    else 
-    { 
-       color = opponent(position->activeColor); 
-       fInvert = 1; 
-       pwhite = blackPieces; 
-       pblack = whitePieces; 
-       tableNr = -tableNr; 
-    } 
-   
- #if defined __APPLE__ 
-    pthread_mutex_lock((pthread_mutex_t *) & lock); 
- #elif defined _MSC_VER 
-    while (lock) 
-       Sleep (1); // allow context switching 
-    lock = 1; // Pierre-Marie Baty -- Win32 thread locking 
- #else 
-    pthread_spin_lock(&lock); 
- #endif 
-   
-    if (FRegisteredFun(tableNr, color) == FALSE) 
-    { 
- #if defined __APPLE__ 
-       pthread_mutex_unlock((pthread_mutex_t *) & lock); 
- #elif defined _MSC_VER 
-       lock = 0; // Pierre-Marie Baty -- Win32 thread locking 
- #else 
-       pthread_spin_unlock(&lock); 
- #endif 
-   
-       return TABLEBASE_ERROR; 
-    } 
-   
-    if (position->enPassantSquare != NO_SQUARE) 
-    { 
-       const Bitboard attackers = 
-          position->piecesOfType[PAWN | position->activeColor] & 
-          generalMoves[PAWN | opponent(position->activeColor)] 
-          [position->enPassantSquare]; 
-   
-       if (attackers != EMPTY_BITBOARD) 
-       { 
-          /* 
-             dumpSquare(position->enPassantSquare); 
-             dumpPosition(position); 
-           */ 
-   
-          enPassantSquare = position->enPassantSquare; 
-       } 
-    } 
-   
-    index = PfnIndCalcFun(tableNr, color) 
-       (pwhite, pblack, enPassantSquare, fInvert); 
-   
-    tableValue = L_TbtProbeTable(tableNr, color, index); 
-   
- #if defined __APPLE__ 
-    pthread_mutex_unlock((pthread_mutex_t *) & lock); 
- #elif defined _MSC_VER 
-    lock = 0; // Pierre-Marie Baty -- Win32 thread locking 
- #else 
-    pthread_spin_unlock(&lock); 
- #endif 
-   
-    if (tableValue == bev_broken) 
-    { 
-       return TABLEBASE_ERROR; 
-    } 
-   
-    if (tableValue == 0) 
-    { 
-       return 0; 
-    } 
-   
-    fullMoves = (tableValue > 0 ? 
-                 1 + tbbe_ssL - tableValue : bev_li0 - tableValue); 
-   
-    return getMateValue(fullMoves); 
- } 
-   
- int initializeModuleTablebase() 
- { 
- #if defined __APPLE__ 
-    pthread_mutex_init((pthread_mutex_t *) & lock, tbAccessCount); 
- #elif defined _MSC_VER 
-    lock = 0; // Pierre-Marie Baty -- Win32 thread locking 
- #else 
-    pthread_spin_init(&lock, tbAccessCount); 
- #endif 
-   
-    if (commandlineOptions.tablebasePath != 0) 
-    { 
-       return initializeTablebase(commandlineOptions.tablebasePath); 
-    } 
-    else 
-    { 
-       return 0; 
-    } 
- } 
-   
- static int testTableFinder() 
- { 
- #ifndef NDEBUG 
-    Variation variation; 
-    int tableValue; 
-   
-    initializeVariation(&variation, "B6k/8/8/8/8/8/8/K6N w - - 0 1"); 
-    tableValue = probeTablebase(&variation.singlePosition); 
-   
-    initializeVariation(&variation, "B6k/8/8/8/8/8/8/K6N b - - 0 1"); 
-    tableValue = probeTablebase(&variation.singlePosition); 
- #endif 
-   
-    return 0; 
- } 
-   
- static int testMateValues() 
- { 
- #ifndef NDEBUG 
-    Variation variation; 
-    int tableValue; 
-   
-    initializeVariation(&variation, "R6k/8/6K1/8/8/8/8/8 b - - 0 1"); 
-    tableValue = probeTablebase(&variation.singlePosition); 
-    assert(- tableValue  ==-  VALUE_MATED );
 
-   
-    initializeVariation(&variation, "7k/8/6K1/8/8/8/8/R7 w - - 0 1"); 
-    tableValue = probeTablebase(&variation.singlePosition); 
-    assert(- tableValue  == -- VALUE_MATED  - 1);
 
- #endif 
-   
-    return 0; 
- } 
-   
- int testModuleTablebase() 
- { 
-    int result; 
-   
-    if (tbAvailable == FALSE) 
-    { 
-       return 0; 
-    } 
-   
-    if (commandlineOptions.tablebasePath == 0) 
-    { 
-       return 0; 
-    } 
-   
-    if ((result = testTableFinder()) != 0) 
-    { 
-       return result; 
-    } 
-   
-    if ((result = testMateValues()) != 0) 
-    { 
-       return result; 
-    } 
-   
-    return 0; 
- } 
- #endif 
-