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 |