00001 //---------------------------------------------------------------------------- 00002 /** @file HexUctUtil.cpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "SgSystem.h" 00007 #include "Hex.hpp" 00008 #include "HexUctUtil.hpp" 00009 00010 #include <iomanip> 00011 #include <iostream> 00012 #include "SgBWSet.h" 00013 #include "SgPointSet.h" 00014 #include "SgProp.h" 00015 #include "SgUctSearch.h" 00016 00017 using namespace benzene; 00018 00019 //---------------------------------------------------------------------------- 00020 00021 void GoGuiGfxStatus(const SgUctSearch& search, std::ostream& out) 00022 { 00023 const SgUctTree& tree = search.Tree(); 00024 const SgUctNode& root = tree.Root(); 00025 const SgUctSearchStat& stat = search.Statistics(); 00026 int abortPercent = static_cast<int>(stat.m_aborted.Mean() * 100); 00027 out << "TEXT N=" << static_cast<size_t>(root.MoveCount()) 00028 << " V=" << std::setprecision(2) << root.Mean() 00029 << " Len=" << static_cast<int>(stat.m_gameLength.Mean()) 00030 << " Tree=" << std::setprecision(1) << stat.m_movesInTree.Mean() 00031 << "/" << static_cast<int>(stat.m_movesInTree.Max()) 00032 << " Abrt=" << abortPercent << '%' 00033 << " Gm/s=" << static_cast<int>(stat.m_gamesPerSecond) << '\n'; 00034 } 00035 00036 void HexUctUtil::GoGuiGfx(const SgUctSearch& search, SgBlackWhite toPlay, 00037 std::ostream& out) 00038 { 00039 const SgUctTree& tree = search.Tree(); 00040 const SgUctNode& root = tree.Root(); 00041 out << "VAR"; 00042 std::vector<const SgUctNode*> bestValueChild; 00043 bestValueChild.push_back(search.FindBestChild(root)); 00044 for (int i=0; i<4; i++) { 00045 if (bestValueChild[i] == 0) break; 00046 SgPoint move = bestValueChild[i]->Move(); 00047 if (0 == (i % 2)) 00048 out << ' ' << (toPlay == SG_BLACK ? 'B' : 'W') << ' ' 00049 << HexUctUtil::MoveString(move); 00050 else 00051 out << ' ' << (toPlay == SG_WHITE ? 'B' : 'W') << ' ' 00052 << HexUctUtil::MoveString(move); 00053 bestValueChild.push_back(search.FindBestChild(*(bestValueChild[i]))); 00054 } 00055 out << "\n"; 00056 out << "INFLUENCE"; 00057 for (SgUctChildIterator it(tree, root); it; ++it) 00058 { 00059 const SgUctNode& child = *it; 00060 if (child.MoveCount() == 0) 00061 continue; 00062 float influence = search.InverseEval(child.Mean()); 00063 SgPoint move = child.Move(); 00064 out << ' ' << HexUctUtil::MoveString(move) << ' ' 00065 << std::fixed << std::setprecision(2) << influence; 00066 } 00067 out << '\n' 00068 << "LABEL"; 00069 int numChildren = 0; 00070 for (SgUctChildIterator it(tree, root); it; ++it) 00071 { 00072 const SgUctNode& child = *it; 00073 size_t count = static_cast<size_t>(child.MoveCount()); 00074 numChildren++; 00075 out << ' ' << HexUctUtil::MoveString(child.Move()) 00076 << ' ' << count; 00077 } 00078 out << '\n'; 00079 GoGuiGfxStatus(search, out); 00080 } 00081 00082 int HexUctUtil::ComputeMaxNumMoves() 00083 { 00084 return FIRST_INVALID; 00085 } 00086 00087 std::string HexUctUtil::MoveString(SgMove sgmove) 00088 { 00089 HexPoint move = static_cast<HexPoint>(sgmove); 00090 00091 // Simple process if just HexPoint 00092 HexAssert(0 <= move && move < FIRST_INVALID); 00093 return HexPointUtil::ToString(move); 00094 } 00095 00096 SgBlackWhite HexUctUtil::ToSgBlackWhite(HexColor c) 00097 { 00098 if (c == BLACK) 00099 return SG_BLACK; 00100 HexAssert(c == WHITE); 00101 return SG_WHITE; 00102 } 00103 00104 //---------------------------------------------------------------------------- 00105 00106 namespace 00107 { 00108 00109 void SaveNode(std::ostream& out, const SgUctTree& tree, const SgUctNode& node, 00110 HexColor toPlay, int maxDepth, int depth) 00111 { 00112 out << "C[MoveCount " << node.MoveCount() 00113 << "\nPosCount " << node.PosCount() 00114 << "\nMean " << std::fixed << std::setprecision(2) << node.Mean(); 00115 if (!node.HasChildren()) 00116 { 00117 out << "]\n"; 00118 return; 00119 } 00120 out << "\n\nRave:"; 00121 for (SgUctChildIterator it(tree, node); it; ++it) 00122 { 00123 const SgUctNode& child = *it; 00124 HexPoint move = static_cast<HexPoint>(child.Move()); 00125 if (child.HasRaveValue()) 00126 { 00127 out << '\n' << HexUctUtil::MoveString(move) << ' ' 00128 << std::fixed << std::setprecision(2) << child.RaveValue() 00129 << " (" << child.RaveCount() << ')'; 00130 } 00131 } 00132 out << "]\nLB"; 00133 for (SgUctChildIterator it(tree, node); it; ++it) 00134 { 00135 const SgUctNode& child = *it; 00136 if (! child.HasMean()) 00137 continue; 00138 HexPoint move = static_cast<HexPoint>(child.Move()); 00139 out << "[" << HexUctUtil::MoveString(move) << ':' 00140 << child.MoveCount() << '@' << child.Mean() << ']'; 00141 } 00142 out << '\n'; 00143 if (maxDepth >= 0 && depth >= maxDepth) 00144 return; 00145 for (SgUctChildIterator it(tree, node); it; ++it) 00146 { 00147 const SgUctNode& child = *it; 00148 if (! child.HasMean()) 00149 continue; 00150 HexPoint move = static_cast<HexPoint>(child.Move()); 00151 out << "(;" << (toPlay == BLACK ? 'B' : 'W') 00152 << '[' << HexUctUtil::MoveString(move) << ']'; 00153 SaveNode(out, tree, child, !toPlay, maxDepth, depth + 1); 00154 out << ")\n"; 00155 } 00156 } 00157 00158 } 00159 00160 void HexUctUtil::SaveTree(const SgUctTree& tree, const StoneBoard& brd, 00161 HexColor toPlay, std::ostream& out, int maxDepth) 00162 { 00163 out << "(;FF[4]GM[11]SZ[" << brd.Width() << "]\n"; 00164 out << ";AB"; 00165 for (BoardIterator it(brd.Stones(BLACK)); it; ++it) 00166 out << '[' << *it << ']'; 00167 out << '\n'; 00168 out << "AW"; 00169 for (BoardIterator it(brd.Stones(WHITE)); it; ++it) 00170 out << '[' << *it << ']'; 00171 out << '\n'; 00172 out << "AE"; 00173 for (BoardIterator it(brd.Stones(EMPTY)); it; ++it) 00174 out << '[' << *it << ']'; 00175 out << '\n'; 00176 out << "PL[" << (toPlay == SG_BLACK ? "B" : "W") << "]\n"; 00177 SaveNode(out, tree, tree.Root(), toPlay, maxDepth, 0); 00178 out << ")\n"; 00179 } 00180 00181 //---------------------------------------------------------------------------- 00182 00183