Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 154 | pmbaty | 1 | /* | 
| 2 |  * tbprobe.h | ||
| 3 |  * (C) 2015 basil, all rights reserved, | ||
| 4 |  * | ||
| 5 |  * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 |  * copy of this software and associated documentation files (the "Software"), | ||
| 7 |  * to deal in the Software without restriction, including without limitation | ||
| 8 |  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 9 |  * and/or sell copies of the Software, and to permit persons to whom the | ||
| 10 |  * Software is furnished to do so, subject to the following conditions: | ||
| 11 |  * | ||
| 12 |  * The above copyright notice and this permission notice shall be included in | ||
| 13 |  * all copies or substantial portions of the Software. | ||
| 14 |  * | ||
| 15 |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 18 |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 20 |  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 21 |  * DEALINGS IN THE SOFTWARE. | ||
| 22 |  */ | ||
| 23 | |||
| 24 | #ifndef TBPROBE_H | ||
| 25 | #  define TBPROBE_H | ||
| 26 | |||
| 27 | #  include "tbconfig.h" | ||
| 28 | |||
| 29 | #  ifdef __cplusplus | ||
| 30 | extern "C" { | ||
| 31 | #  endif | ||
| 32 | |||
| 33 | #  ifndef TB_NO_STDINT | ||
| 34 | #    include <stdint.h> | ||
| 35 | #  else | ||
| 36 | typedef unsigned char uint8_t; | ||
| 37 | typedef unsigned short uint16_t; | ||
| 38 | typedef unsigned uint32_t; | ||
| 39 | typedef long long unsigned uint64_t; | ||
| 40 | typedef char int8_t; | ||
| 41 | typedef short int16_t; | ||
| 42 | typedef int int32_t; | ||
| 43 | typedef long long int64_t; | ||
| 44 | #  endif | ||
| 45 | |||
| 46 | #  ifndef TB_NO_STDBOOL | ||
| 47 | #    include <stdbool.h> | ||
| 48 | #  else | ||
| 49 | #    ifndef __cplusplus | ||
| 50 | typedef uint8_t bool; | ||
| 51 | #      define true    1 | ||
| 52 | #      define false   0 | ||
| 53 | #    endif | ||
| 54 | #  endif | ||
| 55 | |||
| 56 | /* | ||
| 57 |  * Internal definitions.  Do not call these functions directly. | ||
| 58 |  */ | ||
| 59 | extern bool tb_init_impl(const char *_path); | ||
| 60 | extern unsigned tb_probe_wdl_impl(uint64_t _white, uint64_t _black, | ||
| 61 | uint64_t _kings, uint64_t _queens, uint64_t _rooks, uint64_t _bishops, | ||
| 62 | uint64_t _knights, uint64_t _pawns, unsigned _ep, bool _turn, | ||
| 63 | uint64_t _hash); | ||
| 64 | extern unsigned tb_probe_root_impl(uint64_t _white, uint64_t _black, | ||
| 65 | uint64_t _kings, uint64_t _queens, uint64_t _rooks, uint64_t _bishops, | ||
| 66 | uint64_t _knights, uint64_t _pawns, unsigned _rule50, unsigned _ep, | ||
| 67 | bool _turn, unsigned *_results); | ||
| 68 | |||
| 69 | /****************************************************************************/ | ||
| 70 | /* MAIN API                                                                 */ | ||
| 71 | /****************************************************************************/ | ||
| 72 | |||
| 73 | #  define TB_MAX_MOVES                (192+1) | ||
| 74 | |||
| 75 | #  define TB_CASTLING_K               0x1 | ||
| 76 |  /* White king-side. */ | ||
| 77 | #  define TB_CASTLING_Q               0x2 | ||
| 78 |  /* White queen-side. */ | ||
| 79 | #  define TB_CASTLING_k               0x4 | ||
| 80 |  /* Black king-side. */ | ||
| 81 | #  define TB_CASTLING_q               0x8 | ||
| 82 |  /* Black queen-side. */ | ||
| 83 | |||
| 84 | #  define TB_LOSS                     0 | ||
| 85 |  /* LOSS */ | ||
| 86 | #  define TB_BLESSED_LOSS             1 | ||
| 87 |  /* LOSS but 50-move draw */ | ||
| 88 | #  define TB_DRAW                     2 | ||
| 89 |  /* DRAW */ | ||
| 90 | #  define TB_CURSED_WIN               3 | ||
| 91 |  /* WIN but 50-move draw  */ | ||
| 92 | #  define TB_WIN                      4 | ||
| 93 |  /* WIN  */ | ||
| 94 | |||
| 95 | #  define TB_PROMOTES_NONE            0 | ||
| 96 | #  define TB_PROMOTES_QUEEN           1 | ||
| 97 | #  define TB_PROMOTES_ROOK            2 | ||
| 98 | #  define TB_PROMOTES_BISHOP          3 | ||
| 99 | #  define TB_PROMOTES_KNIGHT          4 | ||
| 100 | |||
| 101 | #  define TB_RESULT_WDL_MASK          0x0000000F | ||
| 102 | #  define TB_RESULT_TO_MASK           0x000003F0 | ||
| 103 | #  define TB_RESULT_FROM_MASK         0x0000FC00 | ||
| 104 | #  define TB_RESULT_PROMOTES_MASK     0x00070000 | ||
| 105 | #  define TB_RESULT_EP_MASK           0x00080000 | ||
| 106 | #  define TB_RESULT_DTZ_MASK          0xFFF00000 | ||
| 107 | #  define TB_RESULT_WDL_SHIFT         0 | ||
| 108 | #  define TB_RESULT_TO_SHIFT          4 | ||
| 109 | #  define TB_RESULT_FROM_SHIFT        10 | ||
| 110 | #  define TB_RESULT_PROMOTES_SHIFT    16 | ||
| 111 | #  define TB_RESULT_EP_SHIFT          19 | ||
| 112 | #  define TB_RESULT_DTZ_SHIFT         20 | ||
| 113 | |||
| 114 | #  define TB_GET_WDL(_res)                        \ | ||
| 115 |     (((_res) & TB_RESULT_WDL_MASK) >> TB_RESULT_WDL_SHIFT) | ||
| 116 | #  define TB_GET_TO(_res)                         \ | ||
| 117 |     (((_res) & TB_RESULT_TO_MASK) >> TB_RESULT_TO_SHIFT) | ||
| 118 | #  define TB_GET_FROM(_res)                       \ | ||
| 119 |     (((_res) & TB_RESULT_FROM_MASK) >> TB_RESULT_FROM_SHIFT) | ||
| 120 | #  define TB_GET_PROMOTES(_res)                   \ | ||
| 121 |     (((_res) & TB_RESULT_PROMOTES_MASK) >> TB_RESULT_PROMOTES_SHIFT) | ||
| 122 | #  define TB_GET_EP(_res)                         \ | ||
| 123 |     (((_res) & TB_RESULT_EP_MASK) >> TB_RESULT_EP_SHIFT) | ||
| 124 | #  define TB_GET_DTZ(_res)                        \ | ||
| 125 |     (((_res) & TB_RESULT_DTZ_MASK) >> TB_RESULT_DTZ_SHIFT) | ||
| 126 | |||
| 127 | #  define TB_SET_WDL(_res, _wdl)                  \ | ||
| 128 |     (((_res) & ~TB_RESULT_WDL_MASK) |           \ | ||
| 129 |      (((_wdl) << TB_RESULT_WDL_SHIFT) & TB_RESULT_WDL_MASK)) | ||
| 130 | #  define TB_SET_TO(_res, _to)                    \ | ||
| 131 |     (((_res) & ~TB_RESULT_TO_MASK) |            \ | ||
| 132 |      (((_to) << TB_RESULT_TO_SHIFT) & TB_RESULT_TO_MASK)) | ||
| 133 | #  define TB_SET_FROM(_res, _from)                \ | ||
| 134 |     (((_res) & ~TB_RESULT_FROM_MASK) |          \ | ||
| 135 |      (((_from) << TB_RESULT_FROM_SHIFT) & TB_RESULT_FROM_MASK)) | ||
| 136 | #  define TB_SET_PROMOTES(_res, _promotes)        \ | ||
| 137 |     (((_res) & ~TB_RESULT_PROMOTES_MASK) |      \ | ||
| 138 |      (((_promotes) << TB_RESULT_PROMOTES_SHIFT) & TB_RESULT_PROMOTES_MASK)) | ||
| 139 | #  define TB_SET_EP(_res, _ep)                    \ | ||
| 140 |     (((_res) & ~TB_RESULT_EP_MASK) |            \ | ||
| 141 |      (((_ep) << TB_RESULT_EP_SHIFT) & TB_RESULT_EP_MASK)) | ||
| 142 | #  define TB_SET_DTZ(_res, _dtz)                  \ | ||
| 143 |     (((_res) & ~TB_RESULT_DTZ_MASK) |           \ | ||
| 144 |      (((_dtz) << TB_RESULT_DTZ_SHIFT) & TB_RESULT_DTZ_MASK)) | ||
| 145 | |||
| 146 | #  define TB_RESULT_CHECKMATE         TB_SET_WDL(0, TB_WIN) | ||
| 147 | #  define TB_RESULT_STALEMATE         TB_SET_WDL(0, TB_DRAW) | ||
| 148 | #  define TB_RESULT_FAILED            0xFFFFFFFF | ||
| 149 | |||
| 150 | /* | ||
| 151 |  * The tablebase can be probed for any position where #pieces <= TB_LARGEST. | ||
| 152 |  */ | ||
| 153 | extern unsigned TB_LARGEST; | ||
| 154 | |||
| 155 | /* | ||
| 156 |  * Initialize the tablebase. | ||
| 157 |  * | ||
| 158 |  * PARAMETERS: | ||
| 159 |  * - path: | ||
| 160 |  *   The tablebase PATH string. | ||
| 161 |  * | ||
| 162 |  * RETURN: | ||
| 163 |  * - true=succes, false=failed.  The TB_LARGEST global will also be | ||
| 164 |  *   initialized.  If no tablebase files are found, then `true' is returned | ||
| 165 |  *   and TB_LARGEST is set to zero. | ||
| 166 |  */ | ||
| 167 | static inline bool tb_init(const char *_path) { | ||
| 168 | return tb_init_impl(_path); | ||
| 169 |   } | ||
| 170 | /* | ||
| 171 |  * Probe the Win-Draw-Loss (WDL) table. | ||
| 172 |  * | ||
| 173 |  * PARAMETERS: | ||
| 174 |  * - white, black, kings, queens, rooks, bishops, knights, pawns: | ||
| 175 |  *   The current position (bitboards). | ||
| 176 |  * - rule50: | ||
| 177 |  *   The 50-move half-move clock. | ||
| 178 |  * - castling: | ||
| 179 |  *   Castling rights.  Set to zero if no castling is possible. | ||
| 180 |  * - ep: | ||
| 181 |  *   The en passant square (if exists).  Set to zero if there is no en passant | ||
| 182 |  *   square. | ||
| 183 |  * - turn: | ||
| 184 |  *   true=white, false=black | ||
| 185 |  * | ||
| 186 |  * RETURN: | ||
| 187 |  * - One of {TB_LOSS, TB_BLESSED_LOSS, TB_DRAW, TB_CURSED_WIN, TB_WIN}. | ||
| 188 |  *   Otherwise returns TB_RESULT_FAILED if the probe failed. | ||
| 189 |  * | ||
| 190 |  * NOTES: | ||
| 191 |  * - Engines should use this function during search. | ||
| 192 |  * - This function is thread safe assuming TB_NO_THREADS is disabled. | ||
| 193 | */ static inline unsigned tb_probe_wdl( | ||
| 194 | uint64_t _white, uint64_t _black, uint64_t _kings, uint64_t _queens, | ||
| 195 | uint64_t _rooks, uint64_t _bishops, uint64_t _knights, uint64_t _pawns, | ||
| 196 | unsigned _rule50, unsigned _castling, unsigned _ep, bool _turn, | ||
| 197 | uint64_t _hash) { | ||
| 198 | if (_castling != 0) | ||
| 199 | return TB_RESULT_FAILED; | ||
| 200 | if (_rule50 != 0) | ||
| 201 | return TB_RESULT_FAILED; | ||
| 202 | return tb_probe_wdl_impl(_white, _black, _kings, _queens, _rooks, | ||
| 203 | _bishops, _knights, _pawns, _ep, _turn, _hash); | ||
| 204 |   } | ||
| 205 | |||
| 206 | /* | ||
| 207 |  * Probe the Distance-To-Zero (DTZ) table. | ||
| 208 |  * | ||
| 209 |  * PARAMETERS: | ||
| 210 |  * - white, black, kings, queens, rooks, bishops, knights, pawns: | ||
| 211 |  *   The current position (bitboards). | ||
| 212 |  * - rule50: | ||
| 213 |  *   The 50-move half-move clock. | ||
| 214 |  * - castling: | ||
| 215 |  *   Castling rights.  Set to zero if no castling is possible. | ||
| 216 |  * - ep: | ||
| 217 |  *   The en passant square (if exists).  Set to zero if there is no en passant | ||
| 218 |  *   square. | ||
| 219 |  * - turn: | ||
| 220 |  *   true=white, false=black | ||
| 221 |  * - results (OPTIONAL): | ||
| 222 |  *   Alternative results, one for each possible legal move.  The passed array | ||
| 223 |  *   must be TB_MAX_MOVES in size. | ||
| 224 |  *   If alternative results are not desired then set results=NULL. | ||
| 225 |  * | ||
| 226 |  * RETURN: | ||
| 227 |  * - A TB_RESULT value comprising: | ||
| 228 |  *   1) The WDL value (TB_GET_WDL) | ||
| 229 |  *   2) The suggested move (TB_GET_FROM, TB_GET_TO, TB_GET_PROMOTES, TB_GET_EP) | ||
| 230 |  *   3) The DTZ value (TB_GET_DTZ) | ||
| 231 |  *   The suggested move is guaranteed to preserved the WDL value. | ||
| 232 |  * | ||
| 233 |  *   Otherwise: | ||
| 234 |  *   1) TB_RESULT_STALEMATE is returned if the position is in stalemate. | ||
| 235 |  *   2) TB_RESULT_CHECKMATE is returned if the position is in checkmate. | ||
| 236 |  *   3) TB_RESULT_FAILED is returned if the probe failed. | ||
| 237 |  * | ||
| 238 |  *   If results!=NULL, then a TB_RESULT for each legal move will be generated | ||
| 239 |  *   and stored in the results array.  The results array will be terminated | ||
| 240 |  *   by TB_RESULT_FAILED. | ||
| 241 |  * | ||
| 242 |  * NOTES: | ||
| 243 |  * - Engines can use this function to probe at the root.  This function should | ||
| 244 |  *   not be used during search. | ||
| 245 |  * - DTZ tablebases can suggest unnatural moves, especially for losing | ||
| 246 |  *   positions.  Engines may prefer to traditional search combined with WDL | ||
| 247 |  *   move filtering using the alternative results array. | ||
| 248 |  * - This function is NOT thread safe.  For engines this function should only | ||
| 249 |  *   be called once at the root per search. | ||
| 250 |  */ | ||
| 251 | static inline unsigned tb_probe_root(uint64_t _white, uint64_t _black, | ||
| 252 | uint64_t _kings, uint64_t _queens, uint64_t _rooks, uint64_t _bishops, | ||
| 253 | uint64_t _knights, uint64_t _pawns, unsigned _rule50, | ||
| 254 | unsigned _castling, unsigned _ep, bool _turn, unsigned *_results) { | ||
| 255 | if (_castling != 0) | ||
| 256 | return TB_RESULT_FAILED; | ||
| 257 | return tb_probe_root_impl(_white, _black, _kings, _queens, _rooks, | ||
| 258 | _bishops, _knights, _pawns, _rule50, _ep, _turn, _results); | ||
| 259 |   } | ||
| 260 | |||
| 261 | /****************************************************************************/ | ||
| 262 | /* HELPER API                                                               */ | ||
| 263 | /****************************************************************************/ | ||
| 264 | |||
| 265 | /* | ||
| 266 |  * The HELPER API provides some useful additional functions.  It is optional | ||
| 267 |  * and can be disabled by defining TB_NO_HELPER_API.  Engines should disable | ||
| 268 |  * the HELPER API. | ||
| 269 |  */ | ||
| 270 | |||
| 271 | #  ifndef TB_NO_HELPER_API | ||
| 272 | |||
| 273 | extern unsigned tb_pop_count(uint64_t _bb); | ||
| 274 | extern unsigned tb_lsb(uint64_t _bb); | ||
| 275 | extern uint64_t tb_pop_lsb(uint64_t _bb); | ||
| 276 | extern uint64_t tb_king_attacks(unsigned _square); | ||
| 277 | extern uint64_t tb_queen_attacks(unsigned _square, uint64_t _occ); | ||
| 278 | extern uint64_t tb_rook_attacks(unsigned _square, uint64_t _occ); | ||
| 279 | extern uint64_t tb_bishop_attacks(unsigned _square, uint64_t _occ); | ||
| 280 | extern uint64_t tb_knight_attacks(unsigned _square); | ||
| 281 | extern uint64_t tb_pawn_attacks(unsigned _square, bool _color); | ||
| 282 | |||
| 283 | #  endif | ||
| 284 | |||
| 285 | #  ifdef __cplusplus | ||
| 286 | } | ||
| 287 | #  endif | ||
| 288 | |||
| 289 | #endif |