00001 #ifndef GAME_PLAYING_SEARCHPLAYER_H
00002 #define GAME_PLAYING_SEARCHPLAYER_H
00003
00004 #include "osl/game_playing/computerPlayer.h"
00005 #include "osl/search/searchTimer.h"
00006 #include "osl/misc/milliSeconds.h"
00007 #include "osl/container/moveVector.h"
00008 #include <boost/scoped_ptr.hpp>
00009 #include <boost/shared_ptr.hpp>
00010
00011 namespace osl
00012 {
00013 namespace misc
00014 {
00015 class RealTime;
00016 }
00017 namespace search
00018 {
00019 class CountRecorder;
00020 class SimpleHashTable;
00021 class TimeAssigned;
00022 class SearchMonitor;
00023 }
00024 namespace checkmate
00025 {
00026 class DualDfpn;
00027 }
00028 namespace game_playing
00029 {
00030 struct Config;
00031 bool operator==(const Config& l, const Config& r);
00032 class PVHistory;
00036 class SearchPlayer
00037 : public ComputerPlayer,
00038 public ComputerPlayerSelectBestMoveInTime
00039 {
00040 public:
00041 struct NtesukiThread;
00042 struct Config
00043 {
00044 int limit;
00045 size_t node_limit;
00046 size_t table_size;
00047 int table_record_limit;
00048 int initial_limit;
00049 int deepening_step;
00050 size_t total_checkmate_limit;
00051 int verbose;
00053 double next_iteration_coefficient;
00055 int draw_coef;
00056 bool save_pv;
00057 uint64_t node_count_hard_limit;
00059 int multi_pv_width;
00060 vector<boost::shared_ptr<search::SearchMonitor> > monitors;
00061
00062 Config();
00063 friend bool operator==(const Config& l, const Config& r);
00064 };
00065 protected:
00066 Config config;
00067 boost::shared_ptr<search::SimpleHashTable> table_ptr;
00068 boost::shared_ptr<checkmate::DualDfpn> checkmate_ptr;
00069 boost::scoped_ptr<search::CountRecorder> recorder_ptr;
00070 volatile bool searching;
00071 boost::scoped_ptr<search::SearchTimer> searcher;
00073 volatile bool plan_stop;
00074 const MoveVector *root_ignore_moves;
00075 bool prediction_for_speculative_search;
00076 boost::scoped_ptr<PVHistory> pv_history;
00077 public:
00078 SearchPlayer();
00079 SearchPlayer(const SearchPlayer&);
00080 ~SearchPlayer();
00081
00082 void setDepthLimit(int limit, int initial_limit, int deepening_step);
00083 void setNodeLimit(size_t node_limit);
00084 void setNodeCountHardLimit(size_t node_limit);
00085 void setTableLimit(size_t size, int record_limit);
00086 void setVerbose(int verbose=1);
00087 void setDrawCoef(int new_value) { config.draw_coef = new_value; }
00088 void setNextIterationCoefficient(double new_value);
00089 void enableSavePV(bool enable=true) { config.save_pv = enable; }
00090 void enableMultiPV(int width) { config.multi_pv_width = width; }
00091 void addMonitor(const boost::shared_ptr<search::SearchMonitor>&);
00092
00094 void resetRecorder(search::CountRecorder *new_recorder);
00095
00096 void pushMove(Move m);
00097 void popMove();
00098
00102 void swapTable(SearchPlayer& other);
00103
00104 const search::SimpleHashTable* table() const { return table_ptr.get(); }
00105 const search::CountRecorder& recorder() const { return *recorder_ptr; }
00106
00107 bool stopSearchNow();
00108 bool canStopSearch();
00112 const MoveWithComment selectBestMove(const GameState&, int, int, int);
00113 const MoveWithComment selectBestMoveInTime(const GameState&, const search::TimeAssigned&);
00114 static const search::TimeAssigned assignTime(const GameState& state, int limit, int elapsed,
00115 int byoyomi, int verbose);
00116 const search::TimeAssigned assignTime(const GameState& state, int limit, int elapsed,
00117 int byoyomi) const;
00118 void saveSearchResult(const GameState&, const MoveWithComment&);
00119 protected:
00120 template <class Searcher>
00121 ComputerPlayer* cloneIt(const Searcher&) const;
00123 const MilliSeconds::Interval setUpTable(const GameState&, int pawn_value);
00124 template <class Searcher>
00125 const MoveWithComment search(const GameState&, const search::TimeAssigned&);
00126 template <class Searcher>
00127 bool isReasonableMoveBySearch(Searcher&, Move move, int pawn_sacrifice);
00128 template <class Searcher>
00129 static int pawnValue();
00130 template <class Searcher>
00131 static int pawnValueOfTurn(Player turn);
00132 const search::TimeAssigned adjust(const search::TimeAssigned& org, const MilliSeconds::Interval& elapsed);
00133 public:
00134 virtual const MoveWithComment searchWithSecondsForThisMove(const GameState&, const search::TimeAssigned&)=0;
00135 void setRootIgnoreMoves(const MoveVector *rim, bool prediction)
00136 {
00137 root_ignore_moves = rim;
00138 prediction_for_speculative_search = prediction;
00139 }
00140
00141 const Config& getConfig() const { return config; }
00142
00143 static int secondsForThisMove(const GameState& state,
00144 int limit, int elapsed, int byoyomi, int verboseness);
00145 int secondsForThisMove(const GameState& state, int limit, int elapsed, int byoyomi) const;
00146
00147 void setTimeAssign(const search::TimeAssigned& new_assign);
00148 const MilliSeconds startTime() const;
00149 };
00150
00151 }
00152 }
00153
00154 #endif
00155
00156
00157
00158