Scid  4.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
searchpos.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2013-2018 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 /** @file
20  * Defines the classes used to search for positions.
21  */
22 
23 #ifndef SEARCHPOS_H
24 #define SEARCHPOS_H
25 
26 #include "common.h"
27 #include "fastgame.h"
28 #include "matsig.h"
29 #include "position.h"
30 #include "scidbase.h"
31 #include "stored.h"
32 #include <algorithm>
33 #include <memory>
34 
35 /// Return true if there is a piece's count in @e a which is less than its
36 /// counterpart in @e b.
37 /// @param promo: pawns' difference is considered when comparing queen.
38 /// @param upromo: minor pieces' count is not compared.
39 template <typename TMaterialCount>
40 bool less_mat(const TMaterialCount& a, matSigT b, bool promo, bool upromo) {
41  int wp_diff = a.count(WHITE, PAWN) - static_cast<int>(MATSIG_Count_WP(b));
42  int bp_diff = a.count(BLACK, PAWN) - static_cast<int>(MATSIG_Count_BP(b));
43  if (wp_diff < 0 || bp_diff < 0)
44  return true;
45 
46  int wq_diff = a.count(WHITE, QUEEN) - static_cast<int>(MATSIG_Count_WQ(b));
47  int bq_diff = a.count(BLACK, QUEEN) - static_cast<int>(MATSIG_Count_BQ(b));
48  if (promo) {
49  wq_diff += wp_diff;
50  bq_diff += bp_diff;
51  }
52  if (wq_diff < 0 || bq_diff < 0)
53  return true;
54 
55  if (upromo)
56  return false;
57 
58  return a.count(WHITE, ROOK) < static_cast<int>(MATSIG_Count_WR(b)) ||
59  a.count(WHITE, BISHOP) < static_cast<int>(MATSIG_Count_WB(b)) ||
60  a.count(WHITE, KNIGHT) < static_cast<int>(MATSIG_Count_WN(b)) ||
61  a.count(BLACK, ROOK) < static_cast<int>(MATSIG_Count_BR(b)) ||
62  a.count(BLACK, BISHOP) < static_cast<int>(MATSIG_Count_BB(b)) ||
63  a.count(BLACK, KNIGHT) < static_cast<int>(MATSIG_Count_BN(b));
64 }
65 
66 /// Search for an exact position (same material in the same squares).
67 class SearchPos {
68  MaterialCount nPieces_;
69  pieceT board_[64];
70  std::unique_ptr<StoredLine> storedLine_;
71  std::pair<uint16_t, uint16_t> hpSig_;
72  colorT toMove_;
73  bool isStdStard_;
74 
75 public:
76  explicit SearchPos(const Position* pos) {
77  std::copy_n(pos->GetBoard(), 64, board_);
78 
79  for (auto piece : board_) {
80  if (piece != EMPTY) {
81  nPieces_.incr(piece_Color(piece), piece_Type(piece));
82  }
83  }
84 
85  hpSig_ = hpSig_make(board_);
86  toMove_ = pos->GetToMove();
87  isStdStard_ = pos->IsStdStart();
88 
89  if ((board_[E1] == WK || board_[G1] == WK) &&
90  (board_[E8] == BK || board_[G8] == BK)) {
91  storedLine_ = std::make_unique<StoredLine>(board_, toMove_);
92  }
93  }
94 
95  /// Disable the stored lines optimization
96  void disableOptStoredLine() { storedLine_ = nullptr; }
97 
98  /// Disable the home pawn optimization
99  void disableOptHpSig() { hpSig_ = {0, 0}; }
100 
101  /// Search for the position using the optimizations in a game's index.
102  /// @returns
103  /// -2 : the game cannot reach the searched position
104  /// -1 : the game can reach the searched position
105  /// >=0: the game reach the searched position at the returned ply
106  int index_match(const IndexEntry& ie) const {
107  if (!ie.GetStartFlag()) {
108  if (storedLine_) {
109  int ply = storedLine_->match(ie.GetStoredLineCode());
110  if (ply != -1)
111  return ply;
112  }
113  if (!hpSig_match(hpSig_.first, hpSig_.second, ie.GetHomePawnData()))
114  return -2;
115  }
116  if (less_mat(nPieces_, ie.GetFinalMatSig(), ie.GetPromotionsFlag(),
117  ie.GetUnderPromoFlag())) {
118  return -2;
119  }
120  return -1;
121  }
122 
123  /// Reset @e filter to include only the games that reached the searched
124  /// position in their main line.
125  bool setFilter(scidBaseT* base, HFilter& filter, const Progress& progress) {
126  if (toMove_ == BLACK)
127  return SetFilter<BLACK>(base, filter, progress);
128 
129  if (!isStdStard_)
130  return SetFilter<WHITE>(base, filter, progress);
131 
132  return setFilterStdStart(base, filter);
133  }
134 
135 private:
136  bool setFilterStdStart(scidBaseT* base, HFilter& filter) {
137  filter->includeAll();
138  for (gamenumT i = 0, n = base->numGames(); i < n; i++) {
139  const IndexEntry* ie = base->getIndexEntry(i);
140  if (ie->GetStartFlag()) {
141  int ply = base->getGame(ie).search<WHITE>(board_, nPieces_);
142  filter.set(i, (ply > 255) ? 255 : ply);
143  }
144  }
145  return true;
146  }
147 
148  template <colorT TOMOVE>
149  bool SetFilter(scidBaseT* base, HFilter& filter, const Progress& prg) {
150  filter->clear();
151  long long progress = 0;
152  for (gamenumT i = 0, n = base->numGames(); i < n; i++) {
153  const IndexEntry* ie = base->getIndexEntry(i);
154  int ply = index_match(*ie);
155  if (ply >= 0) {
156  filter.set(i, static_cast<byte>(ply + 1));
157  } else if (ply == -1) {
158  ply = base->getGame(ie).search<TOMOVE>(board_, nPieces_);
159  if (ply != 0)
160  filter.set(i, (ply > 255) ? 255 : ply);
161 
162  if ((progress++ % 256) == 0 && !prg.report(i, n))
163  return false;
164  }
165  }
166  return true;
167  }
168 };
169 
170 #endif
const pieceT WK
Definition: common.h:241
const IndexEntry * getIndexEntry(gamenumT g) const
Definition: scidbase.h:131
int search(const byte *board, const MaterialCount &mt_count)
Definition: fastgame.h:465
void clear()
Definition: hfilter.h:235
piecew sq
Definition: board.tcl:1248
bool GetStartFlag() const
Definition: indexentry.h:252
const colorT WHITE
Definition: common.h:207
pieceT piece_Type(pieceT p)
Definition: common.h:292
#define MATSIG_Count_WN(x)
Definition: matsig.h:139
const pieceT BK
Definition: common.h:242
void disableOptHpSig()
Disable the home pawn optimization.
Definition: searchpos.h:99
const byte * GetHomePawnData() const
Definition: indexentry.h:118
FastGame getGame(const IndexEntry *ie) const
Definition: scidbase.h:141
promopiece
Definition: calvar.tcl:258
#define MATSIG_Count_BN(x)
Definition: matsig.h:140
uint32_t matSigT
Definition: matsig.h:25
#define MATSIG_Count_WR(x)
Definition: matsig.h:135
void includeAll()
Definition: hfilter.h:253
Definition: misc.h:63
#define MATSIG_Count_BQ(x)
Definition: matsig.h:134
int index_match(const IndexEntry &ie) const
Search for the position using the optimizations in a game&#39;s index.
Definition: searchpos.h:106
const colorT BLACK
Definition: common.h:208
bool less_mat(const TMaterialCount &a, matSigT b, bool promo, bool upromo)
Return true if there is a piece&#39;s count in a which is less than its counterpart in b...
Definition: searchpos.h:40
#define MATSIG_Count_BR(x)
Definition: matsig.h:136
matSigT GetFinalMatSig() const
Definition: indexentry.h:114
SearchPos(const Position *pos)
Definition: searchpos.h:76
const pieceT BISHOP
Definition: common.h:229
const pieceT KNIGHT
Definition: common.h:230
Search for an exact position (same material in the same squares).
Definition: searchpos.h:67
void disableOptStoredLine()
Disable the stored lines optimization.
Definition: searchpos.h:96
const pieceT * GetBoard() const
Definition: position.h:197
bool hpSig_match(int hpSig, int nMoved, const byte *changeList)
Definition: matsig.h:325
const pieceT EMPTY
Definition: common.h:239
const squareT G1
Definition: common.h:348
const pieceT QUEEN
Definition: common.h:227
#define MATSIG_Count_WB(x)
Definition: matsig.h:137
const pieceT ROOK
Definition: common.h:228
byte GetStoredLineCode() const
Definition: indexentry.h:115
const pieceT PAWN
Definition: common.h:231
const squareT G8
Definition: common.h:355
bool IsStdStart() const
Definition: position.cpp:650
#define MATSIG_Count_WQ(x)
Definition: matsig.h:133
bool report(size_t done, size_t total) const
Definition: misc.h:75
#define MATSIG_Count_WP(x)
Definition: matsig.h:141
colorT piece_Color(pieceT p)
Definition: common.h:285
gamenumT numGames() const
Definition: scidbase.h:99
colorT GetToMove() const
Definition: position.h:162
const squareT E8
Definition: common.h:355
byte colorT
Definition: common.h:104
#define MATSIG_Count_BP(x)
Definition: matsig.h:142
bool GetUnderPromoFlag() const
Definition: indexentry.h:254
std::pair< uint16_t, uint16_t > hpSig_make(const pieceT *board)
Creates a 16-bits bitmap of the missing pawns in the home ranks.
Definition: matsig.h:298
Store the number of pieces for each type and color.
Definition: fastgame.h:33
const squareT E1
Definition: common.h:348
uint gamenumT
Definition: common.h:163
#define MATSIG_Count_BB(x)
Definition: matsig.h:138
bool setFilter(scidBaseT *base, HFilter &filter, const Progress &progress)
Reset filter to include only the games that reached the searched position in their main line...
Definition: searchpos.h:125
void set(gamenumT gnum, byte value)
Definition: hfilter.h:274
bool GetPromotionsFlag() const
Definition: indexentry.h:253
Definition: indexentry.h:54
byte pieceT
Definition: common.h:103
void incr(colorT color, pieceT piece_type)
Add one piece.
Definition: fastgame.h:38