All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
searchPlayer.tcc
Go to the documentation of this file.
1 /* searchPlayer.tcc
2  */
3 #ifndef GAMEPLAYING_SEARCHPLAYER_TCC
4 #define GAMEPLAYING_SEARCHPLAYER_TCC
9 #include "osl/eval/evalTraits.h"
11 
12 #ifdef USE_NTESUKI
15 #endif
16 
17 #include <boost/scoped_ptr.hpp>
18 #include <boost/foreach.hpp>
19 
20 #ifdef USE_NTESUKI
21 struct
22 osl::game_playing::SearchPlayer::NtesukiThread
23 {
24  explicit NtesukiThread(Move& next_move,
25  volatile bool *thread_finished,
26  volatile bool *stop_flag,
27  NumEffectState state);
28 
29  void operator()();
30 
31  Move& next_move;
32  volatile bool *thread_finished;
33  volatile bool *stop_flag;
34  NumEffectState state;
35 };
36 #endif
37 
38 template <class Searcher>
40 SearchPlayer::cloneIt(const Searcher& copy) const
41 {
42  return new Searcher(copy);
43 }
44 
45 template <class Searcher>
48 {
49  typedef typename Searcher::eval_t eval_t;
50  return abs(eval_t::captureValue(newPtypeO(BLACK,PAWN)))/2;
51 }
52 template <class Searcher>
55 {
56  return pawnValue<Searcher>() * eval::delta(turn);
57 }
58 
59 template <class Searcher>
62 {
63  Searcher& searcher = dynamic_cast<Searcher&>(*this->searcher);
64  searcher.setRootIgnoreMoves(root_ignore_moves, prediction_for_speculative_search);
65 
66  typedef typename Searcher::eval_t eval_t;
67  if (! eval_t::initialized())
68  throw std::runtime_error("evaluation function not initialized");
69 
70  const MoveStack& history = state.moveHistory();
71 
72 #ifdef USE_NTESUKI
73  volatile bool ntesuki_thread_finished;
74  volatile bool stop_ntesuki;
75  Move ntesuki_next_move = Move::INVALID();
76 
77  NtesukiThread thread(ntesuki_next_move, &ntesuki_thread_finished,
78  &stop_ntesuki, state.state());
79  boost::thread ntesuki_thread(thread);
80 #endif
81  searcher.setHistory(history);
82  searcher.enableMultiPV(config.multi_pv_width);
83  BOOST_FOREACH(const boost::shared_ptr<search::SearchMonitor>& m,
84  config.monitors)
85  searcher.addMonitor(m);
86  int deepening_step_for_this_move = config.deepening_step;
87  if (! msec.standard.isInfinity())
88  {
89  if (msec.standard.toSeconds() < 10.0)
90  deepening_step_for_this_move = std::min(100, config.deepening_step);
91  }
92  searcher.setNextIterationCoefficient(config.next_iteration_coefficient);
93  searcher.setNodeCountHardLimit(config.node_count_hard_limit);
94 
95  MoveWithComment best_move;
96  best_move.root = HashKey(state.state());
97  if (plan_stop)
98  return best_move;
99 
100  searching = true;
101  best_move.move
102  = searcher.computeBestMoveIteratively(config.limit,
103  deepening_step_for_this_move,
104  config.initial_limit,
105  config.node_limit,
106  msec,
107  &best_move);
108  searching = false;
109 #ifdef USE_NTESUKI
110  if (ntesuki_thread_finished)
111  {
112  if (ntesuki_next_move.isNormal())
113  {
114  return ntesuki_next_move;
115  }
116  else
117  {
118  //ntesuki_finished
119  }
120  }
121  else
122  {
123  //force_finish
124  stop_ntesuki = true;
125  ntesuki_thread.join();
126  }
127 #endif
128  saveSearchResult(state, best_move);
129  static const int resign_value = OslConfig::resignThreshold();
130  if (! state.state().inCheck() && best_move.move.isNormal()
131  && best_move.value*playerToMul(state.state().turn()) < -resign_value)
132  {
133  ++almost_resign_count;
134  if (almost_resign_count >= 3)
135  best_move.move = Move();
136  }
137  else
138  {
139  almost_resign_count = 0;
140  }
141  return best_move;
142 }
143 
144 template <class Searcher>
146 SearchPlayer::isReasonableMoveBySearch(Searcher& searcher, Move move, int pawn_sacrifice)
147 {
148  return searcher.isReasonableMove(move, pawn_sacrifice);
149 }
150 
151 #endif /* GAMEPLAYING_SEARCHPLAYER_TCC */
152 // ;;; Local Variables:
153 // ;;; mode:c++
154 // ;;; c-basic-offset:2
155 // ;;; End: