All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
quiescenceRecord.h
Go to the documentation of this file.
1 /* quiescenceRecord.h
2  */
3 #ifndef _QUIESCENCERECORD_H
4 #define _QUIESCENCERECORD_H
5 
7 #include "osl/ptype.h"
8 #include "osl/move.h"
10 #include "osl/stl/vector.h"
11 #include <iosfwd>
12 #ifdef OSL_SMP
13 # include "osl/misc/lightMutex.h"
14 #endif
15 
16 namespace osl
17 {
18  namespace search
19  {
21  {
22  enum {
24  MaxDepth = 8,
29  };
30  enum { FirstThreat = 6, SecondThreat = 2 };
31  enum MoveType {
34  };
35  };
36 
41  {
42  int value;
44  explicit QuiescenceThreat(int v=0, Move m=Move::INVALID())
45  : value(v), move(m)
46  {
47  }
48  };
49 
50  struct BestMoves : public CArray<Move,4>
51  {
53  {
54  // automaticallyfilled by invalid data by constructor
55  }
56  size_t capacity() const { return size(); }
57  size_t sizeFilled() const
58  {
59  for (size_t i=0; i<capacity(); ++i)
60  if (! operator[](i).isNormal())
61  return i;
62  return capacity();
63  }
64  void add(Move m)
65  {
66  if (! m.isNormal())
67  return;
68  iterator p = std::find(begin(), end(), m);
69  if (p != end()) {
70  std::rotate(begin(), p, p+1);
71  return;
72  }
73  size_t size = sizeFilled();
74  if (size == capacity())
75  operator[](capacity()-1) = m;
76  else
77  operator[](size++) = m;
78  std::rotate(begin(), begin()+(int)size-1, begin()+(int)size);
79  }
80  void clear()
81  {
82  fill(Move());
83  }
84  void addSecondary(const MoveVector& v)
85  {
86  CArray<Move,4> copy = *this;
87  clear();
88  size_t size = 0;
89  if (copy[0].isNormal())
90  operator[](size++) = copy[0];
91  for (size_t i=0; i<v.size() && size<capacity(); ++i) {
92  assert(v[i].isNormal());
93  if (std::find(begin(), begin()+(int)size, v[i]) == begin()+(int)size)
94  operator[](size++) = v[i];
95  }
96  for (size_t i=1; i<copy.size() && copy[i].isNormal() && size<capacity(); ++i)
97  if (std::find(begin(), begin()+(int)size, copy[i]) == begin()+(int)size)
98  operator[](size++) = copy[i];
99  }
100  };
101 
106  {
117  public:
122  enum { InitialDepth = -128, };
124  protected:
129  {
130  }
132  };
133  class SimpleHashRecord;
138  {
139  public:
140  static const char *toString(StaticValueType);
141  private:
142 #ifdef OSL_SMP
143  typedef osl::misc::LightMutexChar Mutex;
144  mutable Mutex mutex;
145 #endif
146  public:
148  {
149  }
154  : QuiescenceRecordBase(src)
155  {
156  }
158  {
159  if (this == &src)
160  return *this;
161 
162  QuiescenceRecordBase::operator=(src);
163  return *this;
164  }
165 
166  template <Player Turn>
167  const Square8 sendOffSquare(const NumEffectState& state) const
168  {
169 #ifdef OSL_SMP
170  SCOPED_LOCK_CHAR(lk,mutex);
171 #endif
172  assert(Turn == state.turn());
173  Square8 ret;
174  const Square king_position = state.kingSquare(alt(Turn));
175  if (threatmate.sendoffs == SendOffSquare::invalidData())
176  threatmate.sendoffs = SendOffSquare::find<Turn>(state, king_position, ret);
177  else
178  SendOffSquare::unpack(threatmate.sendoffs, king_position, ret);
179  return ret;
180  }
181  const Square8
182  sendOffSquare(Player turn, const NumEffectState& state) const
183  {
184  if (turn == BLACK)
185  return sendOffSquare<BLACK>(state);
186  else
187  return sendOffSquare<WHITE>(state);
188  }
194  {
195 #ifdef OSL_SMP
196  SCOPED_LOCK_CHAR(lk,mutex);
197 #endif
198  if (max > checkmate_nodes)
199  {
200  const int left = max - checkmate_nodes;
201  checkmate_nodes = max;
202  return left;
203  }
204  return 0;
205  }
211  {
212 #ifdef OSL_SMP
213  SCOPED_LOCK_CHAR(lk,mutex);
214 #endif
215  if (max > threatmate_nodes)
216  {
217  const int left = max - threatmate_nodes;
218  threatmate_nodes = max;
219  return left;
220  }
221  return 0;
222  }
224  int checkmateNodes() const { return checkmate_nodes; }
225  int threatmateNodes() const { return threatmate_nodes; }
226 
227  void clear()
228  {
229 #ifdef OSL_SMP
230  SCOPED_LOCK_CHAR(lk,mutex);
231 #endif
232  best_moves.clear();
234  }
235  void setStaticValue(StaticValueType type, int value, int depth,
238  {
239 #ifdef OSL_SMP
240  SCOPED_LOCK_CHAR(lk,mutex);
241 #endif
242  assert((depth <= QSearchTraits::MaxDepth)
244  assert(value % 2 == 0);
245  static_value = value;
246  threat1 = t1;
247  threat2 = t2;
250  }
251  public:
252  void setLowerBound(int depth, int bound, Move best_move)
253  {
254 #ifdef OSL_SMP
255  SCOPED_LOCK_CHAR(lk,mutex);
256 #endif
257  assert((depth <= QSearchTraits::MaxDepth)
259  if (depth >= lower_depth)
260  {
261  best_moves.add(best_move);
262  lower_bound = bound;
263  lower_depth = depth;
264  }
265  }
266  void setUpperBound(int depth, int bound)
267  {
268 #ifdef OSL_SMP
269  SCOPED_LOCK_CHAR(lk,mutex);
270 #endif
271  assert((depth <= QSearchTraits::MaxDepth)
273  if (depth >= upper_depth)
274  {
275  upper_bound = bound;
276  upper_depth = depth;
277  }
278  }
279  void setHistoryValue(int value)
280  {
281  lower_bound = upper_bound = value;
283  }
284  void setHistoryValue(Move best_move, int value)
285  {
286 #ifdef OSL_SMP
287  SCOPED_LOCK_CHAR(lk,mutex);
288 #endif
289  best_moves.add(best_move);
290  setHistoryValue(value);
291  }
292  public:
293  void addKillerMoves(const MoveVector& new_moves)
294  {
295 #ifdef OSL_SMP
296  SCOPED_LOCK_CHAR(lk,mutex);
297 #endif
298  best_moves.addSecondary(new_moves);
299  }
301  return static_cast<StaticValueType>(threatmate.flags.static_value_type);
302  }
303  bool hasStaticValue() const { return staticValueType() != UNKNOWN; }
304  bool hasStaticValue(int& value, int& depth, StaticValueType& type) const {
305  type = staticValueType();
306  if (type == UNKNOWN)
307  return false;
308 #ifdef OSL_SMP
309  SCOPED_LOCK_CHAR(lk,mutex);
310 #endif
311  type = staticValueType();
312  value = static_value;
313  depth = static_value_depth;
314  return type != UNKNOWN;
315  }
316  int staticValue() const { assert(hasStaticValue()); return static_value; }
317  int staticValueDepth() const { return static_value_depth; }
318  int upperDepth() const { return upper_depth; }
319  int lowerDepth() const { return lower_depth; }
320  int upperBound() const { return upper_bound; }
321  int lowerBound() const { return lower_bound; }
322  const Move bestMove() const { return best_moves[0]; }
323  int movesEmpty() const { return ! best_moves[1].isNormal(); }
324  int movesSizeLessThan(size_t n) const {
325  return best_moves.capacity() < n || ! best_moves[n-1].isNormal();
326  }
327  int moves_size() const {
328  return std::max(0, (int)best_moves.sizeFilled()-1);
329  }
330  void loadMoves(MoveVector& dst) const{
331 #ifdef OSL_SMP
332  SCOPED_LOCK_CHAR(lk,mutex);
333 #endif
334  dst.clear();
335  for (size_t i=1; i<best_moves.capacity() && best_moves[i].isNormal(); ++i)
336  dst.push_back(best_moves[i]);
337  }
338  void dump(std::ostream&) const;
339  const QuiescenceThreat staticThreat(int index) const
340  {
341  return (index == 0) ? threat1 : threat2;
342  }
343  void updateThreatmate(Player turn, const DualThreatmateState *parent, bool in_check)
344  {
345 #ifdef OSL_SMP
346  SCOPED_LOCK_CHAR(lk,mutex);
347 #endif
348  threatmate.updateInLock(turn, parent, in_check);
349  }
350  friend class SimpleHashRecord;
351  };
352 
353  } // namespace search
354 } // namespace osl
355 
356 #endif /* _QUIESCENCERECORD_H */
357 // ;;; Local Variables:
358 // ;;; mode:c++
359 // ;;; c-basic-offset:2
360 // ;;; End: