Scid  4.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
fastgame.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2013-2015 Fulvio Benini
3 
4 * This file is part of Scid (Shane's Chess Information Database).
5 *
6 * Scid 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.
9 *
10 * Scid is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Scid. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef FASTGAME_H
20 #define FASTGAME_H
21 
22 #include "common.h"
23 #include "fullmove.h"
24 #include "movegen.h"
25 #include "position.h"
26 #include <algorithm>
27 #include <cstdlib>
28 #include <cstring>
29 #include <sstream>
30 #include <string>
31 
32 /// Store the number of pieces for each type and color.
34  int8_t n_[2][8] = {};
35 
36 public:
37  /// Add one piece.
38  void incr(colorT color, pieceT piece_type) {
39  ASSERT(color == 0 || color == 1);
40  ASSERT(piece_type > 0 && piece_type < 8);
41 
42  ++n_[color][0];
43  ++n_[color][piece_type];
44  }
45 
46  /// Subtract one piece.
47  void decr(colorT color, pieceT piece_type) {
48  ASSERT(color == 0 || color == 1);
49  ASSERT(piece_type > 0 && piece_type < 8);
50 
51  --n_[color][0];
52  --n_[color][piece_type];
53  }
54 
55  /// Return the total number of pieces of the specified color.
56  int8_t count(colorT color) const {
57  ASSERT(color == 0 || color == 1);
58 
59  return n_[color][0];
60  }
61 
62  /// Return the number of pieces of the specified color and type.
63  int8_t count(colorT color, pieceT piece_type) const {
64  ASSERT(color == 0 || color == 1);
65  ASSERT(piece_type > 0 && piece_type < 8);
66 
67  return n_[color][piece_type];
68  }
69 
70  bool operator==(const MaterialCount& b) const {
71  const int8_t* a = n_[0];
72  const int8_t* b_ptr = b.n_[0];
73  return std::equal(a, a + 16, b_ptr);
74  }
75 
76  bool operator!=(const MaterialCount& b) const {
77  return !operator==(b);
78  }
79 };
80 
81 /// Store the type and position of the pieces compatibly with the SCID4 coding.
82 class PieceList {
83  struct {
86  } pieces_[2][16];
87 
88 public:
89  /// SCID4 encoded games must use index 0 for kings.
90  int8_t getKingIdx() const { return 0; }
91 
92  /// Return the type of the piece with index @e idx
93  pieceT getPieceType(colorT color, int idx) const {
94  ASSERT(color == 0 || color == 1);
95  ASSERT(idx >= 0 && idx < 16);
96 
97  return pieces_[color][idx].piece_type;
98  }
99 
100  /// Return the square position of the piece with index @e idx
101  squareT getSquare(colorT color, int idx) const {
102  ASSERT(color == 0 || color == 1);
103  ASSERT(idx >= 0 && idx < 16);
104 
105  return pieces_[color][idx].sq;
106  }
107 
108  /// Change the square position of the piece with index @e idx
109  void move(colorT color, int idx, squareT to) {
110  ASSERT(color == 0 || color == 1);
111  ASSERT(idx >= 0 && idx < 16);
112 
113  pieces_[color][idx].sq = to;
114  }
115 
116  /// Change the type of the piece with index @e idx
117  void promote(colorT color, int idx, pieceT piece_type) {
118  ASSERT(color == 0 || color == 1);
119  ASSERT(idx >= 0 && idx < 16);
120 
121  pieces_[color][idx].piece_type = piece_type;
122  }
123 
124  /// Remove the piece with index @e removed_idx.
125  /// Piece's indexes are important for decoding SCID4 moves: when a piece is
126  /// removed it's index is used by the last valid index @e lastvalid_idx.
127  /// Return the square of the new piece with index @e removed_idx.
128  squareT remove(colorT color, int removed_idx, int lastvalid_idx) {
129  ASSERT(color == 0 || color == 1);
130  ASSERT(removed_idx >= 0 && removed_idx < 16);
131  ASSERT(lastvalid_idx >= 0 && lastvalid_idx < 16);
132 
133  pieces_[color][removed_idx] = pieces_[color][lastvalid_idx];
134  return pieces_[color][lastvalid_idx].sq;
135  }
136 
137  /// Set the type and square of the piece with index @e idx
138  void set(colorT color, int idx, squareT sq, pieceT piece_type) {
139  ASSERT(color == 0 || color == 1);
140  ASSERT(idx >= 0 && idx < 16);
141  ASSERT(piece_type != KING || idx == getKingIdx());
142 
143  pieces_[color][idx].sq = sq;
144  pieces_[color][idx].piece_type = piece_type;
145  }
146 };
147 
148 class FastBoard {
149  uint8_t board_[64];
150  MaterialCount mt_;
151  PieceList pieces_;
152 
153  enum { EMPTY_SQ_ = 0xFF };
154 
155 public:
157  FastBoard(Position& pos) { Init(pos); }
158 
159  void Init() {
160  static Position StdStartPos(Position::getStdStart());
161  static FastBoard StdStart(StdStartPos);
162  *this = StdStart;
163  }
164 
165  void Init(Position& pos) {
166  std::fill_n(board_, 64, EMPTY_SQ_);
167 
168  for (auto color : {WHITE, BLACK}) {
169  const auto pos_count = pos.GetCount(color);
170  const auto pos_list = pos.GetList(color);
171  for (uint8_t idx = 0; idx < 16; ++idx) {
172  if (idx < pos_count) {
173  const squareT sq = pos_list[idx];
174  const pieceT piece_type = piece_Type(pos.GetPiece(sq));
175  pieces_.set(color, idx, sq, piece_type);
176  board_[sq] = idx;
177  mt_.incr(color, piece_type);
178  } else {
179  pieces_.set(color, idx, 0, INVALID_PIECE);
180  }
181  }
182  }
183  }
184 
185  bool isEqual(const pieceT* board, const MaterialCount& mt_count) const {
186  if (mt_ != mt_count)
187  return false;
188 
189  for (int idx = 0, n = mt_.count(WHITE); idx < n; ++idx) {
190  const auto sq = pieces_.getSquare(WHITE, idx);
191  const auto pt = pieces_.getPieceType(WHITE, idx);
192  if (board[sq] != piece_Make(WHITE, pt))
193  return false;
194  }
195  for (int idx = 0, n = mt_.count(BLACK); idx < n; ++idx) {
196  const auto sq = pieces_.getSquare(BLACK, idx);
197  const auto pt = pieces_.getPieceType(BLACK, idx);
198  if (board[sq] != piece_Make(BLACK, pt))
199  return false;
200  }
201  return true;
202  }
203 
204  const MaterialCount& materialCount() const {
205  return mt_;
206  }
207 
208  squareT getSquare(colorT color, int idx) const {
209  return pieces_.getSquare(color, idx);
210  }
211 
212  pieceT getPiece(colorT color, int idx) const {
213  return pieces_.getPieceType(color, idx);
214  }
215 
216  // TODO: error detection
217  template <colorT color> squareT castle(bool king_side) {
218  const squareT black = (color == WHITE) ? 0 : 56;
219  squareT king_to, rook_from, rook_to;
220  if (king_side) { // King Side
221  king_to = black + G1;
222  rook_from = black + H1;
223  rook_to = black + F1;
224  } else { // Queen Side
225  king_to = black + C1;
226  rook_from = black + A1;
227  rook_to = black + D1;
228  }
229  const uint8_t rook_idx = board_[rook_from];
230  const auto king_idx = pieces_.getKingIdx();
231  const squareT king_from = pieces_.getSquare(color, king_idx);
232  pieces_.move(color, rook_idx, rook_to);
233  pieces_.move(color, king_idx, king_to);
234  board_[rook_to] = rook_idx;
235  board_[king_to] = king_idx;
236  board_[rook_from] = EMPTY_SQ_;
237  board_[king_from] = EMPTY_SQ_;
238  return rook_from;
239  }
240 
241  template <colorT color>
242  pieceT move(uint8_t idx, squareT to, pieceT promo) {
243  if (promo != INVALID_PIECE) {
244  pieces_.promote(color, idx, promo);
245  mt_.incr(color, promo);
246  mt_.decr(color, PAWN);
247  }
248  const auto from = pieces_.getSquare(color, idx);
249  board_[from] = EMPTY_SQ_;
250  pieces_.move(color, idx, to);
251  return remove<1 - color>(to, idx);
252  }
253 
254  template <colorT color>
255  pieceT remove(squareT sq, uint8_t newIdx = EMPTY_SQ_) {
256  const uint8_t oldIdx = board_[sq];
257  board_[sq] = newIdx;
258  if (oldIdx == EMPTY_SQ_)
259  return INVALID_PIECE;
260 
261  pieceT removed_pt = pieces_.getPieceType(color, oldIdx);
262  mt_.decr(color, removed_pt);
263  int lastvalid_idx = mt_.count(color);
264  if (oldIdx != lastvalid_idx) {
265  squareT moved_sq = pieces_.remove(color, oldIdx, lastvalid_idx);
266  board_[moved_sq] = oldIdx;
267  }
268  return removed_pt;
269  }
270 
271  /**
272  * Given the actual board position, find if the last move needs to be made
273  * unambiguous and if it gives check (or TODO mate), and then sets the
274  * appropriate bits in @e lastmove.
275  * @param lastmove: the last move played.
276  */
277  void fillSANInfo(FullMove& lastmove) {
278  squareT lastFrom = lastmove.getFrom();
279  squareT lastTo = lastmove.getTo();
280  colorT lastCol = lastmove.getColor();
281  pieceT lastPt = lastmove.getPiece();
282 
283  if (lastPt == PAWN) {
284  if (lastmove.isPromo())
285  lastPt = lastmove.getPromo();
286  } else if (mt_.count(lastCol, lastPt) > 1) {
287  int ambiguity = ambiguousMove(lastFrom, lastTo, lastCol, lastPt);
288  if (ambiguity)
289  lastmove.setAmbiguity(ambiguity != 5, ambiguity >= 5);
290  }
291 
292  // Look for checks
293  ASSERT(mt_.count(WHITE) >= 1 && mt_.count(BLACK) >= 1);
294 
295  const squareT enemyKingSq = getKingSquare(color_Flip(lastCol));
296  bool direct_check = lastPt != KING && movegen::attack<uint8_t>(
297  lastTo, enemyKingSq, lastCol,
298  lastPt, board_, EMPTY_SQ_);
299  if (direct_check || // Look for a discovered check
300  find_attacker_slider(enemyKingSq, lastCol) >= 0) {
301  lastmove.setCheck();
302 
303  // TODO: Find if it's mate:
304  // - it's not mate if the king can move to a safe square
305  // - it's mate if it's double check or the attacker cannot be
306  // captured or blocked.
307  }
308  }
309 
310 private:
311  squareT getKingSquare(colorT color) {
312  return pieces_.getSquare(color, pieces_.getKingIdx());
313  }
314 
315  int ambiguousMove(squareT lastFrom, squareT lastTo, colorT lastCol,
316  pieceT lastPt) {
317  int ambiguity = 0;
318 
319  const squareT kingSq = getKingSquare(lastCol);
320  const colorT enemyCol = color_Flip(lastCol);
321  for (int i = 1, n = mt_.count(lastCol); i < n; i++) {
322  if (getPiece(lastCol, i) != lastPt)
323  continue; // Skip: different type
324 
325  const squareT sq = getSquare(lastCol, i);
326  if (sq == lastTo)
327  continue; // Skip: this is the analyzed piece
328 
329  board_[lastFrom] = board_[sq];
330  board_[sq] = EMPTY_SQ_;
331 
332  bool pseudoLegal = movegen::pseudo<uint8_t>(
333  sq, lastTo, lastCol, lastPt, board_, EMPTY_SQ_);
334 
335  std::pair<pieceT, squareT> pin;
336  if (pseudoLegal)
337  pin = movegen::opens_ray<uint8_t>(sq, lastTo, kingSq, board_,
338  EMPTY_SQ_);
339  board_[sq] = board_[lastFrom];
340  board_[lastFrom] = EMPTY_SQ_;
341 
342  if (!pseudoLegal)
343  continue; // Skip: illegal move
344 
345  if (pin.first != INVALID_PIECE) {
346  uint8_t idx = board_[pin.second];
347  if (idx != EMPTY_SQ_ && idx < mt_.count(enemyCol) &&
348  getSquare(enemyCol, idx) == pin.second) {
349  const pieceT pt = getPiece(enemyCol, idx);
350  if (pt == QUEEN || pt == pin.first)
351  continue; // Skip: pinned piece
352  }
353  }
354 
355  // Ambiguity:
356  // 1 (0001) --> need from-file (preferred) or from-rank
357  // 3 (0011) --> need from-file
358  // 5 (0101) --> need from-rank
359  // 7 (0111) --> need both from-file and from-rank
360  ambiguity |= 1;
361  if (square_Rank(lastFrom) == square_Rank(sq)) {
362  ambiguity |= 2; // 0b0010
363  } else if (square_Fyle(lastFrom) == square_Fyle(sq)) {
364  ambiguity |= 4; // 0b0100
365  }
366  }
367 
368  return ambiguity;
369  }
370 
371  int find_attacker_slider(squareT destSq, colorT color) {
372  for (int idx = 0, n = mt_.count(color); idx < n; ++idx) {
373  const pieceT pt = getPiece(color, idx);
374  if (pt != QUEEN && pt != ROOK && pt != BISHOP)
375  continue;
376 
377  const squareT sq = getSquare(color, idx);
378  if (movegen::attack_slider<uint8_t>(sq, destSq, pt, board_,
379  EMPTY_SQ_)) {
380  return idx;
381  }
382  }
383  return -1;
384  }
385 };
386 
387 class FastGame {
388  FastBoard board_;
389  const byte* v_it_;
390  const byte* v_end_;
391  colorT cToMove_;
392 
393 public:
394  static FastGame Create(const byte* v_begin, const byte* v_end) {
395  const byte* v_it = v_begin;
396  while (v_it < v_end) {
397  byte b = *v_it++;
398  if (b == 0) {
399  if (v_it >= v_end) break; // Error
400  byte haveFEN = *v_it++ & 1;
401  if (haveFEN == 0) {
402  return FastGame(v_it, v_end);
403  } else {
404  const char* FENstring = (char*) v_it;
405  while (v_it < v_end) {
406  if (*v_it++ == 0) return FastGame(FENstring, v_it, v_end);
407  }
408  break; // FEN error
409  }
410  } else if (b == 255) { // Skip special 3-byte binary encoding of EventDate
411  v_it += 3;
412  } else { // Skip tags
413  enum { MAX_TAG_LEN = 240 };
414  if (b <= MAX_TAG_LEN) v_it += b;
415  if (v_it < v_end) v_it += *v_it +1;
416  }
417  }
418 
419  return FastGame(0,0); // Error default to StdStart and empty buffer
420  }
421 
422  FullMove getMove(int ply_to_skip) {
423  for (int ply=0; ply <= ply_to_skip; ply++, cToMove_ = 1 - cToMove_) {
424  auto move = (cToMove_ == WHITE)
425  ? DecodeNextMove<FullMove, WHITE>()
426  : DecodeNextMove<FullMove, BLACK>();
427  if (!move)
428  break;
429 
430  if (ply == ply_to_skip) {
431  board_.fillSANInfo(move);
432  cToMove_ = 1 - cToMove_;
433  return move;
434  }
435  }
436  return {};
437  }
438 
439  std::string getMoveSAN(int ply_to_skip, int count) {
440  std::stringstream res;
441  for (int ply=0; ply < ply_to_skip + count; ply++, cToMove_ = 1 - cToMove_) {
442  FullMove move;
443  if (cToMove_ == WHITE) {
444  move = DecodeNextMove <FullMove, WHITE>();
445  if (!move)
446  break;
447  if (ply < ply_to_skip) continue;
448  if (ply > ply_to_skip) res << " ";
449  res << (1 + ply/2) << ".";
450  } else {
451  move = DecodeNextMove <FullMove, BLACK>();
452  if (!move)
453  break;
454  if (ply < ply_to_skip) continue;
455  if (ply == ply_to_skip) res << (1 + ply/2) << "...";
456  else res << " ";
457  }
458  board_.fillSANInfo(move);
459  res << move.getSAN();
460  }
461  return res.str();
462  }
463 
464  template <colorT toMove>
465  int search(const byte* board, const MaterialCount& mt_count) {
466  int ply = 1;
467  auto less_material = [](const MaterialCount& a, const MaterialCount& b,
468  const colorT color, const auto move) {
469  if (!move)
470  return true;
471 
472  const auto captured_pt = move.getCaptured();
473  if (captured_pt == INVALID_PIECE)
474  return false;
475 
476  if (a.count(color) < b.count(color))
477  return true;
478 
479  return a.count(color, PAWN) + a.count(color, captured_pt) <
480  b.count(color, PAWN) + b.count(color, captured_pt);
481  };
482 
483  if (cToMove_ != toMove) {
484  const auto move = DecodeNextMove<FullMove, 1 - toMove>();
485  if (!move)
486  return 0;
487  ply += 1;
488  }
489  for (;;) {
490  if (board_.isEqual(board, mt_count))
491  return ply;
492 
493  {
494  const auto move = DecodeNextMove<FullMove, toMove>();
495  if (less_material(board_.materialCount(), mt_count, 1 - toMove,
496  move))
497  return 0;
498  }
499  {
500  const auto move = DecodeNextMove<FullMove, 1 - toMove>();
501  if (less_material(board_.materialCount(), mt_count, toMove,
502  move))
503  return 0;
504  }
505 
506  ply += 2;
507  }
508  return 0;
509  }
510 
511 private:
512  FastGame(const byte* v_it, const byte* v_end)
513  : v_it_ (v_it), v_end_(v_end), cToMove_(WHITE) {
514  board_.Init();
515  }
516 
517  FastGame(const char* FEN, const byte* v_it, const byte* v_end)
518  : v_it_ (v_it), v_end_(v_end) {
519  Position StartPos;
520  if (FEN == 0 || StartPos.ReadFromFEN(FEN) != OK) StartPos.StdStart();
521  board_.Init(StartPos);
522  cToMove_ = StartPos.GetToMove();
523  }
524 
525  template <typename TResult, colorT toMove>
526  TResult DecodeNextMove() {
528  enum { ENCODE_FIRST = 11, ENCODE_LAST = 15 };
529 
530  while (v_it_ < v_end_) {
531  byte b = *v_it_++;
532  if (b < ENCODE_FIRST || b > ENCODE_LAST) return doPly<TResult, toMove>(b);
533  if (b == ENCODE_END_GAME || b == ENCODE_END_MARKER) return {};
534  if (b == ENCODE_NAG) {v_it_++; continue; }
535  if (b == ENCODE_START_MARKER) {
536  int nestCount = 1;
537  do {
538  if (v_it_ >= v_end_) return {};
539  switch (*v_it_++) {
540  case ENCODE_NAG: v_it_++; break;
541  case ENCODE_START_MARKER: nestCount++; break;
542  case ENCODE_END_MARKER: nestCount--; break;
543  case ENCODE_END_GAME: return {};
544  }
545  } while (nestCount > 0);
546  }
547  }
548  return {};
549  }
550 
551  template <typename TResult, colorT toMove> TResult doPly(byte v) {
552  byte idx_piece_moving = v >> 4;
553  byte move = v & 0x0F;
554  pieceT moving_piece = board_.getPiece(toMove, idx_piece_moving);
555  squareT from = board_.getSquare(toMove, idx_piece_moving);
556  int to;
558  bool enPassant = false;
559  switch (moving_piece) {
560  case PAWN:
561  to = decodePawn<toMove>(from, move, promo, enPassant);
562  break;
563  case BISHOP:
564  to = decodeBishop(from, move);
565  break;
566  case KNIGHT:
567  to = decodeKnight(from, move);
568  break;
569  case QUEEN:
570  if (move == square_Fyle(from)) { // 2 BYTES MOVE
571  if (v_it_ >= v_end_)
572  return {}; // decode error
573 
574  to = decodeQueen2byte(*v_it_++);
575  break;
576  }
577  /* FALLTHRU */
578  case ROOK:
579  to = decodeRook(from, move);
580  break;
581  case KING:
582  if (move == 0) { // NULL MOVE
583  return TResult(toMove, 0, 0, KING);
584  }
585  if (move <= 8) {
586  to = decodeKing(from, move);
587  break;
588  }
589  if (move <= 10) { // CASTLE
590  const squareT rook_from = board_.castle<toMove>(move == 10);
591  return TResult(toMove, from, rook_from);
592  }
593  return {}; // decode error
594 
595  default:
596  return {}; // decode error
597  }
598 
599  if (to < 0 || to > 63)
600  return {}; // decode error
601 
602  pieceT captured = board_.move<toMove>(idx_piece_moving, to, promo);
603  TResult res(toMove, from, to, moving_piece);
604  if (promo != INVALID_PIECE)
605  res.setPromo(promo);
606  if (captured != INVALID_PIECE) {
607  res.setCapture(captured, false);
608  } else if (enPassant) {
609  squareT sq = (toMove == WHITE) ? to - 8 : to + 8;
610  captured = board_.remove<1 - toMove>(0x3F & sq);
611  res.setCapture(captured, true);
612  }
613  return res;
614  }
615 
616  /**
617  * decode*() - decode a move from Scid format
618  * @from: start square of the moving piece
619  * @val: index of the target square
620  *
621  * Excluding queens, the other chess pieces cannot reach more than 16 target
622  * squares from any given position. This allow to store the target square of
623  * a move into 4 bits, as an index of all the possible target squares.
624  * Return:
625  * - the target square
626  * Error handling:
627  * - Debug code will check if the decoded value is a valid [0-63] square.
628  * - Release code will force the returned valid to be a valid [0-63] square
629  * but, for performance reasons, do not report invalid encoded moves.
630  */
631  static inline int decodeKing(squareT from, byte val) {
632  ASSERT(val <= 8);
633  static const int8_t sqdiff[] = {0, -9, -8, -7, -1, 1, 7, 8, 9};
634  return from + sqdiff[val];
635  }
636  static inline int decodeQueen2byte(byte val) {
637  return val - 64;
638  }
639  static inline int decodeBishop(squareT from, byte val) {
640  int fylediff = square_Fyle(val) - square_Fyle(from);
641  return (val >= 8) ? from - 7 * fylediff //
642  : from + 9 * fylediff;
643  }
644  static inline int decodeKnight(squareT from, byte val) {
645  ASSERT(val <= 16);
646  static const int8_t sqdiff[] = {0, -17, -15, -10, -6, 6, 10, 15, 17, 0, 0, 0, 0, 0, 0, 0};
647  return from + sqdiff[val];
648  }
649  static inline int decodeRook(squareT from, byte val) {
650  ASSERT(val <= 16);
651  if (val >= 8) // vertical move
652  return square_Make(square_Fyle(from), (val - 8));
653  else // horizontal move
654  return square_Make(val, square_Rank(from));
655  }
656  template <colorT color>
657  static inline int decodePawn(squareT from, byte val, pieceT& promo,
658  bool& enPassant) {
659  ASSERT(val <= 16);
660  static const int8_t sqdiff [] = { 7,8,9, 7,8,9, 7,8,9, 7,8,9, 7,8,9, 16 };
661  static const pieceT promoPieceFromVal [] = {
663  };
664  promo = promoPieceFromVal[val];
665  enPassant = (val == 0 || val == 2);
666  return (color == WHITE) ? from + sqdiff[val] //
667  : from - sqdiff[val];
668  }
669 };
670 
671 
672 #endif
unsigned char byte
Definition: common.h:89
int search(const byte *board, const MaterialCount &mt_count)
Definition: fastgame.h:465
squareT getTo() const
Definition: fullmove.h:66
const colorT WHITE
Definition: common.h:207
pieceT piece_Type(pieceT p)
Definition: common.h:292
sqsqname
Definition: board.tcl:292
FullMove getMove(int ply_to_skip)
Definition: fastgame.h:422
void promote(colorT color, int idx, pieceT piece_type)
Change the type of the piece with index idx.
Definition: fastgame.h:117
squareT sq
Definition: fastgame.h:84
FastBoard(Position &pos)
Definition: fastgame.h:157
const errorT OK
Definition: error.h:23
int8_t count(colorT color, pieceT piece_type) const
Return the number of pieces of the specified color and type.
Definition: fastgame.h:63
const squareT H1
Definition: common.h:348
const MaterialCount & materialCount() const
Definition: fastgame.h:204
promopiece
Definition: calvar.tcl:258
void Init()
Definition: fastgame.h:159
static const Position & getStdStart()
Definition: position.cpp:594
#define ASSERT(f)
Definition: common.h:59
const squareT C1
Definition: common.h:348
#define ENCODE_COMMENT
Definition: game.cpp:2945
const pieceT KING
Definition: common.h:226
constexpr size_t MAX_TAG_LEN
Definition: game.cpp:3133
squareT getSquare(colorT color, int idx) const
Definition: fastgame.h:208
const colorT BLACK
Definition: common.h:208
pieceT getPieceType(colorT color, int idx) const
Return the type of the piece with index idx.
Definition: fastgame.h:93
rankT square_Rank(squareT sq)
Definition: common.h:390
int8_t count(colorT color) const
Return the total number of pieces of the specified color.
Definition: fastgame.h:56
errorT ReadFromFEN(const char *s)
Definition: position.cpp:2638
const squareT * GetList(colorT c) const
Definition: position.h:169
pieceT remove(squareT sq, uint8_t newIdx=EMPTY_SQ_)
Definition: fastgame.h:255
pieceT GetPiece(squareT sq) const
Definition: position.h:202
colorT color_Flip(colorT c)
Definition: common.h:214
FastBoard()
Definition: fastgame.h:156
colorT getColor() const
Definition: fullmove.h:69
const pieceT BISHOP
Definition: common.h:229
const squareT A1
Definition: common.h:348
const pieceT KNIGHT
Definition: common.h:230
squareT square_Make(fyleT f, rankT r)
Definition: common.h:377
static FastGame Create(const byte *v_begin, const byte *v_end)
Definition: fastgame.h:394
#define ENCODE_NAG
Definition: game.cpp:2944
pieceT getPiece() const
Definition: fullmove.h:68
pieceT piece_type
Definition: fastgame.h:85
const pieceT INVALID_PIECE
Definition: common.h:225
const squareT G1
Definition: common.h:348
void decr(colorT color, pieceT piece_type)
Subtract one piece.
Definition: fastgame.h:47
int8_t getKingIdx() const
SCID4 encoded games must use index 0 for kings.
Definition: fastgame.h:90
const pieceT QUEEN
Definition: common.h:227
Definition: board.tcl:276
pieceT move(uint8_t idx, squareT to, pieceT promo)
Definition: fastgame.h:242
const pieceT ROOK
Definition: common.h:228
Definition: move.tcl:20
void StdStart()
Definition: position.h:152
getSquarew x y
Definition: board.tcl:670
void set(colorT color, int idx, squareT sq, pieceT piece_type)
Set the type and square of the piece with index idx.
Definition: fastgame.h:138
std::string getMoveSAN(int ply_to_skip, int count)
Definition: fastgame.h:439
void setAmbiguity(bool fyle, bool rank)
Definition: fullmove.h:125
bool isEqual(const pieceT *board, const MaterialCount &mt_count) const
Definition: fastgame.h:185
bool isPromo() const
Definition: fullmove.h:63
const pieceT PAWN
Definition: common.h:231
const squareT D1
Definition: common.h:348
pieceT getPiece(colorT color, int idx) const
Definition: fastgame.h:212
#define ENCODE_FIRST
Definition: game.cpp:2950
colorpct ?col?
Definition: ptracker.tcl:77
void Init(Position &pos)
Definition: fastgame.h:165
colorT GetToMove() const
Definition: position.h:162
pieceT getPromo() const
Definition: fullmove.h:70
bool operator==(const MaterialCount &b) const
Definition: fastgame.h:70
byte colorT
Definition: common.h:104
squareT castle(bool king_side)
Definition: fastgame.h:217
bool operator!=(const MaterialCount &b) const
Definition: fastgame.h:76
Store the number of pieces for each type and color.
Definition: fastgame.h:33
void setCheck()
Definition: fullmove.h:132
squareT getSquare(colorT color, int idx) const
Return the square position of the piece with index idx.
Definition: fastgame.h:101
#define ENCODE_START_MARKER
Definition: game.cpp:2946
void move(colorT color, int idx, squareT to)
Change the square position of the piece with index idx.
Definition: fastgame.h:109
Implements functions for the validation of chess moves.
squareT remove(colorT color, int removed_idx, int lastvalid_idx)
Remove the piece with index removed_idx.
Definition: fastgame.h:128
#define ENCODE_END_GAME
Definition: game.cpp:2948
const squareT F1
Definition: common.h:348
pieceT piece_Make(colorT c, pieceT p)
Definition: common.h:295
#define ENCODE_LAST
Definition: game.cpp:2951
uint GetCount(colorT c) const
Definition: position.h:171
squareT getFrom() const
Definition: fullmove.h:67
Store the type and position of the pieces compatibly with the SCID4 coding.
Definition: fastgame.h:82
void fillSANInfo(FullMove &lastmove)
Given the actual board position, find if the last move needs to be made unambiguous and if it gives c...
Definition: fastgame.h:277
byte squareT
Definition: common.h:105
byte pieceT
Definition: common.h:103
void incr(colorT color, pieceT piece_type)
Add one piece.
Definition: fastgame.h:38
fyleT square_Fyle(squareT sq)
Definition: common.h:384
std::string getSAN(colorT *toMove=0) const
Definition: fullmove.h:72
#define ENCODE_END_MARKER
Definition: game.cpp:2947