Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
112 pmbaty 1
/*
2
    Protector -- a UCI chess engine
3
 
4
    Copyright (C) 2009-2010 Raimund Heid (Raimund_Heid@yahoo.com)
5
 
6
    This program is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
19
*/
20
 
21
/*
22
   This module contains a bitboard-based chess move generator.
23
 */
24
#include <assert.h>
25
#include <string.h>
26
#include <stdlib.h>
27
#include <stdio.h>
28
#include "bitboard.h"
29
#include "io.h"
30
 
31
#ifndef __builtin_popcountll // Pierre-Marie Baty -- __builtin_popcountll support for MSVC 32-bit
32
int __builtin_popcountll (unsigned long long x) {
33
   static const unsigned long long m1 = 0x5555555555555555; //binary: 0101...
34
   static const unsigned long long m2 = 0x3333333333333333; //binary: 00110011..
35
   static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f; //binary:  4 zeros,  4 ones ...
36
   static const unsigned long long h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
37
   x -= (x >> 1) & m1;             //put count of each 2 bits into those 2 bits
38
   x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
39
   x = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits
40
   return (int)((x * h01) >> 56);  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
41
}
42
#endif // Pierre-Marie Baty -- __builtin_popcountll support for MSVC 32-bit
43
 
44
#ifndef __builtin_ctzll // Pierre-Marie Baty -- __builtin_ctzll support for MSVC 32-bit
45
int __builtin_ctzll (unsigned long long x)
46
{
47
   // Returns the number of trailing 0-bits in x, starting at the least significant bit position.
48
   // If x is zero, the result is undefined.
49
   // This uses a binary search algorithm from Hacker's Delight.
50
   int n = 1;
51
   if ((x & 0x00000000FFFFFFFF) == 0) { n = n + 32; x = x >> 32; }
52
   if ((x & 0x000000000000FFFF) == 0) { n = n + 16; x = x >> 16; }
53
   if ((x & 0x00000000000000FF) == 0) { n = n + 8; x = x >> 8; }
54
   if ((x & 0x000000000000000F) == 0) { n = n + 4; x = x >> 4; }
55
   if ((x & 0x0000000000000003) == 0) { n = n + 2; x = x >> 2; }
56
   return (n - (x & 1));
57
}
58
#endif // Pierre-Marie Baty -- __builtin_ctzll support for MSVC 32-bit
59
 
60
#ifndef __builtin_clzll // Pierre-Marie Baty -- __builtin_clzll support for MSVC 32-bit
61
int __builtin_clzll (unsigned long long x)
62
{
63
   // Returns the number of leading 0-bits in x, starting at the most significant bit position.
64
   // If x is zero, the result is undefined.
65
   // This uses a binary search (counting down) algorithm from Hacker's Delight.
66
   unsigned long long y;
67
   int n = 64;
68
   y = x >> 32; if (y != 0) { n = n - 32; x = y; }
69
   y = x >> 16; if (y != 0) { n = n - 16; x = y; }
70
   y = x >> 8; if (y != 0) { n = n - 8; x = y; }
71
   y = x >> 4; if (y != 0) { n = n - 4; x = y; }
72
   y = x >> 2; if (y != 0) { n = n - 2; x = y; }
73
   y = x >> 1; if (y != 0) return (n - 2);
74
   return (n - (int) x);
75
}
76
#endif // Pierre-Marie Baty -- __builtin_clzll support for MSVC 32-bit
77
 
78
#define offset(sq1,sq2) ( ( (sq2)-(sq1) ) / distance(sq1,sq2) )
79
 
80
/**
81
 * Macros for internal use.
82
 */
83
#define HLANE(sq)    ( rank(sq) )
84
#define HLANEBIT(sq) ( FILE_H - file(sq) )
85
#define VLANE(sq)    ( file(sq) )
86
#define VLANEBIT(sq) ( RANK_8 - rank(sq) )
87
#define ULANE(sq)    ( file(sq) - rank(sq) + 7 )
88
#define ULANEBIT(sq) ( RANK_8 - rank(sq) )
89
#define DLANE(sq)    ( file(sq) + rank(sq) )
90
#define DLANEBIT(sq) ( rank(sq) )
91
#define HLANE_SQUARE(lane,bit) ( getSquare ( 7-(bit), (lane) ) )
92
#define VLANE_SQUARE(lane,bit) ( getSquare ( (lane), 7-(bit) ) )
93
#define ULANE_SQUARE(lane,bit) ( getSquare ( (lane)-(bit), 7-(bit) ) )
94
#define DLANE_SQUARE(lane,bit) ( getSquare ( (lane)-(bit), (bit) ) )
95
 
96
static bool isInitialized = FALSE;
97
 
98
UINT64 minValue[_64_];
99
UINT64 maxValue[_64_];
100
INT8 highestBit[0x10000];
101
INT8 lowestBit[0x10000];
102
INT8 numSetBits[0x10000];
103
UINT8 rankOverlay[0x10000];
104
UINT8 bitshiftGap[8][256];
105
int hLaneNumber[_64_], vLaneNumber[_64_];
106
int uLaneNumber[_64_], dLaneNumber[_64_];
107
 
108
Bitboard generalMoves[0x0f][_64_];
109
 
110
/* *INDENT-OFF* */
111
const Bitboard squaresOfFile[8] = {
112
   0x0101010101010101llu,
113
   0x0202020202020202llu,
114
   0x0404040404040404llu,
115
   0x0808080808080808llu,
116
   0x1010101010101010llu,
117
   0x2020202020202020llu,
118
   0x4040404040404040llu,
119
   0x8080808080808080llu
120
};
121
const Bitboard squaresOfRank[8] = {
122
   0x00000000000000ffllu,
123
   0x000000000000ff00llu,
124
   0x0000000000ff0000llu,
125
   0x00000000ff000000llu,
126
   0x000000ff00000000llu,
127
   0x0000ff0000000000llu,
128
   0x00ff000000000000llu,
129
   0xff00000000000000llu
130
};
131
const Bitboard squaresOfLateralFiles[8] = {
132
   0x0202020202020202llu,
133
   0x0505050505050505llu,
134
   0x0a0a0a0a0a0a0a0allu,
135
   0x1414141414141414llu,
136
   0x2828282828282828llu,
137
   0x5050505050505050llu,
138
   0xa0a0a0a0a0a0a0a0llu,
139
   0x4040404040404040llu
140
};
141
/* *INDENT-ON* */
142
 
143
Bitboard squaresOfFileRange[8][8];
144
Bitboard squaresOfRankRange[8][8];
145
Bitboard nonA, nonH, border, center, lightSquares, darkSquares, queenSide,
146
   kingSide, centerFiles, extendedCenter;
147
Bitboard squaresBehind[_64_][_64_];
148
Bitboard squaresBetween[_64_][_64_];
149
Bitboard squaresInDistance[8][_64_];
150
Bitboard squaresInTaxiDistance[15][_64_];
151
Bitboard squaresAbove[2][_64_];
152
Bitboard squaresBelow[2][_64_];
153
Bitboard squaresLeftOf[_64_];
154
Bitboard squaresRightOf[_64_];
155
Bitboard orthoKingAttackers[_64_];
156
Bitboard diaKingAttackers[_64_];
157
Bitboard knightKingAttackers[_64_];
158
Bitboard pawnKingAttackers[2][_64_];
159
 
160
SquareLaneInfo squareLaneInfo[_64_];
161
Bitboard hlane[_64_][256];
162
Bitboard vlane[_64_][256];
163
Bitboard ulane[_64_][256];
164
Bitboard dlane[_64_][256];
165
ObstacleSquareInfo obsi[_64_];
166
Bitboard pawnMoves[2][_64_][256];
167
Bitboard interestedPawns[2][_64_][256];
168
Bitboard castlings[2][16][256];
169
int castlingLane[] = { HLANE(E1), HLANE(E8) };
170
Bitboard promotionCandidates[2];
171
SetSquaresInfo setSquares[4][0x10000];
172
Bitboard preMaskRook[64], preMaskBishop[64];
173
Bitboard magicRookMoves[64][IMAX_ROOK];
174
Bitboard magicBishopMoves[64][IMAX_BISHOP];
175
MagicSquareInfoRook magicSquareInfoRook[64];
176
MagicSquareInfoBishop magicSquareInfoBishop[64];
177
 
178
/* *INDENT-OFF* */
179
const Bitboard magicRookNumber[64] = {
180
   2341871876025885824llu, 5908793080399659264llu,
181
   2814784401577026llu, 4755810071654563842llu,
182
   4683749110191751172llu, 648520571176420352llu,
183
   288793875996213508llu, 36039242390061312llu,
184
   2233855853176307712llu, 360296835543278592llu,
185
   37470368710784llu, 2261832991510528llu,
186
   74595267411776576llu, 4612831726723531008llu,
187
   17491104022660138llu, 9015996489662496llu,
188
   164381455144716288llu, 4785426803991552llu,
189
   2603080765009821794llu, 4504870937840771llu,
190
   73202185810346241llu, 2594073935322554944llu,
191
   577059170398781952llu, 687199551504llu,
192
   36029072970620928llu, 4755818807417635204llu,
193
   2305854279342097445llu, 4654506018003485187llu,
194
   1369095394823243808llu, 1650609881216llu,
195
   35189740863840llu, 17609634498592llu,
196
   17867407885440llu, 1307170084179935305llu,
197
   5224509820511455237llu, 30399366238175240llu,
198
   685674177139050632llu, 4504708001565696llu,
199
   576777574861506688llu, 2305843147759948801llu,
200
   36046664624070657llu, 2305862800624326656llu,
201
   35201686183936llu, 76563943050448912llu,
202
   4828140284174931982llu, 93630429790212llu,
203
   2305862800758624268llu, 4918212371161546978llu,
204
   1197987317416064llu, 4629700452154347536llu,
205
   144220742299427329llu, 1152928385211832832llu,
206
   40132191457288llu, 9354573578272llu,
207
   650209674406199320llu, 36029355649925192llu,
208
   3470081245843620386llu, 9208682512641llu,
209
   586664357648667141llu, 113161891886927874llu,
210
   19144700892151826llu, 594756909391937601llu,
211
   562958551810122llu, 1152922124158043138llu,
212
};
213
 
214
const Bitboard magicBishopNumber[64] = {
215
   2287018567549508llu, 20833559275112450llu,
216
   1157535125460746242llu, 2343279465658384466llu,
217
   182423557274534246llu, 91204498130747394llu,
218
   79165240377360llu, 18024053647361153llu,
219
   4756927389883318784llu, 2377974339296303121llu,
220
   1529092243969llu, 18016872700051744llu,
221
   1153204084472553600llu, 873698516757668385llu,
222
   1125942867148800llu, 26423192526848llu,
223
   289939073072784384llu, 10714208241454656llu,
224
   2306405960274414104llu, 54114131212519426llu,
225
   109212291534684230llu, 2306971108957557248llu,
226
   288239189760215296llu, 166643228131737628llu,
227
   3459894829004630016llu, 35193180131968llu,
228
   576478344523031040llu, 1134696069202368llu,
229
   298367873364066368llu, 2882596248975577091llu,
230
   432437927499531776llu, 72621163549300482llu,
231
   468396630660612192llu, 576812875222894592llu,
232
   3463272528741531664llu, 2612123106223325312llu,
233
   3242874314789487108llu, 3461016494560002066llu,
234
   4539883779662384llu, 5909074606504807464llu,
235
   4684333518172472324llu, 306280543752814656llu,
236
   2345387698176llu, 293016142258114592llu,
237
   5073215437209668llu, 79251277611040llu,
238
   602532708688384llu, 20310252071682068llu,
239
   4467607076866llu, 648573875995549696llu,
240
   288232580007339520llu, 1188986585695191042llu,
241
   9306611390751752llu, 5498105049088llu,
242
   4625205909830770716llu, 1152994261659095304llu,
243
   126118725618245632llu, 2305851875981395204llu,
244
   351843796394505llu, 40532672078233696llu,
245
   9009398294791225llu, 4611688257515749392llu,
246
   1152930369572702464llu, 2306989456245202960llu,
247
};
248
/* *INDENT-ON* */
249
 
250
bool testSquare(const Bitboard bitboard, const Square square)
251
{
252
   return (bool) (((bitboard) & minValue[(square)]) != EMPTY_BITBOARD);
253
}
254
 
255
/**
256
 * Get the king moves for the specified square.
257
 */
258
Bitboard getKingMoves(const Square square)
259
{
260
   return generalMoves[KING][square];
261
}
262
 
263
/**
264
 * Get castling moves depending from the castling rights and
265
 * the current position.
266
 */
267
Bitboard getCastlingMoves(const Color color, const BYTE castlingRights,
268
                          const Bitboard obstacles)
269
{
270
   if (color == WHITE)
271
   {
272
      return castlings[WHITE][castlingRights][obstacles & 0xFF];
273
   }
274
   else
275
   {
276
      return castlings[BLACK][castlingRights][obstacles >> 56];
277
   }
278
}
279
 
280
/**
281
 * Get the queen moves for the specified square.
282
 */
283
/*
284
 Bitboard getQueenMoves(const Square square, const BYTE * obstacles)
285
{
286
   const ObstacleSquareInfo *_obsi = &obsi[square];
287
 
288
   return _obsi->hLane[obstacles[_obsi->hLaneNumber]] |
289
      _obsi->vLane[obstacles[_obsi->vLaneNumber]] |
290
      _obsi->uLane[obstacles[_obsi->uLaneNumber]] |
291
      _obsi->dLane[obstacles[_obsi->dLaneNumber]];
292
}
293
*/
294
 
295
int getWidth(const Bitboard set)
296
{
297
   if (set == EMPTY_BITBOARD)
298
   {
299
      return 0;
300
   }
301
   else
302
   {
303
      File leftMost = FILE_A, rightMost = FILE_H;
304
 
305
      while ((set & squaresOfFile[leftMost]) == EMPTY_BITBOARD)
306
      {
307
         leftMost++;
308
      }
309
 
310
      while ((set & squaresOfFile[rightMost]) == EMPTY_BITBOARD)
311
      {
312
         rightMost--;
313
      }
314
 
315
      return rightMost - leftMost;
316
   }
317
}
318
 
319
/**
320
 * Get the queen moves for the specified square.
321
 */
322
Bitboard getMagicQueenMoves(const Square square, const Bitboard obstacles)
323
{
324
   MagicSquareInfoRook *msir = &magicSquareInfoRook[square];
325
   MagicSquareInfoBishop *msib = &magicSquareInfoBishop[square];
326
 
327
   return
328
      msir->moves[((obstacles & msir->preMask) * msir->magicNumber) >> 52] |
329
      msib->moves[((obstacles & msib->preMask) * msib->magicNumber) >> 55];
330
}
331
 
332
/**
333
 * Get the rook moves for the specified square.
334
 */
335
Bitboard getRookMoves(const Square square, const BYTE * obstacles)
336
{
337
   const ObstacleSquareInfo *_obsi = &obsi[square];
338
 
339
   return _obsi->hLane[obstacles[_obsi->hLaneNumber]] |
340
      _obsi->vLane[obstacles[_obsi->vLaneNumber]];
341
}
342
 
343
/**
344
 * Get the rook moves for the specified square.
345
 */
346
Bitboard getMagicRookMoves(const Square square, const Bitboard obstacles)
347
{
348
   MagicSquareInfoRook *msir = &magicSquareInfoRook[square];
349
 
350
   return
351
      msir->moves[((obstacles & msir->preMask) * msir->magicNumber) >> 52];
352
}
353
 
354
/**
355
 * Get the bishop moves for the specified square.
356
 */
357
Bitboard getBishopMoves(const Square square, const BYTE * obstacles)
358
{
359
   const ObstacleSquareInfo *_obsi = &obsi[square];
360
 
361
   return _obsi->uLane[obstacles[_obsi->uLaneNumber]] |
362
      _obsi->dLane[obstacles[_obsi->dLaneNumber]];
363
}
364
 
365
/**
366
 * Get the bishop moves for the specified square.
367
 */
368
Bitboard getMagicBishopMoves(const Square square, const Bitboard obstacles)
369
{
370
   MagicSquareInfoBishop *msib = &magicSquareInfoBishop[square];
371
 
372
   return
373
      msib->moves[((obstacles & msib->preMask) * msib->magicNumber) >> 55];
374
}
375
 
376
/**
377
 * Get the knight moves for the specified square.
378
 */
379
Bitboard getKnightMoves(const Square square)
380
{
381
   return generalMoves[KNIGHT][square];
382
}
383
 
384
/**
385
 * Get the pawn captures for the specified square.
386
 */
387
Bitboard getPawnCaptures(const Piece piece, const Square square,
388
                         const Bitboard allPieces)
389
{
390
   return generalMoves[piece][square] & allPieces;
391
}
392
 
393
/**
394
 * Get the pawn advances for the specified square.
395
 */
396
Bitboard getPawnAdvances(const Color color, const Square square,
397
                         const Bitboard obstacles)
398
{
399
   Bitboard advances;
400
 
401
   if (color == WHITE)
402
   {
403
      advances = (minValue[square] << 8) & ~obstacles;
404
 
405
      if (rank(square) == RANK_2)
406
      {
407
         advances |= (advances << 8) & ~obstacles;
408
      }
409
   }
410
   else
411
   {
412
      advances = (minValue[square] >> 8) & ~obstacles;
413
 
414
      if (rank(square) == RANK_7)
415
      {
416
         advances |= (advances >> 8) & ~obstacles;
417
      }
418
   }
419
 
420
   return advances;
421
}
422
 
423
/**
424
 * Get the pawns interested in advancing to the specified square.
425
 */
426
Bitboard getInterestedPawns(const Color color, const Square square,
427
                            const Bitboard obstacles)
428
{
429
   Bitboard interestedPawns;
430
 
431
   if (color == WHITE)
432
   {
433
      interestedPawns = minValue[square] >> 8;
434
 
435
      if (rank(square) == RANK_4 &&
436
          (interestedPawns & obstacles) == EMPTY_BITBOARD)
437
      {
438
         interestedPawns |= minValue[square] >> 16;
439
      }
440
   }
441
   else
442
   {
443
      interestedPawns = minValue[square] << 8;
444
 
445
      if (rank(square) == RANK_5 &&
446
          (interestedPawns & obstacles) == EMPTY_BITBOARD)
447
      {
448
         interestedPawns |= minValue[square] << 16;
449
      }
450
   }
451
 
452
   return interestedPawns;
453
}
454
 
455
/**
456
 * Get the squares between the two specified squares.
457
 */
458
Bitboard getSquaresBetween(const Square square1, const Square square2)
459
{
460
   return squaresBetween[square1][square2];
461
}
462
 
463
/**
464
 * Get the squares behind 'target', as seen from 'viewpoint'.
465
 */
466
Bitboard getSquaresBehind(const Square target, const Square viewpoint)
467
{
468
   return squaresBehind[target][viewpoint];
469
}
470
 
471
/**
472
 * Shift all set squares one file to the left.
473
 */
474
Bitboard shiftLeft(const Bitboard bitboard)
475
{
476
   return (bitboard & nonA) >> 1;
477
}
478
 
479
/**
480
 * Shift all set squares one file to the right.
481
 */
482
Bitboard shiftRight(const Bitboard bitboard)
483
{
484
   return (bitboard & nonH) << 1;
485
}
486
 
487
/**
488
 * Get all squares lateral to the specified squares.
489
 */
490
Bitboard getLateralSquares(const Bitboard squares)
491
{
492
   return ((squares & nonA) >> 1) | ((squares & nonH) << 1);
493
}
494
 
495
/**
496
 * Get the squares of the specified file.
497
 */
498
Bitboard getSquaresOfFile(const File file)
499
{
500
   return squaresOfFile[file];
501
}
502
 
503
/**
504
 * Get the squares of the specified rank.
505
 */
506
Bitboard getSquaresOfRank(const Rank rank)
507
{
508
   return squaresOfRank[rank];
509
}
510
 
511
/**
512
 * Get the number of set squares in the specified bitboard.
513
 */
514
int getNumberOfSetSquares(const Bitboard bitboard)
515
{
516
   return __builtin_popcountll(bitboard);
517
}
518
 
519
/**
520
 * Get the rank overlay of the specified bitboard.
521
 */
522
int getRankOverlay(const Bitboard bitboard)
523
{
524
   return rankOverlay[(bitboard) & UHEX_FFFF] |
525
      rankOverlay[(bitboard >> 16) & UHEX_FFFF] |
526
      rankOverlay[(bitboard >> 32) & UHEX_FFFF] |
527
      rankOverlay[(bitboard >> 48) & UHEX_FFFF];
528
}
529
 
530
/**
531
 * Get the moves of the the specified piece.
532
 */
533
Bitboard getMoves(Square square, Piece piece, Bitboard allPieces)
534
{
535
   switch (pieceType(piece))
536
   {
537
   case PAWN:
538
      return getPawnCaptures(piece, square, allPieces) |
539
         getPawnAdvances(pieceColor(piece), square, allPieces);
540
   case KING:
541
      return getKingMoves(square);
542
   case KNIGHT:
543
      return getKnightMoves(square);
544
   case ROOK:
545
      return getMagicRookMoves(square, allPieces);
546
   case BISHOP:
547
      return getMagicBishopMoves(square, allPieces);
548
   default:
549
      return getMagicQueenMoves(square, allPieces);
550
   }
551
}
552
 
553
/**
554
 * Get the capture moves of the the specified piece.
555
 */
556
Bitboard getCaptureMoves(Square square, Piece piece, Bitboard allPieces)
557
{
558
   switch (pieceType(piece))
559
   {
560
   case PAWN:
561
      return getPawnCaptures(piece, square, allPieces);
562
   case KING:
563
      return getKingMoves(square);
564
   case KNIGHT:
565
      return getKnightMoves(square);
566
   case ROOK:
567
      return getMagicRookMoves(square, allPieces);
568
   case BISHOP:
569
      return getMagicBishopMoves(square, allPieces);
570
   default:
571
      return getMagicQueenMoves(square, allPieces);
572
   }
573
}
574
 
575
/**
576
 * Set a square in the specified vector of obstacles.
577
 */
578
void setObstacleSquare(Square square, BYTE obstacles[NUM_LANES])
579
{
580
   SquareLaneInfo *sqi = &squareLaneInfo[square];
581
 
582
   obstacles[sqi->hLane] |= sqi->hLaneSetMask;
583
   obstacles[sqi->vLane] |= sqi->vLaneSetMask;
584
   obstacles[sqi->uLane] |= sqi->uLaneSetMask;
585
   obstacles[sqi->dLane] |= sqi->dLaneSetMask;
586
}
587
 
588
/**
589
 * Clear a square in the specified vector of obstacles.
590
 */
591
void clearObstacleSquare(Square square, BYTE obstacles[NUM_LANES])
592
{
593
   SquareLaneInfo *sqi = &squareLaneInfo[square];
594
 
595
   obstacles[sqi->hLane] &= sqi->hLaneClearMask;
596
   obstacles[sqi->vLane] &= sqi->vLaneClearMask;
597
   obstacles[sqi->uLane] &= sqi->uLaneClearMask;
598
   obstacles[sqi->dLane] &= sqi->dLaneClearMask;
599
}
600
 
601
/**
602
 * Calculate all obstacles according to the specified bitboard.
603
 */
604
void calculateObstacles(Bitboard board, BYTE obstacles[NUM_LANES])
605
{
606
   Square square;
607
 
608
   memset(obstacles, 0x00, NUM_LANES);
609
 
610
   ITERATE(square)
611
   {
612
      if (board & minValue[square])
613
      {
614
         setObstacleSquare(square, obstacles);
615
      }
616
   }
617
}
618
 
619
/**
620
 * Get the number of a set square and clear the corresponding bit.
621
 *
622
 * @return NO_SQUARE if no square was set.
623
 */
624
Square getLastSquare(Bitboard * vector);
625
 
626
/**
627
 * Extend all set bits by one square into all directions.
628
 */
629
void floodBoard(Bitboard * board);
630
 
631
/**
632
 * Get the targets of all pawns specified by 'whitePawns'.
633
 */
634
Bitboard getWhitePawnTargets(const Bitboard whitePawns)
635
{
636
   return ((whitePawns & nonA) << 7) | ((whitePawns & nonH) << 9);
637
}
638
 
639
/**
640
 * Get the targets of all pawns specified by 'blackPawns'.
641
 */
642
Bitboard getBlackPawnTargets(const Bitboard blackPawns)
643
{
644
   return ((blackPawns & nonA) >> 9) | ((blackPawns & nonH) >> 7);
645
}
646
 
647
/**
648
 * Iteration shortcuts
649
 */
650
#define ITERATE_BITBOARD(b,sq) while ( ( sq = getLastSquare(b) ) >= 0 )
651
 
652
void floodBoard(Bitboard * board)
653
{
654
   const Bitboard toLeft = *board & nonA, toRight = *board & nonH;
655
 
656
   *board = (toLeft >> 1) | (toLeft << 7) | (*board >> 8) | (toLeft >> 9) |
657
      (toRight << 1) | (toRight >> 7) | (*board << 8) | (toRight << 9);
658
}
659
 
660
Square getLastSquare(Bitboard * vector)
661
{
662
   if (*vector == EMPTY_BITBOARD)
663
   {
664
      return NO_SQUARE;
665
   }
666
   else
667
   {
668
      const int index = 63 - __builtin_clzll(*vector);
669
 
670
      *vector &= maxValue[index];
671
 
672
      return index;
673
   }
674
}
675
 
676
Square getFirstSquare(Bitboard * vector)
677
{
678
   if (*vector == EMPTY_BITBOARD)
679
   {
680
      return NO_SQUARE;
681
   }
682
   else
683
   {
684
      const int index = __builtin_ctzll(*vector);
685
 
686
      *vector &= maxValue[index];
687
 
688
      return index;
689
   }
690
}
691
 
692
int getSetSquares(const Bitboard board, UINT8 squares[_64_])
693
{
694
   int index;
695
   UINT8 *currentSquare = &squares[0];
696
 
697
   if ((index = (int) (0xFFFF & board)) != 0)
698
   {
699
      const SetSquaresInfo *info = &setSquares[0][index];
700
 
701
      memcpy(currentSquare, info->setSquares, info->numSetSquares);
702
      currentSquare += info->numSetSquares;
703
   }
704
 
705
   if ((index = (int) (0xFFFF & (board >> 16))) != 0)
706
   {
707
      const SetSquaresInfo *info = &setSquares[1][index];
708
 
709
      memcpy(currentSquare, info->setSquares, info->numSetSquares);
710
      currentSquare += info->numSetSquares;
711
   }
712
 
713
   if ((index = (int) (0xFFFF & (board >> 32))) != 0)
714
   {
715
      const SetSquaresInfo *info = &setSquares[2][index];
716
 
717
      memcpy(currentSquare, info->setSquares, info->numSetSquares);
718
      currentSquare += info->numSetSquares;
719
   }
720
 
721
   if ((index = (int) (board >> 48)) != 0)
722
   {
723
      const SetSquaresInfo *info = &setSquares[3][index];
724
 
725
      memcpy(currentSquare, info->setSquares, info->numSetSquares);
726
      currentSquare += info->numSetSquares;
727
   }
728
 
729
   return (int) (currentSquare - &squares[0]);
730
}
731
 
732
Bitboard getMultipleSquaresBetween(const Square origin, Bitboard targets)
733
{
734
   Bitboard squares = targets;
735
   Square targetSquare;
736
   Bitboard *sqb = &(squaresBetween[origin][0]);
737
 
738
   ITERATE_BITBOARD(&targets, targetSquare)
739
   {
740
      squares |= sqb[targetSquare];
741
   }
742
 
743
   return squares;
744
}
745
 
746
int getFloodValue(const Square origin, const Bitboard targets,
747
                  const Bitboard permittedSquares)
748
{
749
   Bitboard floodedSquares = getKingMoves(origin) & permittedSquares;
750
   Bitboard oldFloodedSquares = minValue[origin];
751
   int numSteps = 1;
752
 
753
   while ((targets & floodedSquares) == EMPTY_BITBOARD &&
754
          floodedSquares != oldFloodedSquares)
755
   {
756
      oldFloodedSquares = floodedSquares;
757
      floodBoard(&floodedSquares);
758
      floodedSquares |= oldFloodedSquares;
759
      floodedSquares &= permittedSquares;
760
      numSteps++;
761
   }
762
 
763
   return numSteps;
764
}
765
 
766
static void initializeKingMoves()
767
{
768
   int offset[] = { 1, -1, 7, -7, 8, -8, 9, -9 }, direction;
769
   Square square;
770
 
771
   ITERATE(square)
772
   {
773
      for (direction = 0; direction < 8; direction++)
774
      {
775
         Square target = (Square) (square + offset[direction]);
776
 
777
         if (squareIsValid(target) && distance(square, target) == 1)
778
         {
779
            generalMoves[KING][square] |= minValue[target];
780
         }
781
      }
782
   }
783
}
784
 
785
static void initializeRookMoves()
786
{
787
   int offset[] = { 1, -1, 8, -8 }, direction, moveLength;
788
   Square square;
789
 
790
   ITERATE(square)
791
   {
792
      for (direction = 0; direction < 4; direction++)
793
      {
794
         for (moveLength = 1; moveLength <= 7; moveLength++)
795
         {
796
            Square target =
797
               (Square) (square + offset[direction] * moveLength);
798
            bool sameFile = (bool) (file(square) == file(target));
799
            bool sameRow = (bool) (rank(square) == rank(target));
800
 
801
            if (squareIsValid(target) && (sameFile || sameRow))
802
            {
803
               generalMoves[ROOK][square] |= minValue[target];
804
            }
805
            else
806
            {
807
               break;
808
            }
809
         }
810
      }
811
   }
812
}
813
 
814
static void initializeBishopMoves()
815
{
816
   int offset[] = { 7, -7, 9, -9 }, direction, moveLength;
817
   Square square;
818
 
819
   ITERATE(square)
820
   {
821
      for (direction = 0; direction < 4; direction++)
822
      {
823
         for (moveLength = 1; moveLength <= 7; moveLength++)
824
         {
825
            Square target =
826
               (Square) (square + offset[direction] * moveLength);
827
            int hDistance = horizontalDistance(square, target);
828
            int vDistance = verticalDistance(square, target);
829
 
830
            if (squareIsValid(target) && hDistance == vDistance)
831
            {
832
               generalMoves[BISHOP][square] |= minValue[target];
833
            }
834
            else
835
            {
836
               break;
837
            }
838
         }
839
      }
840
   }
841
}
842
 
843
static void initializeQueenMoves()
844
{
845
   Square square;
846
 
847
   ITERATE(square)
848
   {
849
      generalMoves[QUEEN][square] =
850
         generalMoves[ROOK][square] | generalMoves[BISHOP][square];
851
   }
852
}
853
 
854
static void initializeKnightMoves()
855
{
856
   int offset[] = { 6, -6, 10, -10, 15, -15, 17, -17 }, direction;
857
   Square square;
858
 
859
   ITERATE(square)
860
   {
861
      for (direction = 0; direction < 8; direction++)
862
      {
863
         Square target = (Square) (square + offset[direction]);
864
 
865
         if (squareIsValid(target) && distance(square, target) <= 2)
866
         {
867
            generalMoves[KNIGHT][square] |= minValue[target];
868
         }
869
      }
870
   }
871
}
872
 
873
static void initializePawnMoves()
874
{
875
   Square square;
876
 
877
   ITERATE(square)
878
   {
879
      if (file(square) != FILE_A)
880
      {
881
         if (square <= H8 - 7)
882
         {
883
            generalMoves[WHITE_PAWN][square] |= minValue[square + 7];
884
         }
885
 
886
         if (square >= A1 + 9)
887
         {
888
            generalMoves[BLACK_PAWN][square] |= minValue[square - 9];
889
         }
890
      }
891
 
892
      if (file(square) != FILE_H)
893
      {
894
         if (square <= H8 - 9)
895
         {
896
            generalMoves[WHITE_PAWN][square] |= minValue[square + 9];
897
         }
898
 
899
         if (square >= A1 + 7)
900
         {
901
            generalMoves[BLACK_PAWN][square] |= minValue[square - 7];
902
         }
903
      }
904
   }
905
}
906
 
907
static Bitboard calculateSquaresBehind(Square square, int offset)
908
{
909
   Bitboard squares = EMPTY_BITBOARD;
910
 
911
   for (square = (Square) (square + offset);
912
        squareIsValid(square) &&
913
        distance(square, (Square) (square - offset)) == 1;
914
        square = (Square) (square + offset))
915
   {
916
      Bitboard mv = minValue[square];
917
 
918
      squares |= mv;
919
   }
920
 
921
   return squares;
922
}
923
 
924
static void initializeSquaresBehind()
925
{
926
   Square sq1, sq2;
927
 
928
   ITERATE(sq1)
929
   {
930
      Bitboard squares = generalMoves[QUEEN][sq1];
931
 
932
      ITERATE_BITBOARD(&squares, sq2)
933
      {
934
         int offset = offset(sq1, sq2);
935
 
936
         squaresBehind[sq2][sq1] = calculateSquaresBehind(sq2, offset);
937
      }
938
   }
939
}
940
 
941
static Bitboard calculateSquaresBetween(Square sq1, Square sq2)
942
{
943
   Bitboard squares = EMPTY_BITBOARD;
944
   int _offset = offset(sq1, sq2), square;
945
 
946
   for (square = sq1 + _offset; square != sq2; square += _offset)
947
   {
948
      squares |= minValue[square];
949
   }
950
 
951
   return squares;
952
}
953
 
954
static void initializeSquaresBetween()
955
{
956
   Square sq1, sq2;
957
 
958
   ITERATE(sq1)
959
   {
960
      Bitboard squares = generalMoves[QUEEN][sq1];
961
 
962
      ITERATE_BITBOARD(&squares, sq2)
963
      {
964
         squaresBetween[sq1][sq2] = calculateSquaresBetween(sq1, sq2);
965
      }
966
   }
967
}
968
 
969
static void initializeSquareLaneInfo()
970
{
971
   Square square;
972
 
973
   ITERATE(square)
974
   {
975
      SquareLaneInfo *sqi = &squareLaneInfo[square];
976
 
977
      sqi->hLane = hLaneNumber[square] = HLANE(square);
978
      sqi->hLaneSetMask = (BYTE) minValue[HLANEBIT(square)];
979
      sqi->hLaneClearMask = (BYTE) ~ sqi->hLaneSetMask;
980
 
981
      sqi->vLane = vLaneNumber[square] = VLANE(square) + 8;
982
      sqi->vLaneSetMask = (BYTE) minValue[VLANEBIT(square)];
983
      sqi->vLaneClearMask = (BYTE) ~ sqi->vLaneSetMask;
984
 
985
      sqi->uLane = uLaneNumber[square] = ULANE(square) + 16;
986
      sqi->uLaneSetMask = (BYTE) minValue[ULANEBIT(square)];
987
      sqi->uLaneClearMask = (BYTE) ~ sqi->uLaneSetMask;
988
 
989
      sqi->dLane = dLaneNumber[square] = DLANE(square) + 31;
990
      sqi->dLaneSetMask = (BYTE) minValue[DLANEBIT(square)];
991
      sqi->dLaneClearMask = (BYTE) ~ sqi->dLaneSetMask;
992
   }
993
}
994
 
995
static Bitboard getHlaneVector(int lane, BYTE mask)
996
{
997
   int i;
998
   Bitboard v = EMPTY_BITBOARD;
999
 
1000
   for (i = 0; i < 8; i++)
1001
   {
1002
      if (mask & minValue[i])
1003
      {
1004
         v |= minValue[7 - i];
1005
      }
1006
   }
1007
 
1008
   v <<= 8 * lane;
1009
 
1010
   return v;
1011
}
1012
 
1013
static Bitboard getVlaneVector(int lane, BYTE mask)
1014
{
1015
   int i;
1016
   Bitboard v = EMPTY_BITBOARD;
1017
 
1018
   for (i = 0; i < 8; i++)
1019
   {
1020
      if (mask & minValue[i])
1021
      {
1022
         v |= minValue[8 * (7 - i)];
1023
      }
1024
   }
1025
 
1026
   v <<= lane;
1027
 
1028
   return v;
1029
}
1030
 
1031
static Bitboard getUlaneVector(int lane, BYTE mask)
1032
{
1033
   int i;
1034
   Bitboard v = EMPTY_BITBOARD;
1035
 
1036
   for (i = 0; i < 8; i++)
1037
   {
1038
      v <<= 8;
1039
 
1040
      if (mask & minValue[i])
1041
      {
1042
         v |= minValue[7 - i];
1043
      }
1044
   }
1045
 
1046
   if (lane < 7)
1047
   {
1048
      for (i = lane; i < 7; i++)
1049
      {
1050
         v = (v & nonA) >> 1;
1051
      }
1052
   }
1053
   else
1054
   {
1055
      for (i = lane; i > 7; i--)
1056
      {
1057
         v = (v & nonH) << 1;
1058
      }
1059
   }
1060
 
1061
   return v;
1062
}
1063
 
1064
static Bitboard getDlaneVector(int lane, BYTE mask)
1065
{
1066
   int i;
1067
   Bitboard v = EMPTY_BITBOARD;
1068
 
1069
   for (i = 0; i < 8; i++)
1070
   {
1071
      v <<= 8;
1072
 
1073
      if (mask & minValue[7 - i])
1074
      {
1075
         v |= minValue[i];
1076
      }
1077
   }
1078
 
1079
   if (lane < 7)
1080
   {
1081
      for (i = lane; i < 7; i++)
1082
      {
1083
         v = (v & nonA) >> 1;
1084
      }
1085
   }
1086
   else
1087
   {
1088
      for (i = lane; i > 7; i--)
1089
      {
1090
         v = (v & nonH) << 1;
1091
      }
1092
   }
1093
 
1094
   return v;
1095
}
1096
 
1097
static Bitboard getLaneMask(Square square, int offset,
1098
                            Bitboard legalSquares, Bitboard obstacles)
1099
{
1100
   Bitboard laneMask = EMPTY_BITBOARD, mv = EMPTY_BITBOARD;
1101
 
1102
   while ((square = (Square) (square + offset)) >= A1 &&
1103
          square <= H8 && ((mv = minValue[square]) & legalSquares))
1104
   {
1105
      laneMask |= mv;
1106
 
1107
      if (mv & obstacles)
1108
      {
1109
         break;
1110
      }
1111
   }
1112
 
1113
   return laneMask;
1114
}
1115
 
1116
static Bitboard getHLaneMask(Square square, BYTE mask)
1117
{
1118
   int lane = HLANE(square);
1119
   Bitboard legalSquares = getHlaneVector(lane, 255);
1120
   Bitboard obstacles = getHlaneVector(lane, mask);
1121
 
1122
   Bitboard laneMask = getLaneMask(square, 1, legalSquares, obstacles);
1123
 
1124
   laneMask |= getLaneMask(square, -1, legalSquares, obstacles);
1125
 
1126
   return laneMask;
1127
}
1128
 
1129
static Bitboard getVLaneMask(Square square, BYTE mask)
1130
{
1131
   int lane = VLANE(square);
1132
   Bitboard legalSquares = getVlaneVector(lane, 255);
1133
   Bitboard obstacles = getVlaneVector(lane, mask);
1134
 
1135
   Bitboard laneMask = getLaneMask(square, 8, legalSquares, obstacles);
1136
 
1137
   laneMask |= getLaneMask(square, -8, legalSquares, obstacles);
1138
 
1139
   return laneMask;
1140
}
1141
 
1142
static Bitboard getULaneMask(Square square, BYTE mask)
1143
{
1144
   int lane = ULANE(square);
1145
   Bitboard legalSquares = getUlaneVector(lane, 255);
1146
   Bitboard obstacles = getUlaneVector(lane, mask);
1147
 
1148
   Bitboard laneMask = getLaneMask(square, 9, legalSquares, obstacles);
1149
 
1150
   laneMask |= getLaneMask(square, -9, legalSquares, obstacles);
1151
 
1152
   return laneMask;
1153
}
1154
 
1155
static Bitboard getDLaneMask(Square square, BYTE mask)
1156
{
1157
   int lane = DLANE(square);
1158
   Bitboard legalSquares = getDlaneVector(lane, 255);
1159
   Bitboard obstacles = getDlaneVector(lane, mask);
1160
 
1161
   Bitboard laneMask = getLaneMask(square, 7, legalSquares, obstacles);
1162
 
1163
   laneMask |= getLaneMask(square, -7, legalSquares, obstacles);
1164
 
1165
   return laneMask;
1166
}
1167
 
1168
static Bitboard getWhitePawnMoves(Square square, BYTE laneMask)
1169
{
1170
   int lane = VLANE(square);
1171
   Bitboard moves = EMPTY_BITBOARD, board = getVlaneVector(lane, laneMask);
1172
 
1173
   if (square >= A2 && square <= H7 && (board & minValue[square + 8]) == 0)
1174
   {
1175
      moves |= minValue[square + 8];
1176
 
1177
      if (square <= H2 && (board & minValue[square + 16]) == 0)
1178
      {
1179
         moves |= minValue[square + 16];
1180
      }
1181
   }
1182
 
1183
   return moves;
1184
}
1185
 
1186
static Bitboard getInterestedWhitePawns(Square square, BYTE laneMask)
1187
{
1188
   int lane = VLANE(square);
1189
   Bitboard pawns = EMPTY_BITBOARD, board = getVlaneVector(lane, laneMask);
1190
 
1191
   if (square >= A3 && square <= H8 && (board & minValue[square]) == 0)
1192
   {
1193
      pawns |= minValue[square - 8];
1194
 
1195
      if (rank(square) == RANK_4 && (board & minValue[square - 8]) == 0)
1196
      {
1197
         pawns |= minValue[square - 16];
1198
      }
1199
   }
1200
 
1201
   return pawns;
1202
}
1203
 
1204
static Bitboard getBlackPawnMoves(Square square, BYTE laneMask)
1205
{
1206
   int lane = VLANE(square);
1207
   Bitboard moves = EMPTY_BITBOARD, board = getVlaneVector(lane, laneMask);
1208
 
1209
   if (square >= A2 && square <= H7 && (board & minValue[square - 8]) == 0)
1210
   {
1211
      moves |= minValue[square - 8];
1212
 
1213
      if (square >= A7 && (board & minValue[square - 16]) == 0)
1214
      {
1215
         moves |= minValue[square - 16];
1216
      }
1217
   }
1218
 
1219
   return moves;
1220
}
1221
 
1222
static Bitboard getInterestedBlackPawns(Square square, BYTE laneMask)
1223
{
1224
   int lane = VLANE(square);
1225
   Bitboard pawns = EMPTY_BITBOARD, board = getVlaneVector(lane, laneMask);
1226
 
1227
   if (square >= A1 && square <= H6 && (board & minValue[square]) == 0)
1228
   {
1229
      pawns |= minValue[square + 8];
1230
 
1231
      if (rank(square) == RANK_5 && (board & minValue[square + 8]) == 0)
1232
      {
1233
         pawns |= minValue[square + 16];
1234
      }
1235
   }
1236
 
1237
   return pawns;
1238
}
1239
 
1240
static void initializeLaneMasks()
1241
{
1242
   Square square;
1243
   int i;
1244
 
1245
   ITERATE(square)
1246
   {
1247
      for (i = 0; i <= 255; i++)
1248
      {
1249
         BYTE mask = (BYTE) i;
1250
 
1251
         hlane[square][i] = getHLaneMask(square, mask);
1252
         vlane[square][i] = getVLaneMask(square, mask);
1253
         ulane[square][i] = getULaneMask(square, mask);
1254
         dlane[square][i] = getDLaneMask(square, mask);
1255
         pawnMoves[WHITE][square][i] = getWhitePawnMoves(square, mask);
1256
         pawnMoves[BLACK][square][i] = getBlackPawnMoves(square, mask);
1257
         interestedPawns[WHITE][square][i] =
1258
            getInterestedWhitePawns(square, mask);
1259
         interestedPawns[BLACK][square][i] =
1260
            getInterestedBlackPawns(square, mask);
1261
      }
1262
   }
1263
 
1264
   ITERATE(square)
1265
   {
1266
      int i;
1267
 
1268
      obsi[square].hLaneNumber = hLaneNumber[square];
1269
      obsi[square].vLaneNumber = vLaneNumber[square];
1270
      obsi[square].uLaneNumber = uLaneNumber[square];
1271
      obsi[square].dLaneNumber = dLaneNumber[square];
1272
 
1273
      for (i = 0; i < 256; i++)
1274
      {
1275
         obsi[square].hLane[i] = hlane[square][i];
1276
         obsi[square].vLane[i] = vlane[square][i];
1277
         obsi[square].uLane[i] = ulane[square][i];
1278
         obsi[square].dLane[i] = dlane[square][i];
1279
      }
1280
   }
1281
}
1282
 
1283
static Bitboard getCastlings(const Bitboard obstacles)
1284
{
1285
   Bitboard castlings = EMPTY_BITBOARD;
1286
 
1287
   if ((obstacles & minValue[F1]) == EMPTY_BITBOARD &&
1288
       (obstacles & minValue[G1]) == EMPTY_BITBOARD)
1289
   {
1290
      castlings |= minValue[G1];
1291
   }
1292
 
1293
   if ((obstacles & minValue[B1]) == EMPTY_BITBOARD &&
1294
       (obstacles & minValue[C1]) == EMPTY_BITBOARD &&
1295
       (obstacles & minValue[D1]) == EMPTY_BITBOARD)
1296
   {
1297
      castlings |= minValue[C1];
1298
   }
1299
 
1300
   return castlings;
1301
}
1302
 
1303
static void initializeCastlings()
1304
{
1305
   int i, c;
1306
 
1307
   for (i = 0; i <= 255; i++)
1308
   {
1309
      BYTE mask = (BYTE) i;
1310
      Bitboard moves = getCastlings((Bitboard) mask);
1311
 
1312
      for (c = 0; c <= 15; c++)
1313
      {
1314
         castlings[WHITE][c][mask] = castlings[BLACK][c][mask] = 0;
1315
 
1316
         if (moves & minValue[G1])
1317
         {
1318
            if (c & WHITE_00)
1319
            {
1320
               castlings[WHITE][c][mask] |= minValue[G1];
1321
            }
1322
 
1323
            if (c & BLACK_00)
1324
            {
1325
               castlings[BLACK][c][mask] |= minValue[G8];
1326
            }
1327
         }
1328
 
1329
         if (moves & minValue[C1])
1330
         {
1331
            if (c & WHITE_000)
1332
            {
1333
               castlings[WHITE][c][mask] |= minValue[C1];
1334
            }
1335
 
1336
            if (c & BLACK_000)
1337
            {
1338
               castlings[BLACK][c][mask] |= minValue[C8];
1339
            }
1340
         }
1341
      }
1342
   }
1343
}
1344
 
1345
static INT8 _getNumberOfSetBits(INT32 v)
1346
{
1347
   int count = 0, i;
1348
 
1349
   for (i = 0; i < 16; i++)
1350
   {
1351
      count += (v >> i) & 1;
1352
   }
1353
 
1354
   return (INT8) count;
1355
}
1356
 
1357
static UINT8 _getRankOverlay(INT32 v)
1358
{
1359
   return (UINT8) ((v & 0xff) | ((v >> 8) & 0xff));
1360
}
1361
 
1362
unsigned int getMinimumDistance(const Bitboard targets, const Square square)
1363
{
1364
   unsigned int distance;
1365
 
1366
   for (distance = 1; distance <= 7; distance++)
1367
   {
1368
      if ((squaresInDistance[distance][square] & targets) != EMPTY_BITBOARD)
1369
      {
1370
         return distance;
1371
      }
1372
   }
1373
 
1374
   return 0;
1375
}
1376
 
1377
unsigned int getMaximumDistance(const Bitboard targets, const Square square)
1378
{
1379
   unsigned int distance;
1380
 
1381
   for (distance = 7; distance > 0; distance--)
1382
   {
1383
      if ((squaresInDistance[distance][square] & targets) != EMPTY_BITBOARD)
1384
      {
1385
         return distance;
1386
      }
1387
   }
1388
 
1389
   return 0;
1390
}
1391
 
1392
static Bitboard getPremaskExclusions(const Square square)
1393
{
1394
   if (testSquare(border, square))
1395
   {
1396
      Bitboard exclusions = EMPTY_BITBOARD;
1397
 
1398
      if (testSquare(squaresOfFile[FILE_A], square) == FALSE)
1399
      {
1400
         exclusions |= squaresOfFile[FILE_A];
1401
      }
1402
 
1403
      if (testSquare(squaresOfFile[FILE_H], square) == FALSE)
1404
      {
1405
         exclusions |= squaresOfFile[FILE_H];
1406
      }
1407
 
1408
      if (testSquare(squaresOfRank[RANK_1], square) == FALSE)
1409
      {
1410
         exclusions |= squaresOfRank[RANK_1];
1411
      }
1412
 
1413
      if (testSquare(squaresOfRank[RANK_8], square) == FALSE)
1414
      {
1415
         exclusions |= squaresOfRank[RANK_8];
1416
      }
1417
 
1418
      return exclusions;
1419
   }
1420
   else
1421
   {
1422
      return border;
1423
   }
1424
}
1425
 
1426
static void initializePremasks()
1427
{
1428
   Square square;
1429
 
1430
   ITERATE(square)
1431
   {
1432
      preMaskRook[square] = generalMoves[WHITE_ROOK][square] &
1433
         ~getPremaskExclusions(square);
1434
      preMaskBishop[square] = generalMoves[WHITE_BISHOP][square] &
1435
         ~getPremaskExclusions(square);
1436
   }
1437
}
1438
 
1439
static void initializeMagicRookMoves(const Square square)
1440
{
1441
   Square squareOfIndex[12];
1442
   Bitboard allMoves = preMaskRook[square];
1443
   const Bitboard premask = preMaskRook[square];
1444
   int i, pieceSetup;
1445
   Square sq1;
1446
   BYTE obstacles[NUM_LANES];
1447
   const Bitboard magicNumber = magicRookNumber[square];
1448
 
1449
   for (i = 0; i < IMAX_ROOK; i++)
1450
   {
1451
      magicRookMoves[square][i] = EMPTY_BITBOARD;
1452
   }
1453
 
1454
   for (i = 0; i < 12; i++)
1455
   {
1456
      squareOfIndex[i] = NO_SQUARE;
1457
   }
1458
 
1459
   i = 0;
1460
 
1461
   ITERATE_BITBOARD(&allMoves, sq1)
1462
   {
1463
      assert(i < 12);
1464
 
1465
      squareOfIndex[i++] = sq1;
1466
   }
1467
 
1468
   for (pieceSetup = 0; pieceSetup < 4096; pieceSetup++)
1469
   {
1470
      Bitboard currentSetup = EMPTY_BITBOARD, effectiveMoves;
1471
      int j = 1;
1472
      Bitboard magicIndex;
1473
 
1474
      for (i = 0; i < 12 && squareOfIndex[i] != NO_SQUARE; i++)
1475
      {
1476
         if ((pieceSetup & j) != 0)
1477
         {
1478
            setSquare(currentSetup, squareOfIndex[i]);
1479
         }
1480
 
1481
         j *= 2;
1482
      }
1483
 
1484
      calculateObstacles(currentSetup, obstacles);
1485
      effectiveMoves = getRookMoves(square, obstacles);
1486
      magicIndex = ((currentSetup & premask) * magicNumber) >> 52;
1487
      magicRookMoves[square][magicIndex] = effectiveMoves;
1488
   }
1489
}
1490
 
1491
static void initializeMagicBishopMoves(const Square square)
1492
{
1493
   Square squareOfIndex[12];
1494
   Bitboard allMoves = preMaskBishop[square];
1495
   const Bitboard premask = preMaskBishop[square];
1496
   int i, pieceSetup;
1497
   Square sq1;
1498
   BYTE obstacles[NUM_LANES];
1499
   const Bitboard magicNumber = magicBishopNumber[square];
1500
 
1501
   for (i = 0; i < IMAX_BISHOP; i++)
1502
   {
1503
      magicBishopMoves[square][i] = EMPTY_BITBOARD;
1504
   }
1505
 
1506
   for (i = 0; i < 12; i++)
1507
   {
1508
      squareOfIndex[i] = NO_SQUARE;
1509
   }
1510
 
1511
   i = 0;
1512
 
1513
   ITERATE_BITBOARD(&allMoves, sq1)
1514
   {
1515
      assert(i < 12);
1516
 
1517
      squareOfIndex[i++] = sq1;
1518
   }
1519
 
1520
   for (pieceSetup = 0; pieceSetup < 4096; pieceSetup++)
1521
   {
1522
      Bitboard currentSetup = EMPTY_BITBOARD, effectiveMoves;
1523
      int j = 1;
1524
      Bitboard magicIndex;
1525
 
1526
      for (i = 0; i < 12 && squareOfIndex[i] != NO_SQUARE; i++)
1527
      {
1528
         if ((pieceSetup & j) != 0)
1529
         {
1530
            setSquare(currentSetup, squareOfIndex[i]);
1531
         }
1532
 
1533
         j *= 2;
1534
      }
1535
 
1536
      calculateObstacles(currentSetup, obstacles);
1537
      effectiveMoves = getBishopMoves(square, obstacles);
1538
      magicIndex = ((currentSetup & premask) * magicNumber) >> 55;
1539
      magicBishopMoves[square][magicIndex] = effectiveMoves;
1540
   }
1541
}
1542
 
1543
/* #define GENERATE_MAGIC_NUMBERS */
1544
#ifdef GENERATE_MAGIC_NUMBERS
1545
 
1546
#define IMAX 4096
1547
#define BMAX 12
1548
Bitboard collisions[IMAX];
1549
 
1550
static bool testMagicNumber(const Bitboard magicNumber, const Square square,
1551
                            const bool rookMoves)
1552
{
1553
   Square squareOfIndex[BMAX];
1554
   const Bitboard premask =
1555
      (rookMoves ? preMaskRook[square] : preMaskBishop[square]);
1556
   Bitboard allMoves = premask;
1557
   int i, pieceSetup;
1558
   Square sq1;
1559
   BYTE obstacles[NUM_LANES];
1560
 
1561
   for (i = 0; i < IMAX; i++)
1562
   {
1563
      collisions[i] = EMPTY_BITBOARD;
1564
   }
1565
 
1566
   for (i = 0; i < BMAX; i++)
1567
   {
1568
      squareOfIndex[i] = NO_SQUARE;
1569
   }
1570
 
1571
   i = 0;
1572
 
1573
   ITERATE_BITBOARD(&allMoves, sq1)
1574
   {
1575
      assert(i < BMAX);
1576
 
1577
      squareOfIndex[i++] = sq1;
1578
   }
1579
 
1580
   for (pieceSetup = 0; pieceSetup < IMAX; pieceSetup++)
1581
   {
1582
      Bitboard currentSetup = EMPTY_BITBOARD, effectiveMoves, calcBase;
1583
      int j = 1;
1584
      Bitboard magicIndex;
1585
      const int shift = (rookMoves ? 64 - 12 : 64 - 9);
1586
 
1587
      for (i = 0; i < BMAX && squareOfIndex[i] != NO_SQUARE; i++)
1588
      {
1589
         if ((pieceSetup & j) != 0)
1590
         {
1591
            setSquare(currentSetup, squareOfIndex[i]);
1592
         }
1593
 
1594
         j *= 2;
1595
      }
1596
 
1597
      calculateObstacles(currentSetup, obstacles);
1598
      effectiveMoves =
1599
         (rookMoves ? getRookMoves(square, obstacles) :
1600
          getBishopMoves(square, obstacles));
1601
      calcBase = currentSetup & premask;
1602
      magicIndex = (calcBase * magicNumber) >> shift;
1603
 
1604
      if (collisions[magicIndex] == EMPTY_BITBOARD)
1605
      {
1606
         collisions[magicIndex] = effectiveMoves;
1607
      }
1608
      else
1609
      {
1610
         if (effectiveMoves != collisions[magicIndex])
1611
         {
1612
            return FALSE;       /* severe collision -> magic number not suitable */
1613
         }
1614
      }
1615
   }
1616
 
1617
   return TRUE;                 /* the given magic number is valid */
1618
}
1619
 
1620
static UINT64 get64bitRandom()
1621
{
1622
   const UINT64 limit = (RAND_MAX * 13) / 100;
1623
   UINT64 rn = 0, runningOne = 1;
1624
   int i;
1625
 
1626
   for (i = 0; i < 64; i++)
1627
   {
1628
      if (rand() <= limit)
1629
      {
1630
         rn |= runningOne;
1631
      }
1632
 
1633
      runningOne *= 2;
1634
   }
1635
 
1636
   return rn;
1637
}
1638
 
1639
static void calculateMagicNumbers()
1640
{
1641
   Square square;
1642
 
1643
   printf("{");
1644
 
1645
   ITERATE(square)
1646
   {
1647
      Bitboard magicNumber = get64bitRandom();
1648
 
1649
      while (testMagicNumber(magicNumber, square, TRUE) == FALSE)
1650
      {
1651
         magicNumber = get64bitRandom();
1652
      }
1653
 
1654
      printf("%llu, ", magicNumber);
1655
 
1656
      if ((square % 2) == 1)
1657
      {
1658
         printf("\n");
1659
      }
1660
   }
1661
 
1662
   printf("};\n{");
1663
 
1664
   ITERATE(square)
1665
   {
1666
      Bitboard magicNumber = get64bitRandom();
1667
 
1668
      while (testMagicNumber(magicNumber, square, FALSE) == FALSE)
1669
      {
1670
         magicNumber = get64bitRandom();
1671
      }
1672
 
1673
      printf("%llu, ", magicNumber);
1674
 
1675
      if ((square % 2) == 1)
1676
      {
1677
         printf("\n");
1678
      }
1679
   }
1680
 
1681
   printf("};\n");
1682
   getKeyStroke();
1683
}
1684
 
1685
#endif /* GENREATE_MAGIC_NUMBERS */
1686
 
1687
Bitboard getFlippedBitboard(Bitboard original)
1688
{
1689
   Bitboard flipped = EMPTY_BITBOARD;
1690
   Square square;
1691
 
1692
   ITERATE_BITBOARD(&original, square)
1693
   {
1694
      setSquare(flipped, getFlippedSquare(square));
1695
   }
1696
 
1697
   return flipped;
1698
}
1699
 
1700
int initializeModuleBitboard()
1701
{
1702
   INT32 i;
1703
   UINT32 j;
1704
   INT8 k, indexLow, indexHigh;
1705
   UINT64 min = 1;
1706
   Square square;
1707
 
1708
   if (isInitialized)
1709
   {
1710
      return 0;
1711
   }
1712
   else
1713
   {
1714
      isInitialized = TRUE;
1715
   }
1716
 
1717
   ITERATE(i)
1718
   {
1719
      minValue[i] = min;
1720
      maxValue[i] = ~min;
1721
 
1722
      min *= 2;
1723
   }
1724
 
1725
   lowestBit[0] = highestBit[0] = NO_SQUARE;
1726
   numSetBits[0] = rankOverlay[0] = 0;
1727
 
1728
   for (i = 1; i <= 0xffffL; i++)
1729
   {
1730
      numSetBits[i] = _getNumberOfSetBits(i);
1731
      rankOverlay[i] = _getRankOverlay(i);
1732
 
1733
      j = i;
1734
      indexLow = indexHigh = NO_SQUARE;
1735
 
1736
      for (k = 0x00; k <= 0x0f; k++)
1737
      {
1738
         if ((j & 1) == 1)
1739
         {
1740
            if (indexLow == NO_SQUARE)
1741
            {
1742
               indexLow = k;
1743
            }
1744
 
1745
            indexHigh = k;
1746
         }
1747
 
1748
         j >>= 1;
1749
      }
1750
 
1751
      lowestBit[i] = indexLow;
1752
      highestBit[i] = indexHigh;
1753
   }
1754
 
1755
   ITERATE(square)
1756
   {
1757
      int distance;
1758
 
1759
      if (squareColor(square) == DARK)
1760
      {
1761
         setSquare(darkSquares, square);
1762
         clearSquare(lightSquares, square);
1763
      }
1764
      else
1765
      {
1766
         clearSquare(darkSquares, square);
1767
         setSquare(lightSquares, square);
1768
      }
1769
 
1770
      for (distance = 0; distance <= 7; distance++)
1771
      {
1772
         Square square2;
1773
 
1774
         squaresInDistance[distance][square] = EMPTY_BITBOARD;
1775
 
1776
         ITERATE(square2)
1777
         {
1778
            if (distance(square, square2) <= distance)
1779
            {
1780
               setSquare(squaresInDistance[distance][square], square2);
1781
            }
1782
         }
1783
      }
1784
 
1785
      for (distance = 0; distance <= 14; distance++)
1786
      {
1787
         Square square2;
1788
 
1789
         squaresInTaxiDistance[distance][square] = EMPTY_BITBOARD;
1790
 
1791
         ITERATE(square2)
1792
         {
1793
            if (taxiDistance(square, square2) <= distance)
1794
            {
1795
               setSquare(squaresInTaxiDistance[distance][square], square2);
1796
            }
1797
         }
1798
      }
1799
   }
1800
 
1801
   for (i = FILE_A; i <= FILE_H; i++)
1802
   {
1803
      int j;
1804
 
1805
      for (j = FILE_A; j <= FILE_H; j++)
1806
      {
1807
         int k;
1808
 
1809
         squaresOfFileRange[i][j] = squaresOfRankRange[i][j] = EMPTY_BITBOARD;
1810
 
1811
         for (k = FILE_A; k <= FILE_H; k++)
1812
         {
1813
            if ((k >= i && k <= j) || (k >= j && k <= i))
1814
            {
1815
               squaresOfFileRange[i][j] |= squaresOfFile[k];
1816
               squaresOfRankRange[i][j] |= squaresOfRank[k];
1817
            }
1818
         }
1819
      }
1820
   }
1821
 
1822
   nonA = ~squaresOfFile[FILE_A], nonH = ~squaresOfFile[FILE_H];
1823
   center = minValue[D4] | minValue[D5] | minValue[E4] | minValue[E5];
1824
   extendedCenter =
1825
      (squaresOfFile[FILE_C] | squaresOfFile[FILE_D] |
1826
       squaresOfFile[FILE_E] | squaresOfFile[FILE_F]) &
1827
      (squaresOfRank[RANK_3] | squaresOfRank[RANK_4] |
1828
       squaresOfRank[RANK_5] | squaresOfRank[RANK_6]);
1829
   border = squaresOfFile[FILE_A] | squaresOfFile[FILE_H] |
1830
      squaresOfRank[RANK_1] | squaresOfRank[RANK_8];
1831
   queenSide =
1832
      squaresOfFile[FILE_A] | squaresOfFile[FILE_B] | squaresOfFile[FILE_C];
1833
   kingSide =
1834
      squaresOfFile[FILE_F] | squaresOfFile[FILE_G] | squaresOfFile[FILE_H];
1835
   centerFiles = squaresOfFile[FILE_D] | squaresOfFile[FILE_E];
1836
   promotionCandidates[WHITE] = squaresOfRank[RANK_7];
1837
   promotionCandidates[BLACK] = squaresOfRank[RANK_2];
1838
 
1839
   initializeKingMoves();
1840
   initializeRookMoves();
1841
   initializeBishopMoves();
1842
   initializeQueenMoves();
1843
   initializeKnightMoves();
1844
   initializePawnMoves();
1845
   initializeSquaresBehind();
1846
   initializeSquaresBetween();
1847
   initializeSquareLaneInfo();
1848
   initializeLaneMasks();
1849
   initializeCastlings();
1850
 
1851
   ITERATE(square)
1852
   {
1853
      const Bitboard corona = generalMoves[KING][square];
1854
      Square square2;
1855
 
1856
      orthoKingAttackers[square] = diaKingAttackers[square] =
1857
         knightKingAttackers[square] = pawnKingAttackers[WHITE][square] =
1858
         pawnKingAttackers[BLACK][square] = EMPTY_BITBOARD;
1859
      squaresAbove[WHITE][square] = squaresAbove[BLACK][square] =
1860
         squaresBelow[WHITE][square] = squaresBelow[BLACK][square] =
1861
         squaresLeftOf[square] = squaresRightOf[square] = EMPTY_BITBOARD;
1862
 
1863
      ITERATE(square2)
1864
      {
1865
         const Bitboard orthoSquares = generalMoves[ROOK][square2];
1866
         const Bitboard diaSquares = generalMoves[BISHOP][square2];
1867
         const Bitboard knightSquares = generalMoves[KNIGHT][square2];
1868
         const Bitboard whitePawnSquares = generalMoves[WHITE_PAWN][square2];
1869
         const Bitboard blackPawnSquares = generalMoves[BLACK_PAWN][square2];
1870
 
1871
         if (square != square2 && (corona & orthoSquares) != EMPTY_BITBOARD &&
1872
             taxiDistance(square, square2) > 1)
1873
         {
1874
            setSquare(orthoKingAttackers[square], square2);
1875
         }
1876
 
1877
         if (square != square2 && (corona & diaSquares) != EMPTY_BITBOARD &&
1878
             (distance(square, square2) > 1 ||
1879
              taxiDistance(square, square2) != 2))
1880
         {
1881
            setSquare(diaKingAttackers[square], square2);
1882
         }
1883
 
1884
         if (square != square2 &&
1885
             (corona & knightSquares) != EMPTY_BITBOARD &&
1886
             testSquare(knightSquares, square) == EMPTY_BITBOARD)
1887
         {
1888
            setSquare(knightKingAttackers[square], square2);
1889
         }
1890
 
1891
         if (square != square2 &&
1892
             (corona & whitePawnSquares) != EMPTY_BITBOARD &&
1893
             testSquare(whitePawnSquares, square) == EMPTY_BITBOARD)
1894
         {
1895
            setSquare(pawnKingAttackers[WHITE][square], square2);
1896
         }
1897
 
1898
         if (square != square2 &&
1899
             (corona & blackPawnSquares) != EMPTY_BITBOARD &&
1900
             testSquare(blackPawnSquares, square) == EMPTY_BITBOARD)
1901
         {
1902
            setSquare(pawnKingAttackers[BLACK][square], square2);
1903
         }
1904
 
1905
         if (rank(square2) < rank(square))
1906
         {
1907
            setSquare(squaresBelow[WHITE][square], square2);
1908
            setSquare(squaresAbove[BLACK][square], square2);
1909
         }
1910
 
1911
         if (rank(square2) > rank(square))
1912
         {
1913
            setSquare(squaresAbove[WHITE][square], square2);
1914
            setSquare(squaresBelow[BLACK][square], square2);
1915
         }
1916
 
1917
         if (file(square2) < file(square))
1918
         {
1919
            setSquare(squaresLeftOf[square], square2);
1920
         }
1921
 
1922
         if (file(square2) > file(square))
1923
         {
1924
            setSquare(squaresRightOf[square], square2);
1925
         }
1926
      }
1927
   }
1928
 
1929
   for (i = 0; i < 256; i++)
1930
   {
1931
      for (j = 0; j < 8; j++)
1932
      {
1933
         bitshiftGap[j][i] = (i == 0 ? 0 : 8);
1934
 
1935
         for (k = 0; k < 8; k++)
1936
         {
1937
            if ((minValue[(int) k] & i) != 0
1938
                && abs(j - k) < bitshiftGap[j][i])
1939
            {
1940
               bitshiftGap[j][i] = (UINT8) abs(j - k);
1941
            }
1942
         }
1943
      }
1944
   }
1945
 
1946
   for (i = 0; i < 4; i++)
1947
   {
1948
      UINT64 bitMask;
1949
 
1950
      for (bitMask = 0; bitMask < 0x10000; bitMask++)
1951
      {
1952
         SetSquaresInfo *info = &setSquares[i][bitMask];
1953
         Bitboard board = bitMask << (16 * i);
1954
         Square square;
1955
 
1956
         info->numSetSquares = 0;
1957
 
1958
         ITERATE_BITBOARD(&board, square)
1959
         {
1960
            info->setSquares[info->numSetSquares++] = (UINT8) square;
1961
         }
1962
      }
1963
   }
1964
 
1965
   initializePremasks();
1966
 
1967
   ITERATE(square)
1968
   {
1969
      initializeMagicRookMoves(square);
1970
      initializeMagicBishopMoves(square);
1971
   }
1972
 
1973
   ITERATE(square)
1974
   {
1975
      int i;
1976
 
1977
      magicSquareInfoRook[square].preMask = preMaskRook[square];
1978
      magicSquareInfoRook[square].magicNumber = magicRookNumber[square];
1979
 
1980
      for (i = 0; i < IMAX_ROOK; i++)
1981
      {
1982
         magicSquareInfoRook[square].moves[i] = magicRookMoves[square][i];
1983
      }
1984
 
1985
      magicSquareInfoBishop[square].preMask = preMaskBishop[square];
1986
      magicSquareInfoBishop[square].magicNumber = magicBishopNumber[square];
1987
 
1988
      for (i = 0; i < IMAX_BISHOP; i++)
1989
      {
1990
         magicSquareInfoBishop[square].moves[i] = magicBishopMoves[square][i];
1991
      }
1992
   }
1993
 
1994
   /*
1995
      for (i = 0; i < 8; i++)
1996
      {
1997
      logDebug("0x%016llx,\n", squaresOfLateralFiles[i]);
1998
      }
1999
 
2000
      getKeyStroke();
2001
    */
2002
 
2003
#ifdef GENERATE_MAGIC_NUMBERS
2004
   calculateMagicNumbers();
2005
#endif
2006
 
2007
   return 0;
2008
}
2009
 
2010
#ifndef NDEBUG
2011
 
2012
static int testBitOperations()
2013
{
2014
   Bitboard b = EMPTY_BITBOARD;
2015
 
2016
   assert(testSquare(lightSquares, A1) == 0);
2017
   assert(testSquare(lightSquares, B1));
2018
   assert(testSquare(lightSquares, G8));
2019
   assert(testSquare(lightSquares, H8) == 0);
2020
 
2021
   assert(testSquare(darkSquares, A1));
2022
   assert(testSquare(darkSquares, B1) == 0);
2023
   assert(testSquare(darkSquares, G8) == 0);
2024
   assert(testSquare(darkSquares, H8));
2025
 
2026
   assert(highestBit[0x0f] == 3);
2027
   assert(highestBit[0xffff] == 15);
2028
   assert(numSetBits[0] == 0);
2029
   assert(numSetBits[0x5555] == 8);
2030
   assert(numSetBits[0xaaaa] == 8);
2031
   assert(numSetBits[0xffff] == 16);
2032
 
2033
   assert(testSquare(b, D4) == 0);
2034
   setSquare(b, D4);
2035
   assert(testSquare(b, D4) != 0);
2036
   clearSquare(b, D4);
2037
   assert(testSquare(b, D4) == 0);
2038
 
2039
   assert(testSquare(b, H8) == 0);
2040
   setSquare(b, H8);
2041
   assert(testSquare(b, H8) != 0);
2042
   clearSquare(b, H8);
2043
   assert(testSquare(b, H8) == 0);
2044
 
2045
   assert(getLastSquare(&b) == NO_SQUARE);
2046
   setSquare(b, H8);
2047
   assert(getLastSquare(&b) == H8);
2048
   assert(getLastSquare(&b) == NO_SQUARE);
2049
 
2050
   assert(testSquare(squaresBehind[D4][C3], E5));
2051
   assert(testSquare(squaresBehind[D4][C3], F6));
2052
   assert(testSquare(squaresBehind[D4][C3], G7));
2053
   assert(testSquare(squaresBehind[D4][C3], H8));
2054
   assert(getNumberOfSetSquares(squaresBehind[D4][C3]) == 4);
2055
 
2056
   assert(testSquare(squaresBetween[B3][F7], C4));
2057
   assert(testSquare(squaresBetween[B3][F7], D5));
2058
   assert(testSquare(squaresBetween[B3][F7], E6));
2059
   assert(getNumberOfSetSquares(squaresBetween[B3][F7]) == 3);
2060
 
2061
   assert(rankOverlay[0x8143] == 0xC3);
2062
 
2063
   b = EMPTY_BITBOARD;
2064
   setSquare(b, A4);
2065
   setSquare(b, E1);
2066
   setSquare(b, E8);
2067
   setSquare(b, H7);
2068
   assert(getRankOverlay(b) == 0x91);
2069
 
2070
   assert(testSquare(squaresInDistance[1][C3], C4) != FALSE);
2071
   assert(testSquare(squaresInDistance[1][C3], C5) == FALSE);
2072
   assert(testSquare(squaresInDistance[3][E5], E2) != FALSE);
2073
   assert(testSquare(squaresInDistance[3][E5], E1) == FALSE);
2074
   assert(testSquare(squaresInDistance[5][H8], C3) != FALSE);
2075
   assert(testSquare(squaresInDistance[5][H8], B2) == FALSE);
2076
 
2077
   assert(bitshiftGap[5][0] == 0);
2078
   assert(bitshiftGap[1][129] == 1);
2079
   assert(bitshiftGap[4][129] == 3);
2080
 
2081
   return 0;
2082
}
2083
 
2084
static int testGeneralMoves()
2085
{
2086
   assert(testSquare(generalMoves[KING][C3], C4));
2087
   assert(testSquare(generalMoves[KING][C3], D4));
2088
   assert(testSquare(generalMoves[KING][C3], D3));
2089
   assert(testSquare(generalMoves[KING][C3], D2));
2090
   assert(testSquare(generalMoves[KING][C3], C2));
2091
   assert(testSquare(generalMoves[KING][C3], B2));
2092
   assert(testSquare(generalMoves[KING][C3], B3));
2093
   assert(testSquare(generalMoves[KING][C3], B4));
2094
   assert(getNumberOfSetSquares(generalMoves[KING][C3]) == 8);
2095
 
2096
   assert(testSquare(generalMoves[ROOK][C3], C8));
2097
   assert(testSquare(generalMoves[ROOK][C3], H3));
2098
   assert(testSquare(generalMoves[ROOK][C3], C1));
2099
   assert(testSquare(generalMoves[ROOK][C3], A3));
2100
   assert(getNumberOfSetSquares(generalMoves[ROOK][C3]) == 14);
2101
 
2102
   assert(testSquare(generalMoves[BISHOP][C3], H8));
2103
   assert(testSquare(generalMoves[BISHOP][C3], E1));
2104
   assert(testSquare(generalMoves[BISHOP][C3], A1));
2105
   assert(testSquare(generalMoves[BISHOP][C3], A5));
2106
   assert(getNumberOfSetSquares(generalMoves[BISHOP][C3]) == 11);
2107
 
2108
   assert(testSquare(generalMoves[QUEEN][C3], C8));
2109
   assert(testSquare(generalMoves[QUEEN][C3], H8));
2110
   assert(testSquare(generalMoves[QUEEN][C3], H3));
2111
   assert(testSquare(generalMoves[QUEEN][C3], E1));
2112
   assert(testSquare(generalMoves[QUEEN][C3], C1));
2113
   assert(testSquare(generalMoves[QUEEN][C3], A1));
2114
   assert(testSquare(generalMoves[QUEEN][C3], A3));
2115
   assert(testSquare(generalMoves[QUEEN][C3], A5));
2116
   assert(getNumberOfSetSquares(generalMoves[QUEEN][C3]) == 25);
2117
 
2118
   assert(testSquare(generalMoves[KNIGHT][C3], A2));
2119
   assert(testSquare(generalMoves[KNIGHT][C3], A4));
2120
   assert(testSquare(generalMoves[KNIGHT][C3], B5));
2121
   assert(testSquare(generalMoves[KNIGHT][C3], D5));
2122
   assert(testSquare(generalMoves[KNIGHT][C3], E4));
2123
   assert(testSquare(generalMoves[KNIGHT][C3], E2));
2124
   assert(testSquare(generalMoves[KNIGHT][C3], D1));
2125
   assert(testSquare(generalMoves[KNIGHT][C3], B1));
2126
   assert(getNumberOfSetSquares(generalMoves[KNIGHT][C3]) == 8);
2127
   assert(getNumberOfSetSquares(generalMoves[KNIGHT][A1]) == 2);
2128
   assert(getNumberOfSetSquares(generalMoves[KNIGHT][H8]) == 2);
2129
 
2130
   assert(testSquare(generalMoves[WHITE_PAWN][A2], B3));
2131
   assert(getNumberOfSetSquares(generalMoves[WHITE_PAWN][A2]) == 1);
2132
   assert(testSquare(generalMoves[WHITE_PAWN][B2], A3));
2133
   assert(testSquare(generalMoves[WHITE_PAWN][B2], C3));
2134
   assert(getNumberOfSetSquares(generalMoves[WHITE_PAWN][B2]) == 2);
2135
   assert(testSquare(generalMoves[WHITE_PAWN][H2], G3));
2136
   assert(getNumberOfSetSquares(generalMoves[WHITE_PAWN][H2]) == 1);
2137
 
2138
   assert(testSquare(generalMoves[BLACK_PAWN][A7], B6));
2139
   assert(getNumberOfSetSquares(generalMoves[BLACK_PAWN][A7]) == 1);
2140
   assert(testSquare(generalMoves[BLACK_PAWN][B7], A6));
2141
   assert(testSquare(generalMoves[BLACK_PAWN][B7], C6));
2142
   assert(getNumberOfSetSquares(generalMoves[BLACK_PAWN][B7]) == 2);
2143
   assert(testSquare(generalMoves[BLACK_PAWN][H7], G6));
2144
   assert(getNumberOfSetSquares(generalMoves[BLACK_PAWN][H7]) == 1);
2145
 
2146
   return 0;
2147
}
2148
 
2149
static int testPieces()
2150
{
2151
   Bitboard b = EMPTY_BITBOARD, moves;
2152
   BYTE obstacles[NUM_LANES];
2153
 
2154
   setSquare(b, C3);
2155
   setSquare(b, C6);
2156
   setSquare(b, F6);
2157
 
2158
   calculateObstacles(b, obstacles);
2159
 
2160
   moves = getMagicRookMoves(C4, b);
2161
   assert(testSquare(moves, C3));
2162
   assert(testSquare(moves, C5));
2163
   assert(testSquare(moves, C6));
2164
   assert(testSquare(moves, A4));
2165
   assert(testSquare(moves, B4));
2166
   assert(testSquare(moves, D4));
2167
   assert(testSquare(moves, E4));
2168
   assert(testSquare(moves, F4));
2169
   assert(testSquare(moves, G4));
2170
   assert(testSquare(moves, H4));
2171
   assert(getNumberOfSetSquares(moves) == 10);
2172
 
2173
   moves = getMagicBishopMoves(E5, b);
2174
   assert(testSquare(moves, D4));
2175
   assert(testSquare(moves, C3));
2176
   assert(testSquare(moves, D6));
2177
   assert(testSquare(moves, C7));
2178
   assert(testSquare(moves, B8));
2179
   assert(testSquare(moves, F6));
2180
   assert(testSquare(moves, F4));
2181
   assert(testSquare(moves, G3));
2182
   assert(testSquare(moves, H2));
2183
   assert(getNumberOfSetSquares(moves) == 9);
2184
 
2185
   moves = getMagicQueenMoves(F3, b);
2186
   assert(testSquare(moves, F2));
2187
   assert(testSquare(moves, F1));
2188
   assert(testSquare(moves, F4));
2189
   assert(testSquare(moves, F5));
2190
   assert(testSquare(moves, F6));
2191
   assert(testSquare(moves, E3));
2192
   assert(testSquare(moves, D3));
2193
   assert(testSquare(moves, C3));
2194
   assert(testSquare(moves, G3));
2195
   assert(testSquare(moves, H3));
2196
   assert(testSquare(moves, E4));
2197
   assert(testSquare(moves, D5));
2198
   assert(testSquare(moves, C6));
2199
   assert(testSquare(moves, G4));
2200
   assert(testSquare(moves, H5));
2201
   assert(testSquare(moves, G2));
2202
   assert(testSquare(moves, H1));
2203
   assert(testSquare(moves, E2));
2204
   assert(testSquare(moves, D1));
2205
   assert(getNumberOfSetSquares(moves) == 19);
2206
 
2207
   moves = getKnightMoves(A8);
2208
   assert(testSquare(moves, B6));
2209
   assert(testSquare(moves, C7));
2210
   assert(getNumberOfSetSquares(moves) == 2);
2211
 
2212
   moves = getKnightMoves(E5);
2213
   assert(testSquare(moves, F7));
2214
   assert(testSquare(moves, G6));
2215
   assert(testSquare(moves, G4));
2216
   assert(testSquare(moves, F3));
2217
   assert(testSquare(moves, D3));
2218
   assert(testSquare(moves, C4));
2219
   assert(testSquare(moves, C6));
2220
   assert(testSquare(moves, D7));
2221
   assert(getNumberOfSetSquares(moves) == 8);
2222
 
2223
   return 0;
2224
}
2225
 
2226
static int testPawns()
2227
{
2228
   Bitboard b = EMPTY_BITBOARD, moves, pawns;
2229
   BYTE obstacles[NUM_LANES];
2230
 
2231
   setSquare(b, B3);
2232
   setSquare(b, C4);
2233
   setSquare(b, E4);
2234
   setSquare(b, F6);
2235
   setSquare(b, E5);
2236
   setSquare(b, D6);
2237
   setSquare(b, G2);
2238
   setSquare(b, G3);
2239
   setSquare(b, H2);
2240
   setSquare(b, H7);
2241
 
2242
   calculateObstacles(b, obstacles);
2243
 
2244
   moves = getPawnAdvances(WHITE, A2, b);
2245
   assert(testSquare(moves, A3));
2246
   assert(testSquare(moves, A4));
2247
   assert(getNumberOfSetSquares(moves) == 2);
2248
 
2249
   moves = getPawnAdvances(WHITE, B2, b);
2250
   assert(getNumberOfSetSquares(moves) == 0);
2251
 
2252
   moves = getPawnAdvances(WHITE, C2, b);
2253
   assert(testSquare(moves, C3));
2254
   assert(getNumberOfSetSquares(moves) == 1);
2255
 
2256
   moves = getPawnAdvances(BLACK, H7, b);
2257
   assert(testSquare(moves, H6));
2258
   assert(testSquare(moves, H5));
2259
   assert(getNumberOfSetSquares(moves) == 2);
2260
 
2261
   moves = getPawnAdvances(BLACK, F7, b);
2262
   assert(getNumberOfSetSquares(moves) == 0);
2263
 
2264
   moves = getPawnAdvances(BLACK, E7, b);
2265
   assert(testSquare(moves, E6));
2266
   assert(getNumberOfSetSquares(moves) == 1);
2267
 
2268
   moves = getPawnCaptures(WHITE_PAWN, A2, b);
2269
   assert(testSquare(moves, B3));
2270
   assert(getNumberOfSetSquares(moves) == 1);
2271
 
2272
   moves = getPawnCaptures(WHITE_PAWN, D3, b);
2273
   assert(testSquare(moves, C4));
2274
   assert(testSquare(moves, E4));
2275
   assert(getNumberOfSetSquares(moves) == 2);
2276
 
2277
   moves = getPawnCaptures(BLACK_PAWN, G7, b);
2278
   assert(testSquare(moves, F6));
2279
   assert(getNumberOfSetSquares(moves) == 1);
2280
 
2281
   moves = getPawnCaptures(BLACK_PAWN, E7, b);
2282
   assert(testSquare(moves, D6));
2283
   assert(testSquare(moves, F6));
2284
   assert(getNumberOfSetSquares(moves) == 2);
2285
 
2286
   pawns = getInterestedPawns(BLACK, D5, b);
2287
   assert(testSquare(pawns, D6));
2288
   assert(getNumberOfSetSquares(pawns) == 1);
2289
 
2290
   pawns = getInterestedPawns(BLACK, H5, b);
2291
   assert(testSquare(pawns, H7));
2292
   assert(testSquare(pawns, H6));
2293
   assert(getNumberOfSetSquares(pawns) == 2);
2294
 
2295
   pawns = getInterestedPawns(WHITE, H4, b);
2296
   assert(testSquare(pawns, H2));
2297
   assert(testSquare(pawns, H3));
2298
   assert(getNumberOfSetSquares(pawns) == 2);
2299
 
2300
   pawns = getInterestedPawns(WHITE, G4, b);
2301
   assert(testSquare(pawns, G3));
2302
   assert(getNumberOfSetSquares(pawns) == 1);
2303
 
2304
   return 0;
2305
}
2306
 
2307
static int testKings()
2308
{
2309
   Bitboard obstacles = EMPTY_BITBOARD, moves;
2310
   BYTE castlingRights = WHITE_00 | WHITE_000 | BLACK_000 | BLACK_00;
2311
 
2312
   moves = getKingMoves(A1);
2313
   assert(testSquare(moves, B1));
2314
   assert(testSquare(moves, B2));
2315
   assert(testSquare(moves, A2));
2316
   assert(getNumberOfSetSquares(moves) == 3);
2317
 
2318
   moves = getKingMoves(D5);
2319
   assert(testSquare(moves, D6));
2320
   assert(testSquare(moves, E6));
2321
   assert(testSquare(moves, E5));
2322
   assert(testSquare(moves, E4));
2323
   assert(testSquare(moves, D4));
2324
   assert(testSquare(moves, C4));
2325
   assert(testSquare(moves, C5));
2326
   assert(testSquare(moves, C6));
2327
   assert(getNumberOfSetSquares(moves) == 8);
2328
 
2329
   moves = getKingMoves(D5);
2330
   assert(testSquare(moves, D6));
2331
   assert(testSquare(moves, E6));
2332
   assert(testSquare(moves, E5));
2333
   assert(testSquare(moves, E4));
2334
   assert(testSquare(moves, D4));
2335
   assert(testSquare(moves, C4));
2336
   assert(testSquare(moves, C5));
2337
   assert(testSquare(moves, C6));
2338
   assert(getNumberOfSetSquares(moves) == 8);
2339
 
2340
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2341
   assert(testSquare(moves, G1));
2342
   assert(testSquare(moves, C1));
2343
   assert(getNumberOfSetSquares(moves) == 2);
2344
 
2345
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2346
   assert(testSquare(moves, G8));
2347
   assert(testSquare(moves, C8));
2348
   assert(getNumberOfSetSquares(moves) == 2);
2349
 
2350
   castlingRights = WHITE_00 | BLACK_00;
2351
 
2352
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2353
   assert(testSquare(moves, G1));
2354
   assert(getNumberOfSetSquares(moves) == 1);
2355
 
2356
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2357
   assert(testSquare(moves, G8));
2358
   assert(getNumberOfSetSquares(moves) == 1);
2359
 
2360
   castlingRights = WHITE_000 | BLACK_000;
2361
 
2362
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2363
   assert(testSquare(moves, C1));
2364
   assert(getNumberOfSetSquares(moves) == 1);
2365
 
2366
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2367
   assert(testSquare(moves, C8));
2368
   assert(getNumberOfSetSquares(moves) == 1);
2369
 
2370
   castlingRights = WHITE_00 | WHITE_000 | BLACK_000 | BLACK_00;
2371
   setSquare(obstacles, D1);
2372
   setSquare(obstacles, D8);
2373
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2374
   assert(testSquare(moves, G1));
2375
   assert(getNumberOfSetSquares(moves) == 1);
2376
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2377
   assert(testSquare(moves, G8));
2378
   assert(getNumberOfSetSquares(moves) == 1);
2379
   clearSquare(obstacles, D1);
2380
   clearSquare(obstacles, D8);
2381
 
2382
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2383
   assert(testSquare(moves, G1));
2384
   assert(testSquare(moves, C1));
2385
   assert(getNumberOfSetSquares(moves) == 2);
2386
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2387
   assert(testSquare(moves, G8));
2388
   assert(testSquare(moves, C8));
2389
   assert(getNumberOfSetSquares(moves) == 2);
2390
 
2391
   setSquare(obstacles, C1);
2392
   setSquare(obstacles, C8);
2393
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2394
   assert(testSquare(moves, G1));
2395
   assert(getNumberOfSetSquares(moves) == 1);
2396
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2397
   assert(testSquare(moves, G8));
2398
   assert(getNumberOfSetSquares(moves) == 1);
2399
   clearSquare(obstacles, C1);
2400
   clearSquare(obstacles, C8);
2401
 
2402
   setSquare(obstacles, F1);
2403
   setSquare(obstacles, F8);
2404
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2405
   assert(testSquare(moves, C1));
2406
   assert(getNumberOfSetSquares(moves) == 1);
2407
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2408
   assert(testSquare(moves, C8));
2409
   assert(getNumberOfSetSquares(moves) == 1);
2410
   clearSquare(obstacles, F1);
2411
   clearSquare(obstacles, F8);
2412
 
2413
   setSquare(obstacles, G1);
2414
   setSquare(obstacles, G8);
2415
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2416
   assert(testSquare(moves, C1));
2417
   assert(getNumberOfSetSquares(moves) == 1);
2418
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2419
   assert(testSquare(moves, C8));
2420
   assert(getNumberOfSetSquares(moves) == 1);
2421
   clearSquare(obstacles, G1);
2422
   clearSquare(obstacles, G8);
2423
 
2424
   setSquare(obstacles, G1);
2425
   setSquare(obstacles, G8);
2426
   setSquare(obstacles, C1);
2427
   setSquare(obstacles, C8);
2428
   moves = getCastlingMoves(WHITE, castlingRights, obstacles);
2429
   assert(getNumberOfSetSquares(moves) == 0);
2430
   moves = getCastlingMoves(BLACK, castlingRights, obstacles);
2431
   assert(getNumberOfSetSquares(moves) == 0);
2432
   clearSquare(obstacles, G1);
2433
   clearSquare(obstacles, G8);
2434
   clearSquare(obstacles, C1);
2435
   clearSquare(obstacles, C8);
2436
 
2437
   return 0;
2438
}
2439
 
2440
static int testFlooding()
2441
{
2442
   Bitboard kingMoves = getKingMoves(D4);
2443
   Bitboard expected;
2444
 
2445
   floodBoard(&kingMoves);
2446
   expected = squaresBetween[A6][G6] | squaresBetween[A5][G5] |
2447
      squaresBetween[A4][G4] | squaresBetween[A3][G3] |
2448
      squaresBetween[A2][G2];
2449
   assert(kingMoves == expected);
2450
 
2451
   kingMoves = getKingMoves(H1);
2452
   floodBoard(&kingMoves);
2453
   expected = squaresBehind[E3][A3] | squaresBehind[E2][A2] |
2454
      squaresBehind[E1][A1];
2455
   assert(kingMoves == expected);
2456
 
2457
   kingMoves = getKingMoves(A8);
2458
   floodBoard(&kingMoves);
2459
   expected = squaresBehind[D8][H8] | squaresBehind[D7][H7] |
2460
      squaresBehind[D6][H6];
2461
   assert(kingMoves == expected);
2462
 
2463
   return 0;
2464
}
2465
 
2466
static int testGetSetSquares()
2467
{
2468
   UINT8 moveSquares[_64_];
2469
   Bitboard kingMoves = getKingMoves(D4);
2470
   int numMoves = getSetSquares(kingMoves, moveSquares), i;
2471
 
2472
   assert(numMoves == 8);
2473
 
2474
   for (i = 0; i < numMoves; i++)
2475
   {
2476
      const Square square = (Square) moveSquares[i];
2477
 
2478
      assert(testSquare(kingMoves, square) == TRUE);
2479
   }
2480
 
2481
   return 0;
2482
}
2483
 
2484
#endif
2485
 
2486
int testModuleBitboard()
2487
{
2488
#ifndef NDEBUG
2489
   int result;
2490
 
2491
   if ((result = testBitOperations()) != 0)
2492
   {
2493
      return result;
2494
   }
2495
 
2496
   if ((result = testGeneralMoves()) != 0)
2497
   {
2498
      return result;
2499
   }
2500
 
2501
   if ((result = testPieces()) != 0)
2502
   {
2503
      return result;
2504
   }
2505
 
2506
   if ((result = testPawns()) != 0)
2507
   {
2508
      return result;
2509
   }
2510
 
2511
   if ((result = testKings()) != 0)
2512
   {
2513
      return result;
2514
   }
2515
 
2516
   if ((result = testFlooding()) != 0)
2517
   {
2518
      return result;
2519
   }
2520
 
2521
   if ((result = testGetSetSquares()) != 0)
2522
   {
2523
      return result;
2524
   }
2525
#endif
2526
 
2527
   return 0;
2528
}