Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
33 | pmbaty | 1 | #if !defined(NOEGTB) |
2 | # include "chess.h" |
||
3 | # include "data.h" |
||
4 | /* last modified 02/23/14 */ |
||
5 | /* |
||
6 | ******************************************************************************* |
||
7 | * * |
||
8 | * EGTBProbe() is the interface to the new tablebase code by Eugene Nalimov. * |
||
9 | * This is called from Search() after a capture, when the number of pieces * |
||
10 | * remaining on the board is less than or equal to the max number of pieces * |
||
11 | * we have in the EGTB files that are available for use. * |
||
12 | * * |
||
13 | ******************************************************************************* |
||
14 | */ |
||
108 | pmbaty | 15 | # define \ |
16 | VInitSqCtr(rgCtr, rgSquares, piece, bitboard) { \ |
||
17 | int cPieces=0; \ |
||
18 | uint64_t bbTemp=(bitboard); \ |
||
19 | while (bbTemp) { \ |
||
20 | const squaret sq=MSB(bbTemp); \ |
||
21 | (rgSquares)[(piece)*C_PIECES+cPieces]=sq; \ |
||
22 | cPieces++; \ |
||
23 | Clear(sq, bbTemp); \ |
||
24 | } \ |
||
25 | (rgCtr)[(piece)]=cPieces; \ |
||
33 | pmbaty | 26 | } |
27 | # define T_INDEX64 |
||
108 | pmbaty | 28 | # define C_PIECES 3 /* Maximum # of pieces of one color OTB */ |
33 | pmbaty | 29 | # if defined (T_INDEX64) && defined (_MSC_VER) |
30 | typedef uint64_t INDEX; |
||
31 | # elif defined (T_INDEX64) |
||
32 | typedef uint64_t INDEX; |
||
33 | # else |
||
34 | typedef unsigned long INDEX; |
||
35 | # endif |
||
36 | typedef unsigned int squaret; |
||
37 | |||
38 | /* Those declarations necessary because Crafty is C, not C++ program */ |
||
39 | # if defined (_MSC_VER) |
||
108 | pmbaty | 40 | # define TB_FASTCALL __fastcall |
33 | pmbaty | 41 | # else |
42 | # define TB_FASTCALL |
||
43 | # endif |
||
44 | typedef int pcolor; |
||
45 | |||
108 | pmbaty | 46 | # define x_colorWhite 0 |
47 | # define x_colorBlack 1 |
||
48 | # define x_colorNeutral 2 |
||
33 | pmbaty | 49 | # define COLOR_DECLARED |
50 | typedef int piece; |
||
51 | |||
108 | pmbaty | 52 | # define x_pieceNone 0 |
53 | # define x_piecePawn 1 |
||
54 | # define x_pieceKnight 2 |
||
55 | # define x_pieceBishop 3 |
||
56 | # define x_pieceRook 4 |
||
57 | # define x_pieceQueen 5 |
||
58 | # define x_pieceKing 6 |
||
33 | pmbaty | 59 | # define PIECES_DECLARED |
60 | typedef signed char tb_t; |
||
61 | |||
62 | # define pageL 65536 |
||
63 | # define tbbe_ssL ((pageL-4)/2) |
||
108 | pmbaty | 64 | # define bev_broken (tbbe_ssL+1) /* illegal or busted */ |
65 | # define bev_mi1 tbbe_ssL /* mate in 1 move */ |
||
33 | pmbaty | 66 | # define bev_mimin 1 /* mate in max moves */ |
67 | # define bev_draw 0 /* draw */ |
||
108 | pmbaty | 68 | # define bev_limax (-1) /* mated in max moves */ |
33 | pmbaty | 69 | # define bev_li0 (-tbbe_ssL) |
108 | pmbaty | 70 | /* mated in 0 moves */ |
33 | pmbaty | 71 | typedef INDEX(TB_FASTCALL * PfnCalcIndex) |
72 | (squaret *, squaret *, squaret, int fInverse); |
||
73 | extern int IDescFindFromCounters(int *); |
||
74 | extern int FRegisteredFun(int, pcolor); |
||
75 | extern PfnCalcIndex PfnIndCalcFun(int, pcolor); |
||
76 | extern int TB_FASTCALL L_TbtProbeTable(int, pcolor, INDEX); |
||
77 | |||
78 | # define PfnIndCalc PfnIndCalcFun |
||
79 | # define FRegistered FRegisteredFun |
||
80 | int EGTBProbe(TREE * RESTRICT tree, int ply, int wtm, int *score) { |
||
81 | int rgiCounters[10], iTb, fInvert; |
||
82 | pcolor side; |
||
83 | squaret rgsqWhite[C_PIECES * 5 + 1], rgsqBlack[C_PIECES * 5 + 1]; |
||
84 | squaret *psqW, *psqB, sqEnP; |
||
85 | INDEX ind; |
||
86 | int tbValue; |
||
87 | |||
88 | /* |
||
89 | ************************************************************ |
||
90 | * * |
||
91 | * Initialize counters and piece arrays so the probe code * |
||
92 | * can compute the modified Godel number. * |
||
93 | * * |
||
94 | ************************************************************ |
||
95 | */ |
||
96 | VInitSqCtr(rgiCounters, rgsqWhite, 0, Pawns(white)); |
||
97 | VInitSqCtr(rgiCounters, rgsqWhite, 1, Knights(white)); |
||
98 | VInitSqCtr(rgiCounters, rgsqWhite, 2, Bishops(white)); |
||
99 | VInitSqCtr(rgiCounters, rgsqWhite, 3, Rooks(white)); |
||
100 | VInitSqCtr(rgiCounters, rgsqWhite, 4, Queens(white)); |
||
101 | VInitSqCtr(rgiCounters + 5, rgsqBlack, 0, Pawns(black)); |
||
102 | VInitSqCtr(rgiCounters + 5, rgsqBlack, 1, Knights(black)); |
||
103 | VInitSqCtr(rgiCounters + 5, rgsqBlack, 2, Bishops(black)); |
||
104 | VInitSqCtr(rgiCounters + 5, rgsqBlack, 3, Rooks(black)); |
||
105 | VInitSqCtr(rgiCounters + 5, rgsqBlack, 4, Queens(black)); |
||
106 | /* |
||
107 | ************************************************************ |
||
108 | * * |
||
109 | * Quick early exit. Is the tablebase for the current set * |
||
110 | * of pieces registered? * |
||
111 | * * |
||
112 | ************************************************************ |
||
113 | */ |
||
114 | iTb = IDescFindFromCounters(rgiCounters); |
||
115 | if (!iTb) |
||
116 | return 0; |
||
117 | /* |
||
118 | ************************************************************ |
||
119 | * * |
||
120 | * Yes, finish setting up to probe the tablebase. If * |
||
121 | * black is the "winning" side (more pieces) then we need * |
||
122 | * to "invert" the pieces in the lists. * |
||
123 | * * |
||
124 | ************************************************************ |
||
125 | */ |
||
126 | rgsqWhite[C_PIECES * 5] = KingSQ(white); |
||
127 | rgsqBlack[C_PIECES * 5] = KingSQ(black); |
||
128 | if (iTb > 0) { |
||
129 | side = wtm ? x_colorWhite : x_colorBlack; |
||
130 | fInvert = 0; |
||
131 | psqW = rgsqWhite; |
||
132 | psqB = rgsqBlack; |
||
133 | } else { |
||
134 | side = wtm ? x_colorBlack : x_colorWhite; |
||
135 | fInvert = 1; |
||
136 | psqW = rgsqBlack; |
||
137 | psqB = rgsqWhite; |
||
138 | iTb = -iTb; |
||
139 | } |
||
140 | /* |
||
141 | ************************************************************ |
||
142 | * * |
||
143 | * Now check to see if this particular tablebase for this * |
||
144 | * color to move is registered. * |
||
145 | * * |
||
146 | ************************************************************ |
||
147 | */ |
||
148 | if (!FRegistered(iTb, side)) |
||
149 | return 0; |
||
150 | sqEnP = EnPassant(ply) ? EnPassant(ply) : 127; |
||
151 | ind = PfnIndCalc(iTb, side) (psqW, psqB, sqEnP, fInvert); |
||
152 | tbValue = L_TbtProbeTable(iTb, side, ind); |
||
153 | if (bev_broken == tbValue) |
||
154 | return 0; |
||
155 | /* |
||
156 | ************************************************************ |
||
157 | * * |
||
158 | * Convert to correct MATE range to match the value * |
||
159 | * Crafty uses. * |
||
160 | * * |
||
161 | ************************************************************ |
||
162 | */ |
||
163 | if (tbValue > 0) |
||
164 | *score = MATE + 2 * (-bev_mi1 + tbValue - 1); |
||
165 | else if (tbValue < 0) |
||
166 | *score = -MATE + 2 * (bev_mi1 + tbValue); |
||
167 | else |
||
108 | pmbaty | 168 | *score = 0; |
33 | pmbaty | 169 | return 1; |
170 | } |
||
171 | #endif |