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  */
tb_init(const char * _path)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.
tb_probe_wdl(uint64_t _white,uint64_t _black,uint64_t _kings,uint64_t _queens,uint64_t _rooks,uint64_t _bishops,uint64_t _knights,uint64_t _pawns,unsigned _rule50,unsigned _castling,unsigned _ep,bool _turn,uint64_t _hash)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  */
tb_probe_root(uint64_t _white,uint64_t _black,uint64_t _kings,uint64_t _queens,uint64_t _rooks,uint64_t _bishops,uint64_t _knights,uint64_t _pawns,unsigned _rule50,unsigned _castling,unsigned _ep,bool _turn,unsigned * _results)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
290