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/checkmate/dualCheckmateSearcher.h"
00008 #include "osl/eval/evalTraits.h"
00009 #ifdef MORE_BIGRAM
00010 # include "osl/category/bigramPosition.h"
00011 #endif
00012 #include "osl/container/moveStack.h"
00013 #include "osl/misc/realTime.h"
00014
00015 #ifdef USE_NTESUKI
00016 # include "osl/ntesuki/ntesukiSearcher.h"
00017 # include "osl/ntesuki/ntesukiMoveGenerator.h"
00018 #endif
00019
00020 #include <boost/scoped_ptr.hpp>
00021
00022 struct osl::game_playing::SearchPlayer::CheckmateSearcher
00023 : public osl::checkmate::DualCheckmateSearcher<>
00024 {
00025 explicit CheckmateSearcher(size_t node_limit)
00026 : DualCheckmateSearcher<>(node_limit)
00027 {
00028 }
00029 };
00030
00031 struct osl::game_playing::SearchPlayer::KeyOfMove
00032 {
00033 HashKey root;
00034 Move best_move;
00035 };
00036
00037 #ifdef USE_NTESUKI
00038 struct
00039 osl::game_playing::SearchPlayer::NtesukiThread
00040 {
00041 explicit NtesukiThread(Move& next_move,
00042 volatile bool *thread_finished,
00043 volatile bool *stop_flag,
00044 NumEffectState state);
00045
00046 void operator()();
00047
00048 Move& next_move;
00049 volatile bool *thread_finished;
00050 volatile bool *stop_flag;
00051 NumEffectState state;
00052 };
00053 #endif
00054
00055 template <class Searcher>
00056 osl::game_playing::ComputerPlayer* osl::game_playing::
00057 SearchPlayer::cloneIt(const Searcher& copy) const
00058 {
00059 return new Searcher(copy);
00060 }
00061
00062 template <class Searcher>
00063 int osl::game_playing::
00064 SearchPlayer::pawnValue()
00065 {
00066 typedef typename Searcher::eval_t eval_t;
00067 return abs(eval_t::captureValue(newPtypeO(BLACK,PAWN)))/2;
00068 }
00069 template <class Searcher>
00070 int osl::game_playing::
00071 SearchPlayer::pawnValueOfTurn(Player turn)
00072 {
00073 return pawnValue<Searcher>() * eval::delta(turn);
00074 }
00075
00076 template <class Searcher>
00077 const osl::game_playing::MoveWithComment osl::game_playing::
00078 SearchPlayer::search(const GameState& state, int seconds_for_this_move)
00079 {
00080 Searcher& searcher = dynamic_cast<Searcher&>(*this->searcher);
00081 searcher.setRootIgnoreMoves(root_ignore_moves);
00082
00083 typedef typename Searcher::eval_t eval_t;
00084 if (! eval_t::initialized())
00085 throw std::runtime_error("evaluation function not initialized");
00086
00087 const MoveStack& history = state.moveHistory();
00088
00089 #ifdef USE_NTESUKI
00090 volatile bool ntesuki_thread_finished;
00091 volatile bool stop_ntesuki;
00092 Move ntesuki_next_move = Move::INVALID();
00093
00094 NtesukiThread thread(ntesuki_next_move, &ntesuki_thread_finished,
00095 &stop_ntesuki, state.state());
00096 boost::thread ntesuki_thread(thread);
00097 #endif
00098 #ifdef MORE_BIGRAM
00099 category::BigramHistory::setupTable(state.getInitialState(),
00100 state.state(), history);
00101 #endif
00102 searcher.setHistory(history);
00103 #ifdef GLOBAL_BIGRAMKILLERMOVE
00104 searcher.setBigramKillerMove(*bigram_ptr);
00105 #endif
00106 int deepening_step_for_this_move = config.deepening_step;
00107 if (seconds_for_this_move > 0)
00108 {
00109 if (seconds_for_this_move < 10)
00110 deepening_step_for_this_move = std::min(100, config.deepening_step);
00111 }
00112 searcher.setNextIterationCoefficient(config.next_iteration_coefficient);
00113
00114 MoveWithComment best_move;
00115 if (plan_stop)
00116 return best_move;
00117
00118 stop_flag = searcher.alarmSwitch();
00119 best_move.move
00120 = searcher.computeBestMoveIteratively(config.limit,
00121 deepening_step_for_this_move,
00122 config.initial_limit,
00123 config.node_limit,
00124 misc::RealTime(seconds_for_this_move));
00125
00126 fillMoveComment(best_move, state, table(), pawnValue<Searcher>());
00127 stop_flag = AlarmSwitch(0);
00128 #ifdef GLOBAL_BIGRAMKILLERMOVE
00129 *bigram_ptr = searcher.bigramKillerMove();
00130 #endif
00131 key_of_move->root = state.state().getHash();
00132 key_of_move->best_move = best_move.move;
00133 #ifdef USE_NTESUKI
00134 if (ntesuki_thread_finished)
00135 {
00136 if (ntesuki_next_move.isNormal())
00137 {
00138 return ntesuki_next_move;
00139 }
00140 else
00141 {
00142
00143 }
00144 }
00145 else
00146 {
00147
00148 stop_ntesuki = true;
00149 ntesuki_thread.join();
00150 }
00151 #endif
00152 return best_move;
00153 }
00154
00155 template <class Searcher>
00156 bool osl::game_playing::
00157 SearchPlayer::isReasonableMoveBySearch(Searcher& searcher, Move move, int pawn_sacrifice)
00158 {
00159 return searcher.isReasonableMove(move, pawn_sacrifice);
00160 }
00161
00162 #endif
00163
00164
00165
00166