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 30... Line 30...
30
#include "movegen.h"
30
#include "movegen.h"
31
#include "position.h"
31
#include "position.h"
32
#include "thread.h"
32
#include "thread.h"
33
#include "tt.h"
33
#include "tt.h"
34
#include "uci.h"
34
#include "uci.h"
-
 
35
#include "syzygy/tbprobe.h"
35
 
36
 
36
using std::string;
37
using std::string;
37
 
38
 
38
namespace PSQT {
39
namespace PSQT {
39
  extern Score psq[PIECE_NB][SQUARE_NB];
40
  extern Score psq[PIECE_NB][SQUARE_NB];
Line 42... Line 43...
42
namespace Zobrist {
43
namespace Zobrist {
43
 
44
 
44
  Key psq[PIECE_NB][SQUARE_NB];
45
  Key psq[PIECE_NB][SQUARE_NB];
45
  Key enpassant[FILE_NB];
46
  Key enpassant[FILE_NB];
46
  Key castling[CASTLING_RIGHT_NB];
47
  Key castling[CASTLING_RIGHT_NB];
47
  Key side;
48
  Key side, noPawns;
48
}
49
}
49
 
50
 
50
namespace {
51
namespace {
51
 
52
 
52
const string PieceToChar(" PNBRQK  pnbrqk");
53
const string PieceToChar(" PNBRQK  pnbrqk");
53
 
54
 
-
 
55
const Piece Pieces[] = { W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
-
 
56
                         B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING };
-
 
57
 
54
// min_attacker() is a helper function used by see() to locate the least
58
// min_attacker() is a helper function used by see_ge() to locate the least
55
// valuable attacker for the side to move, remove the attacker we just found
59
// valuable attacker for the side to move, remove the attacker we just found
56
// from the bitboards and scan for new X-ray attacks behind it.
60
// from the bitboards and scan for new X-ray attacks behind it.
57
 
61
 
58
template<int Pt>
62
template<int Pt>
59
PieceType min_attacker(const Bitboard* bb, Square to, Bitboard stmAttackers,
63
PieceType min_attacker(const Bitboard* bb, Square to, Bitboard stmAttackers,
60
                       Bitboard& occupied, Bitboard& attackers) {
64
                       Bitboard& occupied, Bitboard& attackers) {
61
 
65
 
62
  Bitboard b = stmAttackers & bb[Pt];
66
  Bitboard b = stmAttackers & bb[Pt];
63
  if (!b)
67
  if (!b)
64
      return min_attacker<Pt+1>(bb, to, stmAttackers, occupied, attackers);
68
      return min_attacker<Pt + 1>(bb, to, stmAttackers, occupied, attackers);
65
 
69
 
66
  occupied ^= b & ~(b - 1);
70
  occupied ^= b & ~(b - 1);
67
 
71
 
68
  if (Pt == PAWN || Pt == BISHOP || Pt == QUEEN)
72
  if (Pt == PAWN || Pt == BISHOP || Pt == QUEEN)
69
      attackers |= attacks_bb<BISHOP>(to, occupied) & (bb[BISHOP] | bb[QUEEN]);
73
      attackers |= attacks_bb<BISHOP>(to, occupied) & (bb[BISHOP] | bb[QUEEN]);
Line 96... Line 100...
96
 
100
 
97
      os << " |\n +---+---+---+---+---+---+---+---+\n";
101
      os << " |\n +---+---+---+---+---+---+---+---+\n";
98
  }
102
  }
99
 
103
 
100
  os << "\nFen: " << pos.fen() << "\nKey: " << std::hex << std::uppercase
104
  os << "\nFen: " << pos.fen() << "\nKey: " << std::hex << std::uppercase
-
 
105
     << std::setfill('0') << std::setw(16) << pos.key()
101
     << std::setfill('0') << std::setw(16) << pos.key() << std::dec << "\nCheckers: ";
106
     << std::setfill(' ') << std::dec << "\nCheckers: ";
102
 
107
 
103
  for (Bitboard b = pos.checkers(); b; )
108
  for (Bitboard b = pos.checkers(); b; )
104
      os << UCI::square(pop_lsb(&b)) << " ";
109
      os << UCI::square(pop_lsb(&b)) << " ";
-
 
110
 
-
 
111
  if (    int(Tablebases::MaxCardinality) >= popcount(pos.pieces())
-
 
112
      && !pos.can_castle(ANY_CASTLING))
-
 
113
  {
-
 
114
      StateInfo st;
-
 
115
      Position p;
-
 
116
      p.set(pos.fen(), pos.is_chess960(), &st, pos.this_thread());
-
 
117
      Tablebases::ProbeState s1, s2;
-
 
118
      Tablebases::WDLScore wdl = Tablebases::probe_wdl(p, &s1);
-
 
119
      int dtz = Tablebases::probe_dtz(p, &s2);
-
 
120
      os << "\nTablebases WDL: " << std::setw(4) << wdl << " (" << s1 << ")"
-
 
121
         << "\nTablebases DTZ: " << std::setw(4) << dtz << " (" << s2 << ")";
-
 
122
  }
105
 
123
 
106
  return os;
124
  return os;
107
}
125
}
108
 
126
 
109
 
127
 
Line 131... Line 149...
131
          Zobrist::castling[cr] ^= k ? k : rng.rand<Key>();
149
          Zobrist::castling[cr] ^= k ? k : rng.rand<Key>();
132
      }
150
      }
133
  }
151
  }
134
 
152
 
135
  Zobrist::side = rng.rand<Key>();
153
  Zobrist::side = rng.rand<Key>();
-
 
154
  Zobrist::noPawns = rng.rand<Key>();
136
}
155
}
137
 
156
 
138
 
157
 
139
/// Position::set() initializes the position object with the given FEN string.
158
/// Position::set() initializes the position object with the given FEN string.
140
/// This function is not very robust - make sure that input FENs are correct,
159
/// This function is not very robust - make sure that input FENs are correct,
Line 162... Line 181...
162
      can castle queenside), "k" (Black can castle kingside), and/or "q" (Black
181
      can castle queenside), "k" (Black can castle kingside), and/or "q" (Black
163
      can castle queenside).
182
      can castle queenside).
164
 
183
 
165
   4) En passant target square (in algebraic notation). If there's no en passant
184
   4) En passant target square (in algebraic notation). If there's no en passant
166
      target square, this is "-". If a pawn has just made a 2-square move, this
185
      target square, this is "-". If a pawn has just made a 2-square move, this
167
      is the position "behind" the pawn. This is recorded regardless of whether
186
      is the position "behind" the pawn. This is recorded only if there is a pawn
168
      there is a pawn in position to make an en passant capture.
187
      in position to make an en passant capture, and if there really is a pawn
-
 
188
      that might have advanced two squares.
169
 
189
 
170
   5) Halfmove clock. This is the number of halfmoves since the last pawn advance
190
   5) Halfmove clock. This is the number of halfmoves since the last pawn advance
171
      or capture. This is used to determine if a draw can be claimed under the
191
      or capture. This is used to determine if a draw can be claimed under the
172
      fifty-move rule.
192
      fifty-move rule.
173
 
193
 
Line 189... Line 209...
189
 
209
 
190
  // 1. Piece placement
210
  // 1. Piece placement
191
  while ((ss >> token) && !isspace(token))
211
  while ((ss >> token) && !isspace(token))
192
  {
212
  {
193
      if (isdigit(token))
213
      if (isdigit(token))
194
          sq += Square(token - '0'); // Advance the given number of files
214
          sq += (token - '0') * EAST; // Advance the given number of files
195
 
215
 
196
      else if (token == '/')
216
      else if (token == '/')
197
          sq -= Square(16);
217
          sq += 2 * SOUTH;
198
 
218
 
199
      else if ((idx = PieceToChar.find(token)) != string::npos)
219
      else if ((idx = PieceToChar.find(token)) != string::npos)
200
      {
220
      {
201
          put_piece(Piece(idx), sq);
221
          put_piece(Piece(idx), sq);
202
          ++sq;
222
          ++sq;
Line 240... Line 260...
240
  if (   ((ss >> col) && (col >= 'a' && col <= 'h'))
260
  if (   ((ss >> col) && (col >= 'a' && col <= 'h'))
241
      && ((ss >> row) && (row == '3' || row == '6')))
261
      && ((ss >> row) && (row == '3' || row == '6')))
242
  {
262
  {
243
      st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
263
      st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
244
 
264
 
245
      if (!(attackers_to(st->epSquare) & pieces(sideToMove, PAWN)))
265
      if (   !(attackers_to(st->epSquare) & pieces(sideToMove, PAWN))
-
 
266
          || !(pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove))))
246
          st->epSquare = SQ_NONE;
267
          st->epSquare = SQ_NONE;
247
  }
268
  }
248
  else
269
  else
249
      st->epSquare = SQ_NONE;
270
      st->epSquare = SQ_NONE;
250
 
271
 
251
  // 5-6. Halfmove clock and fullmove number
272
  // 5-6. Halfmove clock and fullmove number
252
  ss >> std::skipws >> st->rule50 >> gamePly;
273
  ss >> std::skipws >> st->rule50 >> gamePly;
253
 
274
 
254
  // Convert from fullmove starting from 1 to ply starting from 0,
275
  // Convert from fullmove starting from 1 to gamePly starting from 0,
255
  // handle also common incorrect FEN with fullmove = 0.
276
  // handle also common incorrect FEN with fullmove = 0.
256
  gamePly = std::max(2 * (gamePly - 1), 0) + (sideToMove == BLACK);
277
  gamePly = std::max(2 * (gamePly - 1), 0) + (sideToMove == BLACK);
257
 
278
 
258
  chess960 = isChess960;
279
  chess960 = isChess960;
259
  thisThread = th;
280
  thisThread = th;
Line 315... Line 336...
315
/// The function is only used when a new position is set up, and to verify
336
/// The function is only used when a new position is set up, and to verify
316
/// the correctness of the StateInfo data when running in debug mode.
337
/// the correctness of the StateInfo data when running in debug mode.
317
 
338
 
318
void Position::set_state(StateInfo* si) const {
339
void Position::set_state(StateInfo* si) const {
319
 
340
 
320
  si->key = si->pawnKey = si->materialKey = 0;
341
  si->key = si->materialKey = 0;
-
 
342
  si->pawnKey = Zobrist::noPawns;
321
  si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO;
343
  si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO;
322
  si->psq = SCORE_ZERO;
344
  si->psq = SCORE_ZERO;
323
  si->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
345
  si->checkersBB = attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove);
324
 
346
 
325
  set_check_info(si);
347
  set_check_info(si);
Line 352... Line 374...
352
          si->nonPawnMaterial[color_of(pc)] += pieceCount[pc] * PieceValue[MG][pc];
374
          si->nonPawnMaterial[color_of(pc)] += pieceCount[pc] * PieceValue[MG][pc];
353
 
375
 
354
      for (int cnt = 0; cnt < pieceCount[pc]; ++cnt)
376
      for (int cnt = 0; cnt < pieceCount[pc]; ++cnt)
355
          si->materialKey ^= Zobrist::psq[pc][cnt];
377
          si->materialKey ^= Zobrist::psq[pc][cnt];
356
  }
378
  }
-
 
379
}
-
 
380
 
-
 
381
 
-
 
382
/// Position::set() is an overload to initialize the position object with
-
 
383
/// the given endgame code string like "KBPKN". It is mainly a helper to
-
 
384
/// get the material key out of an endgame code.
-
 
385
 
-
 
386
Position& Position::set(const string& code, Color c, StateInfo* si) {
-
 
387
 
-
 
388
  assert(code.length() > 0 && code.length() < 8);
-
 
389
  assert(code[0] == 'K');
-
 
390
 
-
 
391
  string sides[] = { code.substr(code.find('K', 1)),      // Weak
-
 
392
                     code.substr(0, code.find('K', 1)) }; // Strong
-
 
393
 
-
 
394
  std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
-
 
395
 
-
 
396
  string fenStr = "8/" + sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/"
-
 
397
                       + sides[1] + char(8 - sides[1].length() + '0') + "/8 w - - 0 10";
-
 
398
 
-
 
399
  return set(fenStr, false, si, nullptr);
357
}
400
}
358
 
401
 
359
 
402
 
360
/// Position::fen() returns a FEN representation of the position. In case of
403
/// Position::fen() returns a FEN representation of the position. In case of
361
/// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
404
/// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
Line 402... Line 445...
402
 
445
 
403
  ss << (ep_square() == SQ_NONE ? " - " : " " + UCI::square(ep_square()) + " ")
446
  ss << (ep_square() == SQ_NONE ? " - " : " " + UCI::square(ep_square()) + " ")
404
     << st->rule50 << " " << 1 + (gamePly - (sideToMove == BLACK)) / 2;
447
     << st->rule50 << " " << 1 + (gamePly - (sideToMove == BLACK)) / 2;
405
 
448
 
406
  return ss.str();
449
  return ss.str();
407
}
-
 
408
 
-
 
409
 
-
 
410
/// Position::game_phase() calculates the game phase interpolating total non-pawn
-
 
411
/// material between endgame and midgame limits.
-
 
412
 
-
 
413
Phase Position::game_phase() const {
-
 
414
 
-
 
415
  Value npm = st->nonPawnMaterial[WHITE] + st->nonPawnMaterial[BLACK];
-
 
416
 
-
 
417
  npm = std::max(EndgameLimit, std::min(npm, MidgameLimit));
-
 
418
 
-
 
419
  return Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
-
 
420
}
450
}
421
 
451
 
422
 
452
 
423
/// Position::slider_blockers() returns a bitboard of all the pieces (both colors)
453
/// Position::slider_blockers() returns a bitboard of all the pieces (both colors)
424
/// that are blocking attacks on the square 's' from 'sliders'. A piece blocks a
454
/// that are blocking attacks on the square 's' from 'sliders'. A piece blocks a
Line 431... Line 461...
431
 
461
 
432
  Bitboard result = 0;
462
  Bitboard result = 0;
433
  pinners = 0;
463
  pinners = 0;
434
 
464
 
435
  // Snipers are sliders that attack 's' when a piece is removed
465
  // Snipers are sliders that attack 's' when a piece is removed
436
  Bitboard snipers = (  (PseudoAttacks[ROOK  ][s] & pieces(QUEEN, ROOK))
466
  Bitboard snipers = (  (PseudoAttacks[  ROOK][s] & pieces(QUEEN, ROOK))
437
                      | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
467
                      | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
438
 
468
 
439
  while (snipers)
469
  while (snipers)
440
  {
470
  {
441
    Square sniperSq = pop_lsb(&snipers);
471
    Square sniperSq = pop_lsb(&snipers);
Line 458... Line 488...
458
Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
488
Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
459
 
489
 
460
  return  (attacks_from<PAWN>(s, BLACK)    & pieces(WHITE, PAWN))
490
  return  (attacks_from<PAWN>(s, BLACK)    & pieces(WHITE, PAWN))
461
        | (attacks_from<PAWN>(s, WHITE)    & pieces(BLACK, PAWN))
491
        | (attacks_from<PAWN>(s, WHITE)    & pieces(BLACK, PAWN))
462
        | (attacks_from<KNIGHT>(s)         & pieces(KNIGHT))
492
        | (attacks_from<KNIGHT>(s)         & pieces(KNIGHT))
463
        | (attacks_bb<ROOK  >(s, occupied) & pieces(ROOK,   QUEEN))
493
        | (attacks_bb<  ROOK>(s, occupied) & pieces(  ROOK, QUEEN))
464
        | (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
494
        | (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
465
        | (attacks_from<KING>(s)           & pieces(KING));
495
        | (attacks_from<KING>(s)           & pieces(KING));
466
}
496
}
467
 
497
 
468
 
498
 
Line 552... Line 582...
552
               && (rank_of(from) == relative_rank(us, RANK_2))
582
               && (rank_of(from) == relative_rank(us, RANK_2))
553
               && empty(to)
583
               && empty(to)
554
               && empty(to - pawn_push(us))))
584
               && empty(to - pawn_push(us))))
555
          return false;
585
          return false;
556
  }
586
  }
557
  else if (!(attacks_from(pc, from) & to))
587
  else if (!(attacks_from(type_of(pc), from) & to))
558
      return false;
588
      return false;
559
 
589
 
560
  // Evasions generator already takes care to avoid some kind of illegal moves
590
  // Evasions generator already takes care to avoid some kind of illegal moves
561
  // and legal() relies on this. We therefore have to take care that the same
591
  // and legal() relies on this. We therefore have to take care that the same
562
  // kind of moves are filtered out here.
592
  // kind of moves are filtered out here.
Line 605... Line 635...
605
  {
635
  {
606
  case NORMAL:
636
  case NORMAL:
607
      return false;
637
      return false;
608
 
638
 
609
  case PROMOTION:
639
  case PROMOTION:
610
      return attacks_bb(Piece(promotion_type(m)), to, pieces() ^ from) & square<KING>(~sideToMove);
640
      return attacks_bb(promotion_type(m), to, pieces() ^ from) & square<KING>(~sideToMove);
611
 
641
 
612
  // En passant capture with check? We have already handled the case
642
  // En passant capture with check? We have already handled the case
613
  // of direct checks and ordinary discovered check, so the only case we
643
  // of direct checks and ordinary discovered check, so the only case we
614
  // need to handle is the unusual case of a discovered check through
644
  // need to handle is the unusual case of a discovered check through
615
  // the captured pawn.
645
  // the captured pawn.
Line 645... Line 675...
645
void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
675
void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
646
 
676
 
647
  assert(is_ok(m));
677
  assert(is_ok(m));
648
  assert(&newSt != st);
678
  assert(&newSt != st);
649
 
679
 
650
  ++nodes;
680
  thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
651
  Key k = st->key ^ Zobrist::side;
681
  Key k = st->key ^ Zobrist::side;
652
 
682
 
653
  // Copy some fields of the old state to our new StateInfo object except the
683
  // Copy some fields of the old state to our new StateInfo object except the
654
  // ones which are going to be recalculated from scratch anyway and then switch
684
  // ones which are going to be recalculated from scratch anyway and then switch
655
  // our state pointer to point to the new (ready to be updated) state.
685
  // our state pointer to point to the new (ready to be updated) state.
Line 755... Line 785...
755
  {
785
  {
756
      // Set en-passant square if the moved pawn can be captured
786
      // Set en-passant square if the moved pawn can be captured
757
      if (   (int(to) ^ int(from)) == 16
787
      if (   (int(to) ^ int(from)) == 16
758
          && (attacks_from<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN)))
788
          && (attacks_from<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN)))
759
      {
789
      {
760
          st->epSquare = (from + to) / 2;
790
          st->epSquare = to - pawn_push(us);
761
          k ^= Zobrist::enpassant[file_of(st->epSquare)];
791
          k ^= Zobrist::enpassant[file_of(st->epSquare)];
762
      }
792
      }
763
 
793
 
764
      else if (type_of(m) == PROMOTION)
794
      else if (type_of(m) == PROMOTION)
765
      {
795
      {
Line 784... Line 814...
784
          st->nonPawnMaterial[us] += PieceValue[MG][promotion];
814
          st->nonPawnMaterial[us] += PieceValue[MG][promotion];
785
      }
815
      }
786
 
816
 
787
      // Update pawn hash key and prefetch access to pawnsTable
817
      // Update pawn hash key and prefetch access to pawnsTable
788
      st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
818
      st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
789
      prefetch(thisThread->pawnsTable[st->pawnKey]);
819
      prefetch2(thisThread->pawnsTable[st->pawnKey]);
790
 
820
 
791
      // Reset rule 50 draw counter
821
      // Reset rule 50 draw counter
792
      st->rule50 = 0;
822
      st->rule50 = 0;
793
  }
823
  }
794
 
824
 
Line 954... Line 984...
954
  return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
984
  return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
955
}
985
}
956
 
986
 
957
 
987
 
958
/// Position::see_ge (Static Exchange Evaluation Greater or Equal) tests if the
988
/// Position::see_ge (Static Exchange Evaluation Greater or Equal) tests if the
959
/// SEE value of move is greater or equal to the given value. We'll use an
989
/// SEE value of move is greater or equal to the given threshold. We'll use an
960
/// algorithm similar to alpha-beta pruning with a null window.
990
/// algorithm similar to alpha-beta pruning with a null window.
961
 
991
 
962
bool Position::see_ge(Move m, Value v) const {
992
bool Position::see_ge(Move m, Value threshold) const {
963
 
993
 
964
  assert(is_ok(m));
994
  assert(is_ok(m));
965
 
995
 
966
  // Castling moves are implemented as king capturing the rook so cannot be
-
 
967
  // handled correctly. Simply assume the SEE value is VALUE_ZERO that is always
-
 
968
  // correct unless in the rare case the rook ends up under attack.
996
  // Only deal with normal moves, assume others pass a simple see
969
  if (type_of(m) == CASTLING)
997
  if (type_of(m) != NORMAL)
970
      return VALUE_ZERO >= v;
998
      return VALUE_ZERO >= threshold;
971
 
999
 
972
  Square from = from_sq(m), to = to_sq(m);
1000
  Square from = from_sq(m), to = to_sq(m);
973
  PieceType nextVictim = type_of(piece_on(from));
1001
  PieceType nextVictim = type_of(piece_on(from));
974
  Color stm = ~color_of(piece_on(from)); // First consider opponent's move
1002
  Color stm = ~color_of(piece_on(from)); // First consider opponent's move
975
  Value balance; // Values of the pieces taken by us minus opponent's ones
1003
  Value balance; // Values of the pieces taken by us minus opponent's ones
976
  Bitboard occupied, stmAttackers;
1004
  Bitboard occupied, stmAttackers;
977
 
1005
 
978
  if (type_of(m) == ENPASSANT)
-
 
979
  {
-
 
980
      occupied = SquareBB[to - pawn_push(~stm)]; // Remove the captured pawn
1006
  // The opponent may be able to recapture so this is the best result
981
      balance = PieceValue[MG][PAWN];
1007
  // we can hope for.
982
  }
-
 
983
  else
-
 
984
  {
-
 
985
      balance = PieceValue[MG][piece_on(to)];
1008
  balance = PieceValue[MG][piece_on(to)] - threshold;
986
      occupied = 0;
-
 
987
  }
-
 
988
 
1009
 
989
  if (balance < v)
1010
  if (balance < VALUE_ZERO)
990
      return false;
1011
      return false;
991
 
1012
 
992
  if (nextVictim == KING)
1013
  // Now assume the worst possible result: that the opponent can
993
      return true;
1014
  // capture our piece for free.
994
 
-
 
995
  balance -= PieceValue[MG][nextVictim];
1015
  balance -= PieceValue[MG][nextVictim];
996
 
1016
 
997
  if (balance >= v)
1017
  if (balance >= VALUE_ZERO) // Always true if nextVictim == KING
998
      return true;
1018
      return true;
999
 
1019
 
1000
  bool relativeStm = true; // True if the opponent is to move
1020
  bool opponentToMove = true;
1001
  occupied ^= pieces() ^ from ^ to;
1021
  occupied = pieces() ^ from ^ to;
1002
 
1022
 
1003
  // Find all attackers to the destination square, with the moving piece removed,
1023
  // Find all attackers to the destination square, with the moving piece removed,
1004
  // but possibly an X-ray attacker added behind it.
1024
  // but possibly an X-ray attacker added behind it.
1005
  Bitboard attackers = attackers_to(to, occupied) & occupied;
1025
  Bitboard attackers = attackers_to(to, occupied) & occupied;
1006
 
1026
 
1007
  while (true)
1027
  while (true)
1008
  {
1028
  {
-
 
1029
      // The balance is negative only because we assumed we could win
-
 
1030
      // the last piece for free. We are truly winning only if we can
-
 
1031
      // win the last piece _cheaply enough_. Test if we can actually
-
 
1032
      // do this otherwise "give up".
-
 
1033
      assert(balance < VALUE_ZERO);
-
 
1034
 
1009
      stmAttackers = attackers & pieces(stm);
1035
      stmAttackers = attackers & pieces(stm);
1010
 
1036
 
1011
      // Don't allow pinned pieces to attack pieces except the king as long all
1037
      // Don't allow pinned pieces to attack pieces except the king as long all
1012
      // pinners are on their original square.
1038
      // pinners are on their original square.
1013
      if (!(st->pinnersForKing[stm] & ~occupied))
1039
      if (!(st->pinnersForKing[stm] & ~occupied))
1014
          stmAttackers &= ~st->blockersForKing[stm];
1040
          stmAttackers &= ~st->blockersForKing[stm];
1015
 
1041
 
-
 
1042
      // If we have no more attackers we must give up
1016
      if (!stmAttackers)
1043
      if (!stmAttackers)
1017
          return relativeStm;
1044
          break;
1018
 
1045
 
1019
      // Locate and remove the next least valuable attacker
1046
      // Locate and remove the next least valuable attacker
1020
      nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
1047
      nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
1021
 
1048
 
1022
      if (nextVictim == KING)
1049
      if (nextVictim == KING)
-
 
1050
      {
-
 
1051
          // Our only attacker is the king. If the opponent still has
-
 
1052
          // attackers we must give up. Otherwise we make the move and
-
 
1053
          // (having no more attackers) the opponent must give up.
1023
          return relativeStm == bool(attackers & pieces(~stm));
1054
          if (!(attackers & pieces(~stm)))
-
 
1055
              opponentToMove = !opponentToMove;
-
 
1056
          break;
-
 
1057
      }
1024
 
1058
 
-
 
1059
      // Assume the opponent can win the next piece for free and switch sides
1025
      balance += relativeStm ?  PieceValue[MG][nextVictim]
1060
      balance += PieceValue[MG][nextVictim];
1026
                             : -PieceValue[MG][nextVictim];
1061
      opponentToMove = !opponentToMove;
1027
 
1062
 
1028
      relativeStm = !relativeStm;
1063
      // If balance is negative after receiving a free piece then give up
1029
 
-
 
1030
      if (relativeStm == (balance >= v))
1064
      if (balance < VALUE_ZERO)
1031
          return relativeStm;
1065
          break;
1032
 
1066
 
-
 
1067
      // Complete the process of switching sides. The first line swaps
-
 
1068
      // all negative numbers with non-negative numbers. The compiler
-
 
1069
      // probably knows that it is just the bitwise negation ~balance.
-
 
1070
      balance = -balance-1;
1033
      stm = ~stm;
1071
      stm = ~stm;
1034
  }
1072
  }
-
 
1073
 
-
 
1074
  // If the opponent gave up we win, otherwise we lose.
-
 
1075
  return opponentToMove;
1035
}
1076
}
1036
 
1077
 
1037
 
1078
 
1038
/// Position::is_draw() tests whether the position is drawn by 50-move rule
1079
/// Position::is_draw() tests whether the position is drawn by 50-move rule
1039
/// or by repetition. It does not detect stalemates.
1080
/// or by repetition. It does not detect stalemates.
1040
 
1081
 
1041
bool Position::is_draw() const {
1082
bool Position::is_draw(int ply) const {
1042
 
1083
 
1043
  if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
1084
  if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
1044
      return true;
1085
      return true;
1045
 
1086
 
-
 
1087
  int end = std::min(st->rule50, st->pliesFromNull);
-
 
1088
 
-
 
1089
  if (end < 4)
-
 
1090
    return false;
-
 
1091
 
1046
  StateInfo* stp = st;
1092
  StateInfo* stp = st->previous->previous;
-
 
1093
  int cnt = 0;
-
 
1094
 
1047
  for (int i = 2, e = std::min(st->rule50, st->pliesFromNull); i <= e; i += 2)
1095
  for (int i = 4; i <= end; i += 2)
1048
  {
1096
  {
1049
      stp = stp->previous->previous;
1097
      stp = stp->previous->previous;
1050
 
1098
 
-
 
1099
      // Return a draw score if a position repeats once earlier but strictly
-
 
1100
      // after the root, or repeats twice before or at the root.
1051
      if (stp->key == st->key)
1101
      if (   stp->key == st->key
1052
          return true; // Draw at first repetition
1102
          && ++cnt + (ply > i) == 2)
-
 
1103
          return true;
1053
  }
1104
  }
1054
 
1105
 
1055
  return false;
1106
  return false;
1056
}
1107
}
1057
 
1108
 
Line 1089... Line 1140...
1089
 
1140
 
1090
  assert(pos_is_ok());
1141
  assert(pos_is_ok());
1091
}
1142
}
1092
 
1143
 
1093
 
1144
 
1094
/// Position::pos_is_ok() performs some consistency checks for the position object.
1145
/// Position::pos_is_ok() performs some consistency checks for the
-
 
1146
/// position object and raises an asserts if something wrong is detected.
1095
/// This is meant to be helpful when debugging.
1147
/// This is meant to be helpful when debugging.
1096
 
1148
 
1097
bool Position::pos_is_ok(int* failedStep) const {
1149
bool Position::pos_is_ok() const {
1098
 
1150
 
1099
  const bool Fast = true; // Quick (default) or full check?
1151
  const bool Fast = true; // Quick (default) or full check?
1100
 
1152
 
-
 
1153
  if (   (sideToMove != WHITE && sideToMove != BLACK)
-
 
1154
      || piece_on(square<KING>(WHITE)) != W_KING
-
 
1155
      || piece_on(square<KING>(BLACK)) != B_KING
-
 
1156
      || (   ep_square() != SQ_NONE
1101
  enum { Default, King, Bitboards, State, Lists, Castling };
1157
          && relative_rank(sideToMove, ep_square()) != RANK_6))
-
 
1158
      assert(0 && "pos_is_ok: Default");
1102
 
1159
 
1103
  for (int step = Default; step <= (Fast ? Default : Castling); step++)
-
 
1104
  {
-
 
1105
      if (failedStep)
1160
  if (Fast)
1106
          *failedStep = step;
1161
      return true;
1107
 
1162
 
1108
      if (step == Default)
-
 
1109
          if (   (sideToMove != WHITE && sideToMove != BLACK)
-
 
1110
              || piece_on(square<KING>(WHITE)) != W_KING
1163
  if (   pieceCount[W_KING] != 1
1111
              || piece_on(square<KING>(BLACK)) != B_KING
1164
      || pieceCount[B_KING] != 1
1112
              || (   ep_square() != SQ_NONE
-
 
1113
                  && relative_rank(sideToMove, ep_square()) != RANK_6))
1165
      || attackers_to(square<KING>(~sideToMove)) & pieces(sideToMove))
1114
              return false;
1166
      assert(0 && "pos_is_ok: Kings");
1115
 
1167
 
1116
      if (step == King)
1168
  if (   (pieces(PAWN) & (Rank1BB | Rank8BB))
1117
          if (   std::count(board, board + SQUARE_NB, W_KING) != 1
1169
      || pieceCount[W_PAWN] > 8
1118
              || std::count(board, board + SQUARE_NB, B_KING) != 1
1170
      || pieceCount[B_PAWN] > 8)
1119
              || attackers_to(square<KING>(~sideToMove)) & pieces(sideToMove))
-
 
1120
              return false;
1171
      assert(0 && "pos_is_ok: Pawns");
1121
 
1172
 
1122
      if (step == Bitboards)
1173
  if (   (pieces(WHITE) & pieces(BLACK))
1123
      {
-
 
1124
          if (  (pieces(WHITE) & pieces(BLACK))
1174
      || (pieces(WHITE) | pieces(BLACK)) != pieces()
-
 
1175
      || popcount(pieces(WHITE)) > 16
1125
              ||(pieces(WHITE) | pieces(BLACK)) != pieces())
1176
      || popcount(pieces(BLACK)) > 16)
1126
              return false;
1177
      assert(0 && "pos_is_ok: Bitboards");
1127
 
1178
 
1128
          for (PieceType p1 = PAWN; p1 <= KING; ++p1)
1179
  for (PieceType p1 = PAWN; p1 <= KING; ++p1)
1129
              for (PieceType p2 = PAWN; p2 <= KING; ++p2)
1180
      for (PieceType p2 = PAWN; p2 <= KING; ++p2)
1130
                  if (p1 != p2 && (pieces(p1) & pieces(p2)))
1181
          if (p1 != p2 && (pieces(p1) & pieces(p2)))
1131
                      return false;
1182
              assert(0 && "pos_is_ok: Bitboards");
1132
      }
-
 
1133
 
1183
 
1134
      if (step == State)
-
 
1135
      {
-
 
1136
          StateInfo si = *st;
1184
  StateInfo si = *st;
1137
          set_state(&si);
1185
  set_state(&si);
1138
          if (std::memcmp(&si, st, sizeof(StateInfo)))
1186
  if (std::memcmp(&si, st, sizeof(StateInfo)))
1139
              return false;
1187
      assert(0 && "pos_is_ok: State");
1140
      }
-
 
1141
 
1188
 
1142
      if (step == Lists)
-
 
1143
          for (Piece pc : Pieces)
1189
  for (Piece pc : Pieces)
1144
          {
1190
  {
1145
              if (pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc))))
1191
      if (   pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc)))
-
 
1192
          || pieceCount[pc] != std::count(board, board + SQUARE_NB, pc))
1146
                  return false;
1193
          assert(0 && "pos_is_ok: Pieces");
1147
 
1194
 
1148
              for (int i = 0; i < pieceCount[pc]; ++i)
1195
      for (int i = 0; i < pieceCount[pc]; ++i)
1149
                  if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
1196
          if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
1150
                      return false;
1197
              assert(0 && "pos_is_ok: Index");
1151
          }
1198
  }
1152
 
1199
 
1153
      if (step == Castling)
-
 
1154
          for (Color c = WHITE; c <= BLACK; ++c)
1200
  for (Color c = WHITE; c <= BLACK; ++c)
1155
              for (CastlingSide s = KING_SIDE; s <= QUEEN_SIDE; s = CastlingSide(s + 1))
1201
      for (CastlingSide s = KING_SIDE; s <= QUEEN_SIDE; s = CastlingSide(s + 1))
1156
              {
1202
      {
1157
                  if (!can_castle(c | s))
1203
          if (!can_castle(c | s))
1158
                      continue;
1204
              continue;
1159
 
1205
 
1160
                  if (   piece_on(castlingRookSquare[c | s]) != make_piece(c, ROOK)
1206
          if (   piece_on(castlingRookSquare[c | s]) != make_piece(c, ROOK)
1161
                      || castlingRightsMask[castlingRookSquare[c | s]] != (c | s)
1207
              || castlingRightsMask[castlingRookSquare[c | s]] != (c | s)
1162
                      ||(castlingRightsMask[square<KING>(c)] & (c | s)) != (c | s))
1208
              || (castlingRightsMask[square<KING>(c)] & (c | s)) != (c | s))
1163
                      return false;
1209
              assert(0 && "pos_is_ok: Castling");
1164
              }
-
 
1165
  }
1210
      }
1166
 
1211
 
1167
  return true;
1212
  return true;
1168
}
1213
}