searchPlayer.tcc
Go to the documentation of this file.
00001 /* searchPlayer.tcc
00002  */
00003 #ifndef GAMEPLAYING_SEARCHPLAYER_TCC
00004 #define GAMEPLAYING_SEARCHPLAYER_TCC
00005 #include "osl/game_playing/searchPlayer.h"
00006 #include "osl/game_playing/gameState.h"
00007 #include "osl/game_playing/pvHistory.h"
00008 #include "osl/search/searchState2.h"
00009 #include "osl/eval/evalTraits.h"
00010 #include "osl/container/moveStack.h"
00011 
00012 #ifdef USE_NTESUKI
00013 #  include "osl/ntesuki/ntesukiSearcher.h"
00014 #  include "osl/ntesuki/ntesukiMoveGenerator.h"
00015 #endif
00016 
00017 #include <boost/scoped_ptr.hpp>
00018 #include <boost/foreach.hpp>
00019 
00020 #ifdef USE_NTESUKI
00021 struct
00022 osl::game_playing::SearchPlayer::NtesukiThread
00023 {
00024   explicit NtesukiThread(Move& next_move,
00025                          volatile bool *thread_finished,
00026                          volatile bool *stop_flag,
00027                          NumEffectState state);
00028 
00029   void operator()();
00030 
00031   Move& next_move;
00032   volatile bool *thread_finished;
00033   volatile bool *stop_flag;
00034   NumEffectState state;
00035 };
00036 #endif
00037 
00038 template <class Searcher>
00039 osl::game_playing::ComputerPlayer* osl::game_playing::
00040 SearchPlayer::cloneIt(const Searcher& copy) const
00041 {
00042   return new Searcher(copy);
00043 }
00044 
00045 template <class Searcher>
00046 int osl::game_playing::
00047 SearchPlayer::pawnValue()
00048 {
00049   typedef typename Searcher::eval_t eval_t;
00050   return abs(eval_t::captureValue(newPtypeO(BLACK,PAWN)))/2;
00051 }
00052 template <class Searcher>
00053 int osl::game_playing::
00054 SearchPlayer::pawnValueOfTurn(Player turn)
00055 {
00056   return pawnValue<Searcher>() * eval::delta(turn);
00057 }
00058 
00059 template <class Searcher>
00060 const osl::search::MoveWithComment osl::game_playing::
00061 SearchPlayer::search(const GameState& state, const search::TimeAssigned& msec)
00062 {
00063   Searcher& searcher = dynamic_cast<Searcher&>(*this->searcher);
00064   searcher.setRootIgnoreMoves(root_ignore_moves, prediction_for_speculative_search);
00065   
00066   typedef typename Searcher::eval_t eval_t;
00067   if (! eval_t::initialized())
00068     throw std::runtime_error("evaluation function not initialized");
00069   
00070   const MoveStack& history = state.moveHistory();
00071 
00072 #ifdef USE_NTESUKI
00073   volatile bool ntesuki_thread_finished;
00074   volatile bool stop_ntesuki;
00075   Move ntesuki_next_move = Move::INVALID();
00076 
00077   NtesukiThread thread(ntesuki_next_move, &ntesuki_thread_finished,
00078                        &stop_ntesuki, state.state());
00079   boost::thread ntesuki_thread(thread);
00080 #endif
00081   searcher.setHistory(history);
00082   searcher.enableMultiPV(config.multi_pv_width);
00083   BOOST_FOREACH(const boost::shared_ptr<search::SearchMonitor>& m,
00084                 config.monitors)
00085     searcher.addMonitor(m);
00086   int deepening_step_for_this_move = config.deepening_step;
00087   if (! msec.standard.isInfinity())
00088   {
00089     if (msec.standard.toSeconds() < 10.0)
00090       deepening_step_for_this_move = std::min(100, config.deepening_step);
00091   }
00092   searcher.setNextIterationCoefficient(config.next_iteration_coefficient);
00093   searcher.setNodeCountHardLimit(config.node_count_hard_limit);
00094 
00095   MoveWithComment best_move;
00096   best_move.root = HashKey(state.state());
00097   if (plan_stop)
00098     return best_move;
00099 
00100   searching = true;
00101   best_move.move 
00102     = searcher.computeBestMoveIteratively(config.limit, 
00103                                           deepening_step_for_this_move,
00104                                           config.initial_limit,
00105                                           config.node_limit,
00106                                           msec,
00107                                           &best_move);
00108   searching = false;
00109 #ifdef USE_NTESUKI
00110   if (ntesuki_thread_finished)
00111   {
00112     if (ntesuki_next_move.isNormal())
00113     {
00114       return ntesuki_next_move;
00115     }
00116     else
00117     {
00118       //ntesuki_finished
00119     }
00120   }
00121   else
00122   {
00123     //force_finish
00124     stop_ntesuki = true;
00125     ntesuki_thread.join();
00126   }
00127 #endif
00128   saveSearchResult(state, best_move);
00129   static const int resign_value = OslConfig::resignThreshold();
00130   if (! state.state().inCheck() && best_move.move.isNormal()
00131       && best_move.value*playerToMul(state.state().turn()) < -resign_value) 
00132   {
00133     ++almost_resign_count;
00134     if (almost_resign_count >= 3)
00135       best_move.move = Move();
00136   }
00137   else 
00138   {
00139     almost_resign_count = 0;
00140   }
00141   return best_move;
00142 }
00143 
00144 template <class Searcher>
00145 bool osl::game_playing::
00146 SearchPlayer::isReasonableMoveBySearch(Searcher& searcher, Move move, int pawn_sacrifice)
00147 {
00148   return searcher.isReasonableMove(move, pawn_sacrifice);
00149 }
00150 
00151 #endif /* GAMEPLAYING_SEARCHPLAYER_TCC */
00152 // ;;; Local Variables:
00153 // ;;; mode:c++
00154 // ;;; c-basic-offset:2
00155 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines