3 Copyright (c) Scott Gasch
11 Large data structures and the code that creates/verifies them.
19 $Id: data.c 345 2007-12-02 22:56:42Z scott $
25 // Distance between two squares lookup table
26 ULONG g_uDistance[256];
27 ULONG *g_pDistance = &(g_uDistance[128]);
29 // Who controls the square lookup table
30 CHAR g_SwapTable[14][32][32];
32 // Vector (bitvector indicating which pieces can move between squares) and
33 // Delta (direction to travel to get from square a to square b) lookup table.
34 VECTOR_DELTA g_VectorDelta[256];
35 VECTOR_DELTA *g_pVectorDelta = &(g_VectorDelta[128]);
37 // How many generated moves should we bother to sort
38 ULONG g_uSearchSortLimits[MAX_PLY_PER_SEARCH];
40 // Hardcoded move patterns to terminate PVs with
42 MOVE HASHMOVE = {0x11118888};
43 MOVE RECOGNMOVE = {0x22228888};
44 MOVE DRAWMOVE = {0x33338888};
45 MOVE MATEMOVE = {0x44448888};
48 FLAG g_fIsWhiteSquare[128];
52 DistanceBetweenSquares(COOR a, COOR b)
54 int i = (int)a - (int)b + 128;
55 int j = (int)b - (int)a + 128;
56 ASSERT(IS_ON_BOARD(a));
57 ASSERT(IS_ON_BOARD(b));
58 ASSERT((i >= 0) && (i < 256));
59 ASSERT(g_uDistance[i] == REAL_DISTANCE(a, b));
60 ASSERT(g_pDistance[a - b] == g_uDistance[i]);
61 ASSERT(g_pDistance[b - a] == g_uDistance[i]);
62 ASSERT(g_uDistance[j] == REAL_DISTANCE(a, b));
63 return(REAL_DISTANCE(a, b));
66 #define VALID_VECTOR(x) \
68 ((x) == (1 << KNIGHT)) || \
69 ((x) == ( (1 << BISHOP) | (1 << QUEEN))) || \
70 ((x) == ( (1 << ROOK) | (1 << QUEEN))) || \
71 ((x) == ( (1 << BISHOP) | (1 << QUEEN) | (1 << KING))) || \
72 ((x) == ( (1 << ROOK) | (1 << QUEEN) | (1 << KING))) || \
73 ((x) == ( (1 << BISHOP) | (1 << QUEEN) | (1 << KING) | (1 << PAWN))))
76 #define VALID_INDEX(x) \
77 (((x) >= -128) && ((x) <= 127))
80 CheckVectorWithIndex(int i, ULONG uColor)
83 ASSERT(VALID_INDEX(i));
84 ASSERT(IS_VALID_COLOR(uColor));
85 u = g_pVectorDelta[i].iVector[uColor];
86 ASSERT(VALID_VECTOR(u));
87 ASSERT(u == g_VectorDelta[i + 128].iVector[uColor]);
88 ASSERT(&(g_pVectorDelta[i]) == &(g_VectorDelta[i + 128]));
92 #define VALID_DELTA(x) \
94 ((x) == +1) || ((x) == -1) || \
95 ((x) == +16) || ((x) == -16) || \
96 ((x) == +15) || ((x) == -15) || \
97 ((x) == +17) || ((x) == -17))
100 DirectionBetweenSquaresWithIndex(int i)
103 ASSERT(VALID_INDEX(i));
104 iDir = g_pVectorDelta[i].iDelta;
105 ASSERT(iDir == g_VectorDelta[i + 128].iDelta);
106 ASSERT(&(g_pVectorDelta[i]) == &(g_VectorDelta[i + 128]));
107 ASSERT(VALID_DELTA(iDir));
108 ASSERT(iDir == -g_pVectorDelta[i].iNegDelta);
113 DirectionBetweenSquaresFromTo(COOR from, COOR to)
115 int i = (int)from - (int)to;
116 return DirectionBetweenSquaresWithIndex(i);
120 NegativeDirectionBetweenSquaresWithIndex(int i)
123 ASSERT(VALID_INDEX(i));
124 iDir = g_pVectorDelta[i].iNegDelta;
125 ASSERT(iDir == g_VectorDelta[i + 128].iNegDelta);
126 ASSERT(&(g_pVectorDelta[i]) == &(g_VectorDelta[i + 128]));
127 ASSERT(VALID_DELTA(iDir));
128 ASSERT(iDir == -g_pVectorDelta[i].iDelta);
133 DirectionBetweenSquares(COOR cFrom, COOR cTo)
135 int i = (int)cFrom - (int)cTo;
136 return(DirectionBetweenSquaresWithIndex(i));
140 IsSquareWhite(COOR c)
143 FLAG f = IS_WHITE_SQUARE_COOR(c);
144 ASSERT(IS_ON_BOARD(c));
145 ASSERT(f == g_fIsWhiteSquare[c]);
147 ASSERT(f == ((bb & BBWHITESQ) != 0));
148 ASSERT(f == ((bb & BBBLACKSQ) == 0));
154 VerifyVectorDelta(void)
163 ASSERT(VALID_VECTOR(g_VectorDelta[iIndex].iVector[BLACK]));
164 ASSERT(VALID_VECTOR(g_VectorDelta[iIndex].iVector[WHITE]));
165 ASSERT(VALID_DELTA(g_VectorDelta[iIndex].iDelta));
166 ASSERT(VALID_DELTA(g_VectorDelta[iIndex].iNegDelta));
167 ASSERT(-g_VectorDelta[iIndex].iDelta ==
168 g_VectorDelta[iIndex].iNegDelta);
169 iChecksum += g_VectorDelta[iIndex].iVector[BLACK] * iIndex;
170 iChecksum += g_VectorDelta[iIndex].iVector[WHITE] * iIndex;
171 iChecksum += g_VectorDelta[iIndex].iDelta * iIndex;
174 if (iChecksum != 0xb1b58)
176 UtilPanic(DETECTED_INCORRECT_INITIALIZATION,
186 InitializeSearchDepthArray(void)
191 x < ARRAY_LENGTH(g_uSearchSortLimits);
194 g_uSearchSortLimits[x] = 5;
196 g_uSearchSortLimits[0] = 0;
197 g_uSearchSortLimits[1] = 17;
198 g_uSearchSortLimits[2] = 12;
199 g_uSearchSortLimits[3] = 9;
200 g_uSearchSortLimits[4] = 7;
201 g_uSearchSortLimits[5] = 6;
206 GetSearchSortLimit(ULONG uPly)
209 ASSERT(uPly < MAX_PLY_PER_SEARCH);
210 ASSERT(g_uSearchSortLimits[uPly] != 0);
211 return(g_uSearchSortLimits[uPly]);
216 InitializeWhiteSquaresTable(void)
222 g_fIsWhiteSquare[c] = FALSE;
227 g_fIsWhiteSquare[c] = IS_WHITE_SQUARE_COOR(c);
232 InitializeVectorDeltaTable(void)
241 static const BYTE _LOCATIONS[] =
243 D4, A5, A3, G3, C1, B5, H4, E5, E3, A6, C5, A5, A5,
244 G5, A6, D3, D2, A5, E1, E1, A6, H4, B2, D1, D2, E5
246 static int iNumDirs[7] = { 0, 0, 8, 4, 4, 8, 8 };
247 static int iDelta[7][8] = { { 0, 0, 0, 0, 0, 0, 0, 0 },
248 { 0, 0, 0, 0, 0, 0, 0, 0 },
249 { -33, -31, -18, -14, +14, +18, +31, +33 },
250 { -17, -15, +15, +17, 0, 0, 0, 0 },
251 { -16, -1, +1, +16, 0, 0, 0, 0 },
252 { -17, -16, -15, -1, +1, +15, +16, +17 },
253 { -17, -16, -15, -1, +1, +15, +16, +17 } };
255 memset(g_VectorDelta, 0, sizeof(g_VectorDelta));
256 FOREACH_SQUARE(cStart)
258 if (!IS_ON_BOARD(cStart)) continue;
259 for (u = 0; u < ARRAY_LENGTH(_LOCATIONS); u++)
261 if (cStart == _LOCATIONS[u])
270 iIndex = (int)cStart - ((int)cStart - 17) + 128;
271 g_VectorDelta[iIndex].iVector[WHITE] |= (1 << PAWN);
272 iIndex = (int)cStart - ((int)cStart - 15) + 128;
273 g_VectorDelta[iIndex].iVector[WHITE] |= (1 << PAWN);
275 iIndex = (int)cStart - ((int)cStart + 17) + 128;
276 g_VectorDelta[iIndex].iVector[BLACK] |= (1 << PAWN);
277 iIndex = (int)cStart - ((int)cStart + 15) + 128;
278 g_VectorDelta[iIndex].iVector[BLACK] |= (1 << PAWN);
283 for (p = KNIGHT; p <= KING; p++)
290 cNew = cRay + iDelta[p][iDir];
291 while (IS_ON_BOARD(cNew))
293 iIndex = (int)cStart - (int)cNew + 128;
296 // Fill in the vector
298 g_VectorDelta[iIndex].iVector[WHITE] |= (1 << p);
299 g_VectorDelta[iIndex].iVector[BLACK] |= (1 << p);
304 if (FILE(cStart) == FILE(cNew))
308 g_VectorDelta[iIndex].iDelta = 16;
309 g_VectorDelta[iIndex].iNegDelta = -16;
313 g_VectorDelta[iIndex].iDelta = -16;
314 g_VectorDelta[iIndex].iNegDelta = 16;
317 else if (RANK(cStart) == RANK(cNew))
321 g_VectorDelta[iIndex].iDelta = 1;
322 g_VectorDelta[iIndex].iNegDelta = -1;
326 g_VectorDelta[iIndex].iDelta = -1;
327 g_VectorDelta[iIndex].iNegDelta = 1;
330 else if ((cStart % 15) == (cNew % 15))
334 g_VectorDelta[iIndex].iDelta = +15;
335 g_VectorDelta[iIndex].iNegDelta = -15;
339 g_VectorDelta[iIndex].iDelta = -15;
340 g_VectorDelta[iIndex].iNegDelta = 15;
343 else if ((cStart % 17) == (cNew % 17))
347 g_VectorDelta[iIndex].iDelta = +17;
348 g_VectorDelta[iIndex].iNegDelta = -17;
352 g_VectorDelta[iIndex].iDelta = -17;
353 g_VectorDelta[iIndex].iNegDelta = 17;
356 cNew += iDelta[p][iDir];
358 if ((KING == p) || (KNIGHT == p))
367 (void)VerifyVectorDelta();
370 // nasm under OSX/macho has a nasty bug that causes the addresses
371 // of extern symbols to be screwed up. I only use two extern data
372 // structs in the x86.asm code: the vector delta table and the
373 // piece data table. My workaround to the nasm bug is to copy
374 // these tables into a symbol in the asm module and access them
377 extern VECTOR_DELTA *g_NasmVectorDelta;
378 extern PIECE_DATA *g_NasmPieceData;
380 memcpy(&g_NasmVectorDelta, &g_VectorDelta, sizeof(g_VectorDelta));
381 memcpy(&g_NasmPieceData, &g_PieceData, sizeof(g_PieceData));
386 // TODO: fix this to use attack counts also
389 InitializeSwapTable(void)
391 ULONG GET_HIGH_BIT[32] =
436 for (p = 0; p <= WHITE_KING; p++)
440 for (uBlack = 0; uBlack < 32; uBlack++)
442 for (uWhite = 0; uWhite < 32; uWhite++)
444 uGains[BLACK] = uGains[WHITE] = 0;
445 uAttacks[BLACK] = uBlack;
446 uAttacks[WHITE] = uWhite;
447 uAtStake = PIECE_VALUE(p);
449 if (GET_COLOR(p) == WHITE)
455 // Ok, if the side on move has an attack, play it
456 // and give them credit for some plunder.
458 while(uAttacks[uOnMove])
461 uGains[uOnMove] += uAtStake;
462 uAtStake = GET_HIGH_BIT[uAttacks[uOnMove]];
465 uAtStake = VALUE_PAWN;
467 else if (uAtStake == 8)
469 uAtStake = VALUE_BISHOP;
471 else if (uAtStake == 4)
473 uAtStake = VALUE_ROOK;
475 else if (uAtStake == 2)
477 uAtStake = VALUE_QUEEN;
479 else if (uAtStake == 1)
482 // Don't let them move into check
484 if (uAttacks[FLIP(uOnMove)])
486 uGains[uOnMove] -= uOld;
493 UtilPanic(SHOULD_NOT_GET_HERE,
494 NULL, NULL, NULL, NULL,
497 uAttacks[uOnMove] &= ~GET_HIGH_BIT[uAttacks[uOnMove]];
498 uOnMove = FLIP(uOnMove);
502 // The side on move doesn't have an attack... does
503 // the side not on move have an attack? If so they
504 // get a chance to assert some more control.
506 if (uAttacks[FLIP(uOnMove)])
508 uGains[FLIP(uOnMove)] += 100;
511 if (uGains[BLACK] > uGains[WHITE])
513 iDiff = uGains[BLACK] - uGains[WHITE];
515 iDiff += (iDiff == 0);
516 g_SwapTable[p][uWhite][uBlack] = MIN(+127, iDiff);
517 g_SwapTable[p][uWhite][uBlack] *= -1;
519 else if (uGains[WHITE] > uGains[BLACK])
521 iDiff = uGains[WHITE] - uGains[BLACK];
523 iDiff += (iDiff == 0);
524 g_SwapTable[p][uWhite][uBlack] = MIN(+127, iDiff);
528 g_SwapTable[p][uWhite][uBlack] = 0;
533 else // no piece sitting there
535 for (uBlack = 0; uBlack < 32; uBlack++)
537 for (uWhite = 0; uWhite < 32; uWhite++)
541 g_SwapTable[p][uWhite][uBlack] = -1;
543 else if (uWhite > uBlack)
545 g_SwapTable[p][uWhite][uBlack] = +1;
549 g_SwapTable[p][uWhite][uBlack] = 0;
558 InitializeDistanceTable(void)
566 for (x = 0; x < 128; x++)
568 if (!IS_ON_BOARD(x)) continue;
569 for (y = 0; y < 128; y++)
571 if (!IS_ON_BOARD(y)) continue;
574 g_uDistance[i] = REAL_DISTANCE(x, y);
575 ASSERT(g_uDistance[i] >= 0);
576 ASSERT(g_uDistance[i] <= 7);
581 for (x = 0; x < 128; x++)
583 if (!IS_ON_BOARD(x)) continue;
584 for (y = 0; y < 128; y++)
586 if (!IS_ON_BOARD(y)) continue;
587 i = (int)x - (int)y + 128;
588 ASSERT(g_uDistance[i] == REAL_DISTANCE(x, y));
589 ASSERT(g_pDistance[x - y] == g_uDistance[i]);
590 ASSERT(&(g_pDistance[x - y]) == &(g_uDistance[i]));
591 j = (int)y - (int)x + 128;
592 ASSERT(g_uDistance[j] == REAL_DISTANCE(x, y));
593 ASSERT(g_pDistance[y - x] == g_uDistance[j]);
594 ASSERT(&(g_pDistance[y - x]) == &(g_uDistance[j]));