WolvePlayer.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "BitsetIterator.hpp"
00007 #include "VCSet.hpp"
00008 #include "HexEval.hpp"
00009 #include "Misc.hpp"
00010 #include "EndgameUtils.hpp"
00011 #include "SequenceHash.hpp"
00012 #include "WolvePlayer.hpp"
00013
00014 using namespace benzene;
00015
00016
00017
00018 WolvePlayer::WolvePlayer()
00019 : BenzenePlayer(),
00020 m_tt(16),
00021 m_plywidth(),
00022 m_search_depths(),
00023 m_panic_time(240)
00024 {
00025 m_plywidth.push_back(20);
00026 m_plywidth.push_back(20);
00027 m_plywidth.push_back(20);
00028 m_plywidth.push_back(20);
00029 m_search_depths.push_back(1);
00030 m_search_depths.push_back(2);
00031 m_search_depths.push_back(4);
00032 m_search.SetTT(&m_tt);
00033 }
00034
00035 WolvePlayer::~WolvePlayer()
00036 {
00037 }
00038
00039
00040
00041
00042 void WolvePlayer::CheckPanicMode(double timeRemaining,
00043 std::vector<int>& search_depths,
00044 std::vector<int>& plywidth)
00045 {
00046
00047 if (m_panic_time >= 0.01 && timeRemaining < m_panic_time)
00048 {
00049 std::vector<int> new_search_depths;
00050 for (std::size_t i = 0; i < search_depths.size(); ++i)
00051 if (search_depths[i] <= 4)
00052 new_search_depths.push_back(search_depths[i]);
00053 search_depths = new_search_depths;
00054
00055 for (std::size_t i = 0; i < plywidth.size(); ++i)
00056 plywidth[i] = std::max(plywidth[i], 15);
00057 LogWarning() << "############# PANIC MODE #############\n";
00058 }
00059 }
00060
00061
00062 HexPoint WolvePlayer::Search(const HexState& state, const Game& game,
00063 HexBoard& brd, const bitset_t& consider,
00064 double maxTime, double& score)
00065 {
00066 UNUSED(game);
00067 std::vector<int> search_depths = m_search_depths;
00068 std::vector<int> plywidth = m_plywidth;
00069
00070 CheckPanicMode(maxTime, search_depths, plywidth);
00071
00072 m_search.SetRootMovesToConsider(consider);
00073 LogInfo() << "Using consider set:" << brd.Write(consider) << '\n'
00074 << "Plywidths: " << MiscUtil::PrintVector(plywidth) << '\n'
00075 << "Depths: " << MiscUtil::PrintVector(search_depths) << '\n';
00076
00077 std::vector<HexPoint> PV;
00078 score = m_search.Search(brd, state.ToPlay(), plywidth,
00079 search_depths, -1, PV);
00080
00081 LogInfo() << m_search.DumpStats() << '\n';
00082
00083 HexAssert(PV.size() > 0);
00084 return PV[0];
00085 }
00086
00087
00088
00089 WolveSearch::WolveSearch()
00090 : m_varTT(16),
00091 m_backup_ice_info(true)
00092 {
00093 }
00094
00095 WolveSearch::~WolveSearch()
00096 {
00097 }
00098
00099 void WolveSearch::OnStartSearch()
00100 {
00101 m_varTT.Clear();
00102 m_consider.clear();
00103 }
00104
00105 void WolveSearch::EnteredNewState()
00106 {
00107 }
00108
00109 HexEval WolveSearch::Evaluate()
00110 {
00111 Resistance resist;
00112 ComputeResistance(resist);
00113 HexEval score = (m_toplay == BLACK) ? resist.Score() : -resist.Score();
00114 LogFine() << "Score for " << m_toplay << ": " << score << '\n';
00115 return score;
00116 }
00117
00118 void WolveSearch::GenerateMoves(std::vector<HexPoint>& moves)
00119 {
00120 Resistance resist;
00121 ComputeResistance(resist);
00122
00123
00124
00125
00126
00127 bitset_t consider;
00128
00129 VariationInfo varInfo;
00130 if (m_varTT.Get(SequenceHash::Hash(m_sequence), varInfo))
00131 {
00132 LogFine() << "Using consider set from TT.\n"
00133 << HexPointUtil::ToString(m_sequence) << '\n'
00134 << m_brd << '\n';
00135 consider = varInfo.consider;
00136 }
00137 else if (m_current_depth == 0)
00138 {
00139 LogFine() << "Using root consider set.\n";
00140 consider = m_rootMTC;
00141 }
00142 else
00143 {
00144 LogFine() << "Computing our own consider set.\n";
00145 consider = EndgameUtils::MovesToConsider(*m_brd, m_toplay);
00146 }
00147
00148 m_consider.push_back(consider);
00149 HexAssert((int)m_consider.size() == m_current_depth+1);
00150
00151
00152 moves.clear();
00153 std::vector<std::pair<HexEval, HexPoint> > mvsc;
00154 for (BitsetIterator it(consider); it; ++it)
00155 {
00156
00157 HexEval score = (*it == m_tt_bestmove)
00158 ? 10000
00159 : resist.Score(*it);
00160 mvsc.push_back(std::make_pair(-score, *it));
00161 }
00162
00163 stable_sort(mvsc.begin(), mvsc.end());
00164 for (std::size_t i = 0; i < mvsc.size(); ++i)
00165 moves.push_back(mvsc[i].second);
00166 }
00167
00168 void WolveSearch::ExecuteMove(HexPoint move)
00169 {
00170 m_brd->PlayMove(m_toplay, move);
00171 }
00172
00173 void WolveSearch::UndoMove(HexPoint move)
00174 {
00175 UNUSED(move);
00176 m_brd->UndoMove();
00177 }
00178
00179 void WolveSearch::AfterStateSearched()
00180 {
00181 if (m_backup_ice_info)
00182 {
00183
00184 bitset_t old_consider = m_consider[m_current_depth];
00185 bitset_t new_consider
00186 = EndgameUtils::MovesToConsider(*m_brd, m_toplay) & old_consider;
00187 hash_t hash = SequenceHash::Hash(m_sequence);
00188 m_varTT.Put(hash, VariationInfo(m_current_depth, new_consider));
00189 }
00190 m_consider.pop_back();
00191 }
00192
00193 void WolveSearch::OnSearchComplete()
00194 {
00195 }
00196
00197
00198
00199 void WolveSearch::ComputeResistance(Resistance& resist)
00200 {
00201 StoneBoard plain(m_brd->Width(), m_brd->Height());
00202 plain.SetPosition(m_brd->GetPosition());
00203 Groups groups;
00204 GroupBuilder::Build(plain, groups);
00205 AdjacencyGraph graphs[BLACK_AND_WHITE];
00206 ResistanceUtil::AddAdjacencies(*m_brd, graphs);
00207 resist.Evaluate(groups, graphs);
00208 }
00209
00210