All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
simpleHashRecord.h
Go to the documentation of this file.
1 /* simpleHashRecord.h
2  */
3 #ifndef OSL_SEARCH_SIMPLEHASHRECORD_H
4 #define OSL_SEARCH_SIMPLEHASHRECORD_H
5 
8 #include "osl/eval/evalTraits.h"
9 #include "osl/moveLogProb.h"
10 #ifdef OSL_SMP
11 # include "osl/misc/lightMutex.h"
12 #endif
13 #include <cassert>
14 
15 namespace osl
16 {
17  namespace search
18  {
23  {
24  public:
27  private:
31  signed short upper_limit;
32  signed short lower_limit;
34  unsigned int search_nodes;
35  public:
37  : upper_limit(-1), lower_limit(-1), search_nodes(0)
38  {
39  }
40  void addNodeCount(size_t diff)
41  {
42 #ifdef OSL_SMP
43  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
44 #endif
45  search_nodes += diff;
46  }
47 
51  void setAbsoluteValue(Move best_move, int value, int limit)
52  {
53 #ifdef OSL_SMP
54  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
55 #endif
57  lower_bound = value;
59  upper_bound = value;
60  if (best_move.isNormal())
61  this->best_move = MoveLogProb(best_move, 100);
62  else
63  this->best_move = MoveLogProb();
64  }
65  void setBestMove(Move m, int logprob=100)
66  {
67  assert(! m.isInvalid());
68  // 普通の更新はsetLowerBoundで。
69  best_move = MoveLogProb(m, logprob);
71  }
73  {
74 #ifdef OSL_SMP
75  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
76 #endif
78  lower_bound = value;
80  upper_bound = value;
81  this->best_move = best_move;
82  }
83 
90  int value)
91  {
92 #ifdef OSL_SMP
93  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
94 #endif
95  assert((value % 2) == 0);
96  assert(limit >= 0);
97  if (limit < lower_limit)
98  return;
99  if (best_move.validMove())
100  this->best_move= best_move;
101  lower_bound = value;
102  lower_limit = limit;
103  if (hasUpperBound(0))
104  makeConsistent<true>(P);
105  }
106 
113  int value)
114  {
115 #ifdef OSL_SMP
116  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
117 #endif
118  assert((value % 2) == 0);
119  assert(limit >= 0);
120  if (limit < upper_limit)
121  return;
122  if (best_move.validMove()
123  && (! this->best_move.validMove()))
124  {
125  // best move はupper boundでは基本的には更新しない
126  this->best_move= best_move;
127  }
128  upper_bound = value;
129  upper_limit = limit;
130  if (hasLowerBound(0))
131  makeConsistent<false>(P);
132  }
133  private:
139  template <bool PreferLowerBound>
141  {
142  assert(hasLowerBound(0) && hasUpperBound(0));
144  return;
145  if ((upper_limit < lower_limit)
146  || (PreferLowerBound && (upper_limit == lower_limit)))
147  {
149  assert((upper_bound % 2) == 0);
150  }
151  else
152  {
154  assert((lower_bound % 2) == 0);
155  }
156  }
157  public:
159  int upperLimit() const { return upper_limit; }
161  int upperBound() const { return upper_bound; }
163  int lowerLimit() const { return lower_limit; }
165  int lowerBound() const { return lower_bound; }
167  int checkmateNodes() const { return qrecord.checkmate_nodes; }
168  int threatmateNodes() const { return qrecord.threatmate_nodes; }
169  const MoveLogProb bestMove() const {
170 #ifdef OSL_SMP
171  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
172 #endif
173  return best_move;
174  }
175 
176  bool hasUpperBound(int limit) const
177  {
178  return (upperLimit() >= limit);
179  }
180  bool hasLowerBound(int limit) const
181  {
182  return (lowerLimit() >= limit);
183  }
184  bool hasAbsoluteUpperBound(Player p, int limit) const
185  {
186  return (p == BLACK) ? hasUpperBound(limit) : hasLowerBound(limit);
187  }
188  bool hasAbsoluteLowerBound(Player p, int limit) const
189  {
190  return (p == BLACK) ? hasLowerBound(limit) : hasUpperBound(limit);
191  }
193  {
194  return (p == BLACK) ? upperBound() : lowerBound();
195  }
197  {
198  return (p == BLACK) ? lowerBound() : upperBound();
199  }
200  void resetValue()
201  {
202 #ifdef OSL_SMP
203  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
204 #endif
205  lower_limit = -1;
206  upper_limit = -1;
207  }
209  template <Player P>
210  bool hasGreaterLowerBound(int limit, int threshold, int& val) const
211  {
212 #ifdef OSL_SMP
213  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
214 #endif
215  if ((lowerLimit() < limit)
216  || (EvalTraits<P>::betterThan(threshold, lowerBound())))
217  return false;
218  val = lowerBound();
219  return true;
220  }
222  template <Player P>
223  bool hasLesserUpperBound(int limit, int threshold, int& val) const
224  {
225 #ifdef OSL_SMP
226  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
227 #endif
228  if ((upperLimit() < limit)
229  || (EvalTraits<P>::betterThan(upperBound(), threshold)))
230  return false;
231  val = upperBound();
232  return true;
233  }
234 
237 
238  void dump(std::ostream&) const;
239 
240  size_t nodeCount() const { return search_nodes; }
241  bool inCheck() const
242  {
243 #ifdef OSL_USE_RACE_DETECTOR
244  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
245 #endif
247  }
248  void setInCheck(bool new_value)
249  {
250 #ifdef OSL_USE_RACE_DETECTOR
251  SCOPED_LOCK_CHAR(lk,qrecord.mutex);
252 #endif
254  }
255  };
256  } // namespace search
257 
258  using search::SimpleHashRecord;
259 } // namespace osl
260 
261 
262 #endif /* OSL_SEARCH_SIMPLEHASHRECORD_H */
263 // ;;; Local Variables:
264 // ;;; mode:c++
265 // ;;; c-basic-offset:2
266 // ;;; End: