00001
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
00110 #ifdef USE_NTESUKI
00111 if (ntesuki_thread_finished)
00112 {
00113 if (ntesuki_next_move.isNormal())
00114 {
00115 return ntesuki_next_move;
00116 }
00117 else
00118 {
00119
00120 }
00121 }
00122 else
00123 {
00124
00125 stop_ntesuki = true;
00126 ntesuki_thread.join();
00127 }
00128 #endif
00129 saveSearchResult(state, best_move);
00130 return best_move;
00131 }
00132
00133 template <class Searcher>
00134 bool osl::game_playing::
00135 SearchPlayer::isReasonableMoveBySearch(Searcher& searcher, Move move, int pawn_sacrifice)
00136 {
00137 return searcher.isReasonableMove(move, pawn_sacrifice);
00138 }
00139
00140 #endif
00141
00142
00143
00144