Subversion Repositories Games.Chess Giants

Rev

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

Rev 96 Rev 154
Line 20... Line 20...
20
 
20
 
21
#ifndef POSITION_H_INCLUDED
21
#ifndef POSITION_H_INCLUDED
22
#define POSITION_H_INCLUDED
22
#define POSITION_H_INCLUDED
23
 
23
 
24
#include <cassert>
24
#include <cassert>
-
 
25
#include <deque>
25
#include <cstddef>  // For offsetof()
26
#include <memory> // For std::unique_ptr
26
#include <string>
27
#include <string>
27
 
28
 
28
#include "bitboard.h"
29
#include "bitboard.h"
29
#include "types.h"
30
#include "types.h"
30
 
-
 
31
class Position;
-
 
32
class Thread;
-
 
33
 
-
 
34
namespace PSQT {
-
 
35
 
-
 
36
  extern Score psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
-
 
37
 
-
 
38
  void init();
-
 
39
}
-
 
40
 
-
 
41
/// CheckInfo struct is initialized at constructor time and keeps info used to
-
 
42
/// detect if a move gives check.
-
 
43
 
-
 
44
struct CheckInfo {
-
 
45
 
-
 
46
  explicit CheckInfo(const Position&);
-
 
47
 
-
 
48
  Bitboard dcCandidates;
-
 
49
  Bitboard pinned;
-
 
50
  Bitboard checkSquares[PIECE_TYPE_NB];
-
 
51
  Square   ksq;
-
 
52
};
-
 
53
 
31
 
54
 
32
 
55
/// StateInfo struct stores information needed to restore a Position object to
33
/// StateInfo struct stores information needed to restore a Position object to
56
/// its previous state when we retract a move. Whenever a move is made on the
34
/// its previous state when we retract a move. Whenever a move is made on the
57
/// board (by calling Position::do_move), a StateInfo object must be passed.
35
/// board (by calling Position::do_move), a StateInfo object must be passed.
Line 66... Line 44...
66
  int    rule50;
44
  int    rule50;
67
  int    pliesFromNull;
45
  int    pliesFromNull;
68
  Score  psq;
46
  Score  psq;
69
  Square epSquare;
47
  Square epSquare;
70
 
48
 
71
  // Not copied when making a move
49
  // Not copied when making a move (will be recomputed anyhow)
72
  Key        key;
50
  Key        key;
73
  Bitboard   checkersBB;
51
  Bitboard   checkersBB;
74
  PieceType  capturedType;
52
  Piece      capturedPiece;
75
  StateInfo* previous;
53
  StateInfo* previous;
-
 
54
  Bitboard   blockersForKing[COLOR_NB];
-
 
55
  Bitboard   pinnersForKing[COLOR_NB];
-
 
56
  Bitboard   checkSquares[PIECE_TYPE_NB];
76
};
57
};
77
 
58
 
-
 
59
// In a std::deque references to elements are unaffected upon resizing
-
 
60
typedef std::unique_ptr<std::deque<StateInfo>> StateListPtr;
-
 
61
 
78
 
62
 
79
/// Position class stores information regarding the board representation as
63
/// Position class stores information regarding the board representation as
80
/// pieces, side to move, hash keys, castling info, etc. Important methods are
64
/// pieces, side to move, hash keys, castling info, etc. Important methods are
81
/// do_move() and undo_move(), used by the search to update node info when
65
/// do_move() and undo_move(), used by the search to update node info when
82
/// traversing the search tree.
66
/// traversing the search tree.
-
 
67
class Thread;
83
 
68
 
84
class Position {
69
class Position {
85
 
-
 
86
public:
70
public:
87
  static void init();
71
  static void init();
88
 
72
 
89
  Position() = default; // To define the global object RootPos
73
  Position() = default;
90
  Position(const Position&) = delete;
74
  Position(const Position&) = delete;
91
  Position(const Position& pos, Thread* th) { *this = pos; thisThread = th; }
-
 
92
  Position(const std::string& f, bool c960, Thread* th) { set(f, c960, th); }
-
 
93
  Position& operator=(const Position&); // To assign RootPos from UCI
75
  Position& operator=(const Position&) = delete;
94
 
76
 
95
  // FEN string input/output
77
  // FEN string input/output
96
  void set(const std::string& fenStr, bool isChess960, Thread* th);
78
  Position& set(const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th);
97
  const std::string fen() const;
79
  const std::string fen() const;
98
 
80
 
99
  // Position representation
81
  // Position representation
100
  Bitboard pieces() const;
82
  Bitboard pieces() const;
101
  Bitboard pieces(PieceType pt) const;
83
  Bitboard pieces(PieceType pt) const;
Line 118... Line 100...
118
 
100
 
119
  // Checking
101
  // Checking
120
  Bitboard checkers() const;
102
  Bitboard checkers() const;
121
  Bitboard discovered_check_candidates() const;
103
  Bitboard discovered_check_candidates() const;
122
  Bitboard pinned_pieces(Color c) const;
104
  Bitboard pinned_pieces(Color c) const;
-
 
105
  Bitboard check_squares(PieceType pt) const;
123
 
106
 
124
  // Attacks to/from a given square
107
  // Attacks to/from a given square
125
  Bitboard attackers_to(Square s) const;
108
  Bitboard attackers_to(Square s) const;
126
  Bitboard attackers_to(Square s, Bitboard occupied) const;
109
  Bitboard attackers_to(Square s, Bitboard occupied) const;
127
  Bitboard attacks_from(Piece pc, Square s) const;
110
  Bitboard attacks_from(Piece pc, Square s) const;
128
  template<PieceType> Bitboard attacks_from(Square s) const;
111
  template<PieceType> Bitboard attacks_from(Square s) const;
129
  template<PieceType> Bitboard attacks_from(Square s, Color c) const;
112
  template<PieceType> Bitboard attacks_from(Square s, Color c) const;
-
 
113
  Bitboard slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const;
130
 
114
 
131
  // Properties of moves
115
  // Properties of moves
132
  bool legal(Move m, Bitboard pinned) const;
116
  bool legal(Move m) const;
133
  bool pseudo_legal(const Move m) const;
117
  bool pseudo_legal(const Move m) const;
134
  bool capture(Move m) const;
118
  bool capture(Move m) const;
135
  bool capture_or_promotion(Move m) const;
119
  bool capture_or_promotion(Move m) const;
136
  bool gives_check(Move m, const CheckInfo& ci) const;
120
  bool gives_check(Move m) const;
137
  bool advanced_pawn_push(Move m) const;
121
  bool advanced_pawn_push(Move m) const;
138
  Piece moved_piece(Move m) const;
122
  Piece moved_piece(Move m) const;
139
  PieceType captured_piece_type() const;
123
  Piece captured_piece() const;
140
 
124
 
141
  // Piece specific
125
  // Piece specific
142
  bool pawn_passed(Color c, Square s) const;
126
  bool pawn_passed(Color c, Square s) const;
143
  bool opposite_bishops() const;
127
  bool opposite_bishops() const;
144
 
128
 
Line 146... Line 130...
146
  void do_move(Move m, StateInfo& st, bool givesCheck);
130
  void do_move(Move m, StateInfo& st, bool givesCheck);
147
  void undo_move(Move m);
131
  void undo_move(Move m);
148
  void do_null_move(StateInfo& st);
132
  void do_null_move(StateInfo& st);
149
  void undo_null_move();
133
  void undo_null_move();
150
 
134
 
151
  // Static exchange evaluation
135
  // Static Exchange Evaluation
152
  Value see(Move m) const;
-
 
153
  Value see_sign(Move m) const;
136
  bool see_ge(Move m, Value value) const;
154
 
137
 
155
  // Accessing hash keys
138
  // Accessing hash keys
156
  Key key() const;
139
  Key key() const;
157
  Key key_after(Move m) const;
140
  Key key_after(Move m) const;
158
  Key exclusion_key() const;
-
 
159
  Key material_key() const;
141
  Key material_key() const;
160
  Key pawn_key() const;
142
  Key pawn_key() const;
161
 
143
 
162
  // Other properties of the position
144
  // Other properties of the position
163
  Color side_to_move() const;
145
  Color side_to_move() const;
164
  Phase game_phase() const;
146
  Phase game_phase() const;
165
  int game_ply() const;
147
  int game_ply() const;
166
  bool is_chess960() const;
148
  bool is_chess960() const;
167
  Thread* this_thread() const;
149
  Thread* this_thread() const;
168
  uint64_t nodes_searched() const;
150
  uint64_t nodes_searched() const;
169
  void set_nodes_searched(uint64_t n);
-
 
170
  bool is_draw() const;
151
  bool is_draw() const;
171
  int rule50_count() const;
152
  int rule50_count() const;
172
  Score psq_score() const;
153
  Score psq_score() const;
173
  Value non_pawn_material(Color c) const;
154
  Value non_pawn_material(Color c) const;
174
 
155
 
175
  // Position consistency check, for debugging
156
  // Position consistency check, for debugging
176
  bool pos_is_ok(int* failedStep = nullptr) const;
157
  bool pos_is_ok(int* failedStep = nullptr) const;
177
  void flip();
158
  void flip();
178
 
159
 
179
private:
160
private:
180
  // Initialization helpers (used while setting up a position)
161
  // Initialization helpers (used while setting up a position)
181
  void clear();
-
 
182
  void set_castling_right(Color c, Square rfrom);
162
  void set_castling_right(Color c, Square rfrom);
183
  void set_state(StateInfo* si) const;
163
  void set_state(StateInfo* si) const;
-
 
164
  void set_check_info(StateInfo* si) const;
184
 
165
 
185
  // Other helpers
166
  // Other helpers
186
  Bitboard check_blockers(Color c, Color kingColor) const;
-
 
187
  void put_piece(Color c, PieceType pt, Square s);
167
  void put_piece(Piece pc, Square s);
188
  void remove_piece(Color c, PieceType pt, Square s);
168
  void remove_piece(Piece pc, Square s);
189
  void move_piece(Color c, PieceType pt, Square from, Square to);
169
  void move_piece(Piece pc, Square from, Square to);
190
  template<bool Do>
170
  template<bool Do>
191
  void do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto);
171
  void do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto);
192
 
172
 
193
  // Data members
173
  // Data members
194
  Piece board[SQUARE_NB];
174
  Piece board[SQUARE_NB];
195
  Bitboard byTypeBB[PIECE_TYPE_NB];
175
  Bitboard byTypeBB[PIECE_TYPE_NB];
196
  Bitboard byColorBB[COLOR_NB];
176
  Bitboard byColorBB[COLOR_NB];
197
  int pieceCount[COLOR_NB][PIECE_TYPE_NB];
177
  int pieceCount[PIECE_NB];
198
  Square pieceList[COLOR_NB][PIECE_TYPE_NB][16];
178
  Square pieceList[PIECE_NB][16];
199
  int index[SQUARE_NB];
179
  int index[SQUARE_NB];
200
  int castlingRightsMask[SQUARE_NB];
180
  int castlingRightsMask[SQUARE_NB];
201
  Square castlingRookSquare[CASTLING_RIGHT_NB];
181
  Square castlingRookSquare[CASTLING_RIGHT_NB];
202
  Bitboard castlingPath[CASTLING_RIGHT_NB];
182
  Bitboard castlingPath[CASTLING_RIGHT_NB];
203
  StateInfo startState;
-
 
204
  uint64_t nodes;
183
  uint64_t nodes;
205
  int gamePly;
184
  int gamePly;
206
  Color sideToMove;
185
  Color sideToMove;
207
  Thread* thisThread;
186
  Thread* thisThread;
208
  StateInfo* st;
187
  StateInfo* st;
Line 250... Line 229...
250
inline Bitboard Position::pieces(Color c, PieceType pt1, PieceType pt2) const {
229
inline Bitboard Position::pieces(Color c, PieceType pt1, PieceType pt2) const {
251
  return byColorBB[c] & (byTypeBB[pt1] | byTypeBB[pt2]);
230
  return byColorBB[c] & (byTypeBB[pt1] | byTypeBB[pt2]);
252
}
231
}
253
 
232
 
254
template<PieceType Pt> inline int Position::count(Color c) const {
233
template<PieceType Pt> inline int Position::count(Color c) const {
255
  return pieceCount[c][Pt];
234
  return pieceCount[make_piece(c, Pt)];
256
}
235
}
257
 
236
 
258
template<PieceType Pt> inline const Square* Position::squares(Color c) const {
237
template<PieceType Pt> inline const Square* Position::squares(Color c) const {
259
  return pieceList[c][Pt];
238
  return pieceList[make_piece(c, Pt)];
260
}
239
}
261
 
240
 
262
template<PieceType Pt> inline Square Position::square(Color c) const {
241
template<PieceType Pt> inline Square Position::square(Color c) const {
263
  assert(pieceCount[c][Pt] == 1);
242
  assert(pieceCount[make_piece(c, Pt)] == 1);
264
  return pieceList[c][Pt][0];
243
  return pieceList[make_piece(c, Pt)][0];
265
}
244
}
266
 
245
 
267
inline Square Position::ep_square() const {
246
inline Square Position::ep_square() const {
268
  return st->epSquare;
247
  return st->epSquare;
269
}
248
}
Line 307... Line 286...
307
inline Bitboard Position::checkers() const {
286
inline Bitboard Position::checkers() const {
308
  return st->checkersBB;
287
  return st->checkersBB;
309
}
288
}
310
 
289
 
311
inline Bitboard Position::discovered_check_candidates() const {
290
inline Bitboard Position::discovered_check_candidates() const {
312
  return check_blockers(sideToMove, ~sideToMove);
291
  return st->blockersForKing[~sideToMove] & pieces(sideToMove);
313
}
292
}
314
 
293
 
315
inline Bitboard Position::pinned_pieces(Color c) const {
294
inline Bitboard Position::pinned_pieces(Color c) const {
-
 
295
  return st->blockersForKing[c] & pieces(c);
-
 
296
}
-
 
297
 
-
 
298
inline Bitboard Position::check_squares(PieceType pt) const {
316
  return check_blockers(c, c);
299
  return st->checkSquares[pt];
317
}
300
}
318
 
301
 
319
inline bool Position::pawn_passed(Color c, Square s) const {
302
inline bool Position::pawn_passed(Color c, Square s) const {
320
  return !(pieces(~c, PAWN) & passed_pawn_mask(c, s));
303
  return !(pieces(~c, PAWN) & passed_pawn_mask(c, s));
321
}
304
}
Line 353... Line 336...
353
  return st->rule50;
336
  return st->rule50;
354
}
337
}
355
 
338
 
356
inline uint64_t Position::nodes_searched() const {
339
inline uint64_t Position::nodes_searched() const {
357
  return nodes;
340
  return nodes;
358
}
-
 
359
 
-
 
360
inline void Position::set_nodes_searched(uint64_t n) {
-
 
361
  nodes = n;
-
 
362
}
341
}
363
 
342
 
364
inline bool Position::opposite_bishops() const {
343
inline bool Position::opposite_bishops() const {
365
  return   pieceCount[WHITE][BISHOP] == 1
344
  return   pieceCount[W_BISHOP] == 1
366
        && pieceCount[BLACK][BISHOP] == 1
345
        && pieceCount[B_BISHOP] == 1
367
        && opposite_colors(square<BISHOP>(WHITE), square<BISHOP>(BLACK));
346
        && opposite_colors(square<BISHOP>(WHITE), square<BISHOP>(BLACK));
368
}
347
}
369
 
348
 
370
inline bool Position::is_chess960() const {
349
inline bool Position::is_chess960() const {
371
  return chess960;
350
  return chess960;
372
}
351
}
373
 
352
 
374
inline bool Position::capture_or_promotion(Move m) const {
353
inline bool Position::capture_or_promotion(Move m) const {
375
 
-
 
376
  assert(is_ok(m));
354
  assert(is_ok(m));
377
  return type_of(m) != NORMAL ? type_of(m) != CASTLING : !empty(to_sq(m));
355
  return type_of(m) != NORMAL ? type_of(m) != CASTLING : !empty(to_sq(m));
378
}
356
}
379
 
357
 
380
inline bool Position::capture(Move m) const {
358
inline bool Position::capture(Move m) const {
381
 
-
 
382
  // Castling is encoded as "king captures the rook"
-
 
383
  assert(is_ok(m));
359
  assert(is_ok(m));
-
 
360
  // Castling is encoded as "king captures rook"
384
  return (!empty(to_sq(m)) && type_of(m) != CASTLING) || type_of(m) == ENPASSANT;
361
  return (!empty(to_sq(m)) && type_of(m) != CASTLING) || type_of(m) == ENPASSANT;
385
}
362
}
386
 
363
 
387
inline PieceType Position::captured_piece_type() const {
364
inline Piece Position::captured_piece() const {
388
  return st->capturedType;
365
  return st->capturedPiece;
389
}
366
}
390
 
367
 
391
inline Thread* Position::this_thread() const {
368
inline Thread* Position::this_thread() const {
392
  return thisThread;
369
  return thisThread;
393
}
370
}
394
 
371
 
395
inline void Position::put_piece(Color c, PieceType pt, Square s) {
372
inline void Position::put_piece(Piece pc, Square s) {
396
 
373
 
397
  board[s] = make_piece(c, pt);
374
  board[s] = pc;
398
  byTypeBB[ALL_PIECES] |= s;
375
  byTypeBB[ALL_PIECES] |= s;
399
  byTypeBB[pt] |= s;
376
  byTypeBB[type_of(pc)] |= s;
400
  byColorBB[c] |= s;
377
  byColorBB[color_of(pc)] |= s;
401
  index[s] = pieceCount[c][pt]++;
378
  index[s] = pieceCount[pc]++;
402
  pieceList[c][pt][index[s]] = s;
379
  pieceList[pc][index[s]] = s;
403
  pieceCount[c][ALL_PIECES]++;
380
  pieceCount[make_piece(color_of(pc), ALL_PIECES)]++;
404
}
381
}
405
 
382
 
406
inline void Position::remove_piece(Color c, PieceType pt, Square s) {
383
inline void Position::remove_piece(Piece pc, Square s) {
407
 
384
 
408
  // WARNING: This is not a reversible operation. If we remove a piece in
385
  // WARNING: This is not a reversible operation. If we remove a piece in
409
  // do_move() and then replace it in undo_move() we will put it at the end of
386
  // do_move() and then replace it in undo_move() we will put it at the end of
410
  // the list and not in its original place, it means index[] and pieceList[]
387
  // the list and not in its original place, it means index[] and pieceList[]
411
  // are not guaranteed to be invariant to a do_move() + undo_move() sequence.
388
  // are not invariant to a do_move() + undo_move() sequence.
412
  byTypeBB[ALL_PIECES] ^= s;
389
  byTypeBB[ALL_PIECES] ^= s;
413
  byTypeBB[pt] ^= s;
390
  byTypeBB[type_of(pc)] ^= s;
414
  byColorBB[c] ^= s;
391
  byColorBB[color_of(pc)] ^= s;
415
  /* board[s] = NO_PIECE;  Not needed, overwritten by the capturing one */
392
  /* board[s] = NO_PIECE;  Not needed, overwritten by the capturing one */
416
  Square lastSquare = pieceList[c][pt][--pieceCount[c][pt]];
393
  Square lastSquare = pieceList[pc][--pieceCount[pc]];
417
  index[lastSquare] = index[s];
394
  index[lastSquare] = index[s];
418
  pieceList[c][pt][index[lastSquare]] = lastSquare;
395
  pieceList[pc][index[lastSquare]] = lastSquare;
419
  pieceList[c][pt][pieceCount[c][pt]] = SQ_NONE;
396
  pieceList[pc][pieceCount[pc]] = SQ_NONE;
420
  pieceCount[c][ALL_PIECES]--;
397
  pieceCount[make_piece(color_of(pc), ALL_PIECES)]--;
421
}
398
}
422
 
399
 
423
inline void Position::move_piece(Color c, PieceType pt, Square from, Square to) {
400
inline void Position::move_piece(Piece pc, Square from, Square to) {
424
 
401
 
425
  // index[from] is not updated and becomes stale. This works as long as index[]
402
  // index[from] is not updated and becomes stale. This works as long as index[]
426
  // is accessed just by known occupied squares.
403
  // is accessed just by known occupied squares.
427
  Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to];
404
  Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to];
428
  byTypeBB[ALL_PIECES] ^= from_to_bb;
405
  byTypeBB[ALL_PIECES] ^= from_to_bb;
429
  byTypeBB[pt] ^= from_to_bb;
406
  byTypeBB[type_of(pc)] ^= from_to_bb;
430
  byColorBB[c] ^= from_to_bb;
407
  byColorBB[color_of(pc)] ^= from_to_bb;
431
  board[from] = NO_PIECE;
408
  board[from] = NO_PIECE;
432
  board[to] = make_piece(c, pt);
409
  board[to] = pc;
433
  index[to] = index[from];
410
  index[to] = index[from];
434
  pieceList[c][pt][index[to]] = to;
411
  pieceList[pc][index[to]] = to;
435
}
412
}
436
 
413
 
437
#endif // #ifndef POSITION_H_INCLUDED
414
#endif // #ifndef POSITION_H_INCLUDED