Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 154 Rev 169
Line 4... Line 4...
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
5
  Copyright (C) 2015-2016 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
5
  Copyright (C) 2015-2018 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
6
 
6
 
7
  Stockfish is free software: you can redistribute it and/or modify
7
  Stockfish is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU General Public License as published by
8
  it under the terms of the GNU General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
10
  (at your option) any later version.
Line 23... Line 23...
23
#include "bitboard.h"
23
#include "bitboard.h"
24
#include "misc.h"
24
#include "misc.h"
25
 
25
 
26
uint8_t PopCnt16[1 << 16];
26
uint8_t PopCnt16[1 << 16];
27
int SquareDistance[SQUARE_NB][SQUARE_NB];
27
int SquareDistance[SQUARE_NB][SQUARE_NB];
28
 
-
 
29
Bitboard  RookMasks  [SQUARE_NB];
-
 
30
Bitboard  RookMagics [SQUARE_NB];
-
 
31
Bitboard* RookAttacks[SQUARE_NB];
-
 
32
unsigned  RookShifts [SQUARE_NB];
-
 
33
 
-
 
34
Bitboard  BishopMasks  [SQUARE_NB];
-
 
35
Bitboard  BishopMagics [SQUARE_NB];
-
 
36
Bitboard* BishopAttacks[SQUARE_NB];
-
 
37
unsigned  BishopShifts [SQUARE_NB];
-
 
38
 
28
 
39
Bitboard SquareBB[SQUARE_NB];
29
Bitboard SquareBB[SQUARE_NB];
40
Bitboard FileBB[FILE_NB];
30
Bitboard FileBB[FILE_NB];
41
Bitboard RankBB[RANK_NB];
31
Bitboard RankBB[RANK_NB];
42
Bitboard AdjacentFilesBB[FILE_NB];
32
Bitboard AdjacentFilesBB[FILE_NB];
43
Bitboard InFrontBB[COLOR_NB][RANK_NB];
33
Bitboard ForwardRanksBB[COLOR_NB][RANK_NB];
44
Bitboard StepAttacksBB[PIECE_NB][SQUARE_NB];
-
 
45
Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
34
Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
46
Bitboard LineBB[SQUARE_NB][SQUARE_NB];
35
Bitboard LineBB[SQUARE_NB][SQUARE_NB];
47
Bitboard DistanceRingBB[SQUARE_NB][8];
36
Bitboard DistanceRingBB[SQUARE_NB][8];
48
Bitboard ForwardBB[COLOR_NB][SQUARE_NB];
37
Bitboard ForwardFileBB[COLOR_NB][SQUARE_NB];
49
Bitboard PassedPawnMask[COLOR_NB][SQUARE_NB];
38
Bitboard PassedPawnMask[COLOR_NB][SQUARE_NB];
50
Bitboard PawnAttackSpan[COLOR_NB][SQUARE_NB];
39
Bitboard PawnAttackSpan[COLOR_NB][SQUARE_NB];
51
Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
40
Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
-
 
41
Bitboard PawnAttacks[COLOR_NB][SQUARE_NB];
-
 
42
 
-
 
43
Magic RookMagics[SQUARE_NB];
-
 
44
Magic BishopMagics[SQUARE_NB];
52
 
45
 
53
namespace {
46
namespace {
54
 
47
 
55
  // De Bruijn sequences. See chessprogramming.wikispaces.com/BitScan
48
  // De Bruijn sequences. See chessprogramming.wikispaces.com/BitScan
56
  const uint64_t DeBruijn64 = 0x3F79D71B4CB0A89ULL;
49
  const uint64_t DeBruijn64 = 0x3F79D71B4CB0A89ULL;
Line 59... Line 52...
59
  int MSBTable[256];            // To implement software msb()
52
  int MSBTable[256];            // To implement software msb()
60
  Square BSFTable[SQUARE_NB];   // To implement software bitscan
53
  Square BSFTable[SQUARE_NB];   // To implement software bitscan
61
  Bitboard RookTable[0x19000];  // To store rook attacks
54
  Bitboard RookTable[0x19000];  // To store rook attacks
62
  Bitboard BishopTable[0x1480]; // To store bishop attacks
55
  Bitboard BishopTable[0x1480]; // To store bishop attacks
63
 
56
 
64
  typedef unsigned (Fn)(Square, Bitboard);
-
 
65
 
-
 
66
  void init_magics(Bitboard table[], Bitboard* attacks[], Bitboard magics[],
57
  void init_magics(Bitboard table[], Magic magics[], Direction directions[]);
67
                   Bitboard masks[], unsigned shifts[], Square deltas[], Fn index);
-
 
68
 
58
 
69
  // bsf_index() returns the index into BSFTable[] to look up the bitscan. Uses
59
  // bsf_index() returns the index into BSFTable[] to look up the bitscan. Uses
70
  // Matt Taylor's folding for 32 bit case, extended to 64 bit by Kim Walisch.
60
  // Matt Taylor's folding for 32 bit case, extended to 64 bit by Kim Walisch.
71
 
61
 
72
  unsigned bsf_index(Bitboard b) {
62
  unsigned bsf_index(Bitboard b) {
Line 171... Line 161...
171
 
161
 
172
  for (File f = FILE_A; f <= FILE_H; ++f)
162
  for (File f = FILE_A; f <= FILE_H; ++f)
173
      AdjacentFilesBB[f] = (f > FILE_A ? FileBB[f - 1] : 0) | (f < FILE_H ? FileBB[f + 1] : 0);
163
      AdjacentFilesBB[f] = (f > FILE_A ? FileBB[f - 1] : 0) | (f < FILE_H ? FileBB[f + 1] : 0);
174
 
164
 
175
  for (Rank r = RANK_1; r < RANK_8; ++r)
165
  for (Rank r = RANK_1; r < RANK_8; ++r)
176
      InFrontBB[WHITE][r] = ~(InFrontBB[BLACK][r + 1] = InFrontBB[BLACK][r] | RankBB[r]);
166
      ForwardRanksBB[WHITE][r] = ~(ForwardRanksBB[BLACK][r + 1] = ForwardRanksBB[BLACK][r] | RankBB[r]);
177
 
167
 
178
  for (Color c = WHITE; c <= BLACK; ++c)
168
  for (Color c = WHITE; c <= BLACK; ++c)
179
      for (Square s = SQ_A1; s <= SQ_H8; ++s)
169
      for (Square s = SQ_A1; s <= SQ_H8; ++s)
180
      {
170
      {
181
          ForwardBB[c][s]      = InFrontBB[c][rank_of(s)] & FileBB[file_of(s)];
171
          ForwardFileBB [c][s] = ForwardRanksBB[c][rank_of(s)] & FileBB[file_of(s)];
182
          PawnAttackSpan[c][s] = InFrontBB[c][rank_of(s)] & AdjacentFilesBB[file_of(s)];
172
          PawnAttackSpan[c][s] = ForwardRanksBB[c][rank_of(s)] & AdjacentFilesBB[file_of(s)];
183
          PassedPawnMask[c][s] = ForwardBB[c][s] | PawnAttackSpan[c][s];
173
          PassedPawnMask[c][s] = ForwardFileBB [c][s] | PawnAttackSpan[c][s];
184
      }
174
      }
185
 
175
 
186
  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
176
  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
187
      for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
177
      for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
188
          if (s1 != s2)
178
          if (s1 != s2)
189
          {
179
          {
190
              SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
180
              SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
191
              DistanceRingBB[s1][SquareDistance[s1][s2] - 1] |= s2;
181
              DistanceRingBB[s1][SquareDistance[s1][s2] - 1] |= s2;
192
          }
182
          }
193
 
183
 
194
  int steps[][9] = { {}, { 7, 9 }, { 17, 15, 10, 6, -6, -10, -15, -17 },
184
  int steps[][5] = { {}, { 7, 9 }, { 6, 10, 15, 17 }, {}, {}, {}, { 1, 7, 8, 9 } };
195
                     {}, {}, {}, { 9, 7, -7, -9, 8, 1, -1, -8 } };
-
 
196
 
185
 
197
  for (Color c = WHITE; c <= BLACK; ++c)
186
  for (Color c = WHITE; c <= BLACK; ++c)
198
      for (PieceType pt = PAWN; pt <= KING; ++pt)
187
      for (PieceType pt : { PAWN, KNIGHT, KING })
199
          for (Square s = SQ_A1; s <= SQ_H8; ++s)
188
          for (Square s = SQ_A1; s <= SQ_H8; ++s)
200
              for (int i = 0; steps[pt][i]; ++i)
189
              for (int i = 0; steps[pt][i]; ++i)
201
              {
190
              {
202
                  Square to = s + Square(c == WHITE ? steps[pt][i] : -steps[pt][i]);
191
                  Square to = s + Direction(c == WHITE ? steps[pt][i] : -steps[pt][i]);
203
 
192
 
204
                  if (is_ok(to) && distance(s, to) < 3)
193
                  if (is_ok(to) && distance(s, to) < 3)
-
 
194
                  {
-
 
195
                      if (pt == PAWN)
-
 
196
                          PawnAttacks[c][s] |= to;
-
 
197
                      else
205
                      StepAttacksBB[make_piece(c, pt)][s] |= to;
198
                          PseudoAttacks[pt][s] |= to;
-
 
199
                  }
206
              }
200
              }
207
 
201
 
208
  Square RookDeltas[] = { NORTH,  EAST,  SOUTH,  WEST  };
202
  Direction RookDirections[] = { NORTH,  EAST,  SOUTH,  WEST };
209
  Square BishopDeltas[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
203
  Direction BishopDirections[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
210
 
204
 
211
  init_magics(RookTable, RookAttacks, RookMagics, RookMasks, RookShifts, RookDeltas, magic_index<ROOK>);
205
  init_magics(RookTable, RookMagics, RookDirections);
212
  init_magics(BishopTable, BishopAttacks, BishopMagics, BishopMasks, BishopShifts, BishopDeltas, magic_index<BISHOP>);
206
  init_magics(BishopTable, BishopMagics, BishopDirections);
213
 
207
 
214
  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
208
  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
215
  {
209
  {
216
      PseudoAttacks[QUEEN][s1]  = PseudoAttacks[BISHOP][s1] = attacks_bb<BISHOP>(s1, 0);
210
      PseudoAttacks[QUEEN][s1]  = PseudoAttacks[BISHOP][s1] = attacks_bb<BISHOP>(s1, 0);
217
      PseudoAttacks[QUEEN][s1] |= PseudoAttacks[  ROOK][s1] = attacks_bb<  ROOK>(s1, 0);
211
      PseudoAttacks[QUEEN][s1] |= PseudoAttacks[  ROOK][s1] = attacks_bb<  ROOK>(s1, 0);
218
 
212
 
219
      for (Piece pc = W_BISHOP; pc <= W_ROOK; ++pc)
213
      for (PieceType pt : { BISHOP, ROOK })
220
          for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
214
          for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
221
          {
215
          {
222
              if (!(PseudoAttacks[pc][s1] & s2))
216
              if (!(PseudoAttacks[pt][s1] & s2))
223
                  continue;
217
                  continue;
224
 
218
 
225
              LineBB[s1][s2] = (attacks_bb(pc, s1, 0) & attacks_bb(pc, s2, 0)) | s1 | s2;
219
              LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2;
226
              BetweenBB[s1][s2] = attacks_bb(pc, s1, SquareBB[s2]) & attacks_bb(pc, s2, SquareBB[s1]);
220
              BetweenBB[s1][s2] = attacks_bb(pt, s1, SquareBB[s2]) & attacks_bb(pt, s2, SquareBB[s1]);
227
          }
221
          }
228
  }
222
  }
229
}
223
}
230
 
224
 
231
 
225
 
232
namespace {
226
namespace {
233
 
227
 
234
  Bitboard sliding_attack(Square deltas[], Square sq, Bitboard occupied) {
228
  Bitboard sliding_attack(Direction directions[], Square sq, Bitboard occupied) {
235
 
229
 
236
    Bitboard attack = 0;
230
    Bitboard attack = 0;
237
 
231
 
238
    for (int i = 0; i < 4; ++i)
232
    for (int i = 0; i < 4; ++i)
239
        for (Square s = sq + deltas[i];
233
        for (Square s = sq + directions[i];
240
             is_ok(s) && distance(s, s - deltas[i]) == 1;
234
             is_ok(s) && distance(s, s - directions[i]) == 1;
241
             s += deltas[i])
235
             s += directions[i])
242
        {
236
        {
243
            attack |= s;
237
            attack |= s;
244
 
238
 
245
            if (occupied & s)
239
            if (occupied & s)
246
                break;
240
                break;
Line 253... Line 247...
253
  // init_magics() computes all rook and bishop attacks at startup. Magic
247
  // init_magics() computes all rook and bishop attacks at startup. Magic
254
  // bitboards are used to look up attacks of sliding pieces. As a reference see
248
  // bitboards are used to look up attacks of sliding pieces. As a reference see
255
  // chessprogramming.wikispaces.com/Magic+Bitboards. In particular, here we
249
  // chessprogramming.wikispaces.com/Magic+Bitboards. In particular, here we
256
  // use the so called "fancy" approach.
250
  // use the so called "fancy" approach.
257
 
251
 
258
  void init_magics(Bitboard table[], Bitboard* attacks[], Bitboard magics[],
252
  void init_magics(Bitboard table[], Magic magics[], Direction directions[]) {
259
                   Bitboard masks[], unsigned shifts[], Square deltas[], Fn index) {
-
 
260
 
253
 
-
 
254
    // Optimal PRNG seeds to pick the correct magics in the shortest time
261
    int seeds[][RANK_NB] = { { 8977, 44560, 54343, 38998,  5731, 95205, 104912, 17020 },
255
    int seeds[][RANK_NB] = { { 8977, 44560, 54343, 38998,  5731, 95205, 104912, 17020 },
262
                             {  728, 10316, 55013, 32803, 12281, 15100,  16645,   255 } };
256
                             {  728, 10316, 55013, 32803, 12281, 15100,  16645,   255 } };
263
 
257
 
264
    Bitboard occupancy[4096], reference[4096], edges, b;
258
    Bitboard occupancy[4096], reference[4096], edges, b;
265
    int age[4096] = {0}, current = 0, i, size;
259
    int epoch[4096] = {}, cnt = 0, size = 0;
266
 
-
 
267
    // attacks[s] is a pointer to the beginning of the attacks table for square 's'
-
 
268
    attacks[SQ_A1] = table;
-
 
269
 
260
 
270
    for (Square s = SQ_A1; s <= SQ_H8; ++s)
261
    for (Square s = SQ_A1; s <= SQ_H8; ++s)
271
    {
262
    {
272
        // Board edges are not considered in the relevant occupancies
263
        // Board edges are not considered in the relevant occupancies
273
        edges = ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s));
264
        edges = ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s));
Line 275... Line 266...
275
        // Given a square 's', the mask is the bitboard of sliding attacks from
266
        // Given a square 's', the mask is the bitboard of sliding attacks from
276
        // 's' computed on an empty board. The index must be big enough to contain
267
        // 's' computed on an empty board. The index must be big enough to contain
277
        // all the attacks for each possible subset of the mask and so is 2 power
268
        // all the attacks for each possible subset of the mask and so is 2 power
278
        // the number of 1s of the mask. Hence we deduce the size of the shift to
269
        // the number of 1s of the mask. Hence we deduce the size of the shift to
279
        // apply to the 64 or 32 bits word to get the index.
270
        // apply to the 64 or 32 bits word to get the index.
-
 
271
        Magic& m = magics[s];
280
        masks[s]  = sliding_attack(deltas, s, 0) & ~edges;
272
        m.mask  = sliding_attack(directions, s, 0) & ~edges;
281
        shifts[s] = (Is64Bit ? 64 : 32) - popcount(masks[s]);
273
        m.shift = (Is64Bit ? 64 : 32) - popcount(m.mask);
-
 
274
 
-
 
275
        // Set the offset for the attacks table of the square. We have individual
-
 
276
        // table sizes for each square with "Fancy Magic Bitboards".
-
 
277
        m.attacks = s == SQ_A1 ? table : magics[s - 1].attacks + size;
282
 
278
 
283
        // Use Carry-Rippler trick to enumerate all subsets of masks[s] and
279
        // Use Carry-Rippler trick to enumerate all subsets of masks[s] and
284
        // store the corresponding sliding attack bitboard in reference[].
280
        // store the corresponding sliding attack bitboard in reference[].
285
        b = size = 0;
281
        b = size = 0;
286
        do {
282
        do {
287
            occupancy[size] = b;
283
            occupancy[size] = b;
288
            reference[size] = sliding_attack(deltas, s, b);
284
            reference[size] = sliding_attack(directions, s, b);
289
 
285
 
290
            if (HasPext)
286
            if (HasPext)
291
                attacks[s][pext(b, masks[s])] = reference[size];
287
                m.attacks[pext(b, m.mask)] = reference[size];
292
 
288
 
293
            size++;
289
            size++;
294
            b = (b - masks[s]) & masks[s];
290
            b = (b - m.mask) & m.mask;
295
        } while (b);
291
        } while (b);
296
 
-
 
297
        // Set the offset for the table of the next square. We have individual
-
 
298
        // table sizes for each square with "Fancy Magic Bitboards".
-
 
299
        if (s < SQ_H8)
-
 
300
            attacks[s + 1] = attacks[s] + size;
-
 
301
 
292
 
302
        if (HasPext)
293
        if (HasPext)
303
            continue;
294
            continue;
304
 
295
 
305
        PRNG rng(seeds[Is64Bit][rank_of(s)]);
296
        PRNG rng(seeds[Is64Bit][rank_of(s)]);
306
 
297
 
307
        // Find a magic for square 's' picking up an (almost) random number
298
        // Find a magic for square 's' picking up an (almost) random number
308
        // until we find the one that passes the verification test.
299
        // until we find the one that passes the verification test.
309
        do {
300
        for (int i = 0; i < size; )
310
            do
301
        {
311
                magics[s] = rng.sparse_rand<Bitboard>();
302
            for (m.magic = 0; popcount((m.magic * m.mask) >> 56) < 6; )
312
            while (popcount((magics[s] * masks[s]) >> 56) < 6);
303
                m.magic = rng.sparse_rand<Bitboard>();
313
 
304
 
314
            // A good magic must map every possible occupancy to an index that
305
            // A good magic must map every possible occupancy to an index that
315
            // looks up the correct sliding attack in the attacks[s] database.
306
            // looks up the correct sliding attack in the attacks[s] database.
316
            // Note that we build up the database for square 's' as a side
307
            // Note that we build up the database for square 's' as a side
317
            // effect of verifying the magic.
308
            // effect of verifying the magic. Keep track of the attempt count
-
 
309
            // and save it in epoch[], little speed-up trick to avoid resetting
-
 
310
            // m.attacks[] after every failed attempt.
318
            for (++current, i = 0; i < size; ++i)
311
            for (++cnt, i = 0; i < size; ++i)
319
            {
312
            {
320
                unsigned idx = index(s, occupancy[i]);
313
                unsigned idx = m.index(occupancy[i]);
321
 
314
 
322
                if (age[idx] < current)
315
                if (epoch[idx] < cnt)
323
                {
316
                {
324
                    age[idx] = current;
317
                    epoch[idx] = cnt;
325
                    attacks[s][idx] = reference[i];
318
                    m.attacks[idx] = reference[i];
326
                }
319
                }
327
                else if (attacks[s][idx] != reference[i])
320
                else if (m.attacks[idx] != reference[i])
328
                    break;
321
                    break;
329
            }
322
            }
330
        } while (i < size);
323
        }
331
    }
324
    }
332
  }
325
  }
333
}
326
}