00001 //---------------------------------------------------------------------------- 00002 /** @file WolvePlayer.hpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef WOLVEPLAYER_HPP 00007 #define WOLVEPLAYER_HPP 00008 00009 #include <boost/scoped_ptr.hpp> 00010 #include <boost/thread/barrier.hpp> 00011 #include <boost/thread/condition.hpp> 00012 #include <boost/thread/mutex.hpp> 00013 #include <boost/thread/thread.hpp> 00014 00015 #include "BenzenePlayer.hpp" 00016 #include "TwoDistance.hpp" 00017 #include "HexAbSearch.hpp" 00018 #include "Resistance.hpp" 00019 00020 _BEGIN_BENZENE_NAMESPACE_ 00021 00022 //---------------------------------------------------------------------------- 00023 00024 /** Varaition TT entry. */ 00025 struct VariationInfo 00026 { 00027 VariationInfo() 00028 : depth(-1) 00029 { } 00030 00031 VariationInfo(int d, const bitset_t& con) 00032 : depth(d), consider(con) 00033 { } 00034 00035 ~VariationInfo(); 00036 00037 bool Initialized() const; 00038 00039 void CheckCollision(const VariationInfo& other) const; 00040 00041 bool ReplaceWith(const VariationInfo& other) const; 00042 00043 //------------------------------------------------------------------------ 00044 00045 /** Depth state was searched. */ 00046 int depth; 00047 00048 /** Moves to consider from this variation. */ 00049 bitset_t consider; 00050 }; 00051 00052 inline VariationInfo::~VariationInfo() 00053 { 00054 } 00055 00056 inline bool VariationInfo::Initialized() const 00057 { 00058 return (depth != -1); 00059 } 00060 00061 inline void VariationInfo::CheckCollision(const VariationInfo& other) const 00062 { 00063 UNUSED(other); 00064 } 00065 00066 inline bool VariationInfo::ReplaceWith(const VariationInfo& other) const 00067 { 00068 /** @todo check for better bounds/scores? */ 00069 00070 // replace this state only with a deeper state 00071 return (other.depth > depth); 00072 } 00073 00074 //-------------------------------------------------------------------------- 00075 00076 /** Performs an AlphaBeta search using Resistance for evaluations. 00077 00078 @todo Switch to SgSearch instead of HexAbSearch? 00079 */ 00080 class WolveSearch : public HexAbSearch 00081 { 00082 public: 00083 WolveSearch(); 00084 00085 virtual ~WolveSearch(); 00086 00087 //----------------------------------------------------------------------- 00088 00089 /** Moves to consider in the root state -- this set is used 00090 instead of the GenerateMoves() since it could have more 00091 knowledge. */ 00092 bitset_t RootMovesToConsider() const; 00093 00094 /** See RootMovesToConsider() */ 00095 void SetRootMovesToConsider(const bitset_t& consider); 00096 00097 //----------------------------------------------------------------------- 00098 00099 /** @name Virtual methods from HexAbSearch. */ 00100 // @{ 00101 00102 virtual HexEval Evaluate(); 00103 00104 virtual void GenerateMoves(std::vector<HexPoint>& moves); 00105 00106 virtual void ExecuteMove(HexPoint move); 00107 00108 virtual void UndoMove(HexPoint move); 00109 00110 virtual void EnteredNewState(); 00111 00112 virtual void OnStartSearch(); 00113 00114 virtual void OnSearchComplete(); 00115 00116 virtual void AfterStateSearched(); 00117 00118 // @} 00119 00120 //----------------------------------------------------------------------- 00121 00122 /** @name Parameters */ 00123 // @{ 00124 00125 /** Whether the backed-up ice info is used to reduce the moves to 00126 consider after a state has been searched. This is useful if 00127 using iterative deepening, since the next time the state is 00128 visited a smaller number of moves need to be considered. */ 00129 bool BackupIceInfo() const; 00130 00131 /** BackupIceInfo() */ 00132 void SetBackupIceInfo(bool enable); 00133 00134 // @} 00135 00136 private: 00137 /** Computes the evaluation on the no_fillin_board (if it exists) 00138 using the ConductanceGraph from m_brd. */ 00139 void ComputeResistance(Resistance& resist); 00140 00141 /** Consider sets for each depth. */ 00142 std::vector<bitset_t> m_consider; 00143 00144 /** See RootMovesToConsider() */ 00145 bitset_t m_rootMTC; 00146 00147 /** Variation TT. */ 00148 TransTable<VariationInfo> m_varTT; 00149 00150 /** See BackupIceInfo() */ 00151 bool m_backup_ice_info; 00152 }; 00153 00154 inline bitset_t WolveSearch::RootMovesToConsider() const 00155 { 00156 return m_rootMTC; 00157 } 00158 00159 inline void WolveSearch::SetRootMovesToConsider(const bitset_t& consider) 00160 { 00161 m_rootMTC = consider; 00162 } 00163 00164 inline bool WolveSearch::BackupIceInfo() const 00165 { 00166 return m_backup_ice_info; 00167 } 00168 00169 inline void WolveSearch::SetBackupIceInfo(bool enable) 00170 { 00171 m_backup_ice_info = enable; 00172 } 00173 00174 //---------------------------------------------------------------------------- 00175 00176 /** Player using HexAbSearch to generate moves. */ 00177 class WolvePlayer : public BenzenePlayer 00178 { 00179 public: 00180 explicit WolvePlayer(); 00181 00182 virtual ~WolvePlayer(); 00183 00184 /** Returns "wolve". */ 00185 std::string Name() const; 00186 00187 /** Returns the search. */ 00188 WolveSearch& Search(); 00189 00190 //----------------------------------------------------------------------- 00191 00192 /** @name Parameters */ 00193 // @{ 00194 00195 /** Number of moves to consider at each depth after move 00196 ordering. */ 00197 const std::vector<int>& PlyWidth() const; 00198 00199 /** See PlyWidth() */ 00200 void SetPlyWidth(const std::vector<int>& width); 00201 00202 /** Depths to search if using iterative deepening. 00203 See UseIterativeDeepening(). */ 00204 const std::vector<int>& SearchDepths() const; 00205 00206 /** See UseIterativeDeepening() */ 00207 void SetSearchDepths(const std::vector<int>& depths); 00208 00209 /** When time remaining is less than this, max search depth is set 00210 to 4. A value of zero turns this option off. */ 00211 double PanicTime() const; 00212 00213 /** See PanicTime() */ 00214 void SetPanicTime(double time); 00215 00216 // @} 00217 00218 private: 00219 WolveSearch m_search; 00220 00221 /** TT for search. */ 00222 SearchTT m_tt; 00223 00224 /** See PlyWidths() */ 00225 std::vector<int> m_plywidth; 00226 00227 /** See SearchDepths() */ 00228 std::vector<int> m_search_depths; 00229 00230 /** See PanicTime() */ 00231 double m_panic_time; 00232 00233 void CheckPanicMode(double timeRemaining, std::vector<int>& search_depths, 00234 std::vector<int>& plywidth); 00235 00236 virtual HexPoint Search(const HexState& state, const Game& game, 00237 HexBoard& brd, const bitset_t& consider, 00238 double maxTime, double& score); 00239 }; 00240 00241 inline std::string WolvePlayer::Name() const 00242 { 00243 return "wolve"; 00244 } 00245 00246 inline WolveSearch& WolvePlayer::Search() 00247 { 00248 return m_search; 00249 } 00250 00251 inline const std::vector<int>& WolvePlayer::PlyWidth() const 00252 { 00253 return m_plywidth; 00254 } 00255 00256 inline void WolvePlayer::SetPlyWidth(const std::vector<int>& width) 00257 { 00258 m_plywidth = width; 00259 } 00260 00261 inline const std::vector<int>& WolvePlayer::SearchDepths() const 00262 { 00263 return m_search_depths; 00264 } 00265 00266 inline void WolvePlayer::SetSearchDepths(const std::vector<int>& depths) 00267 { 00268 m_search_depths = depths; 00269 } 00270 00271 inline double WolvePlayer::PanicTime() const 00272 { 00273 return m_panic_time; 00274 } 00275 00276 inline void WolvePlayer::SetPanicTime(double time) 00277 { 00278 m_panic_time = time; 00279 } 00280 00281 //---------------------------------------------------------------------------- 00282 00283 _END_BENZENE_NAMESPACE_ 00284 00285 #endif // WOLVEPLAYER_HPP