00001 //---------------------------------------------------------------------------- 00002 /** @file GoSafetyCommands.cpp 00003 See GoSafetyCommands.h 00004 */ 00005 //---------------------------------------------------------------------------- 00006 00007 #include "SgSystem.h" 00008 #include "GoSafetyCommands.h" 00009 00010 #include "GoBensonSolver.h" 00011 #include "GoBoard.h" 00012 #include "GoGtpCommandUtil.h" 00013 #include "GoModBoard.h" 00014 #include "GoSafetyUtil.h" 00015 #include "GoSafetySolver.h" 00016 #include "SgPointSet.h" 00017 00018 using namespace std; 00019 using GoGtpCommandUtil::BlackWhiteArg; 00020 00021 //---------------------------------------------------------------------------- 00022 00023 GoSafetyCommands::GoSafetyCommands(const GoBoard& bd) 00024 : m_bd(bd) 00025 { 00026 } 00027 00028 void GoSafetyCommands::AddGoGuiAnalyzeCommands(GtpCommand& cmd) 00029 { 00030 cmd << 00031 "gfx/Go Safe Benson/go_safe_gfx benson\n" 00032 "gfx/Go Safe Static/go_safe_gfx static\n" 00033 "plist/Go Safe Dame Static/go_safe_dame_static\n"; 00034 } 00035 00036 /** Return dame points after running static safety algorithm. */ 00037 void GoSafetyCommands::CmdDameStatic(GtpCommand& cmd) 00038 { 00039 cmd.CheckArgNone(); 00040 GoModBoard modBoard(m_bd); 00041 GoBoard& bd = modBoard.Board(); 00042 GoRegionBoard regionAttachment(bd); 00043 GoSafetySolver solver(bd, ®ionAttachment); 00044 SgBWSet safe; 00045 solver.FindSafePoints(&safe); 00046 SgPointSet dame = GoSafetyUtil::FindDamePoints(bd, m_bd.AllEmpty(), safe); 00047 cmd << SgWritePointSet(dame, "", false); 00048 } 00049 00050 /** Information about safe points optimized for graphical display in GoGui. 00051 This command is compatible with GoGui's analyze command type "gfx". 00052 Arguments: benson|static <br> 00053 Returns: GoGui gfx commands to display safe points and additional 00054 information in the status line 00055 - black and white territory: safe points 00056 - Color Magenta (#980098): dame points 00057 - Color Red: safe for black and white (should not happen) 00058 - Circle: unsurroundable 00059 - Status line: point counts, percentage of safe points 00060 */ 00061 void GoSafetyCommands::CmdGfx(GtpCommand& cmd) 00062 { 00063 cmd.CheckNuArg(1); 00064 string type = cmd.Arg(0); 00065 int totalRegions = 0; 00066 SgBWSet safe = GetSafe(totalRegions, type); 00067 SgPointSet dame; 00068 SgPointSet unsurroundable; 00069 GoSafetyUtil::FindDameAndUnsurroundablePoints(m_bd, m_bd.AllEmpty(), safe, 00070 &dame, &unsurroundable); 00071 cmd << "BLACK"; 00072 for (SgSetIterator it(safe[SG_BLACK]); it; ++it) 00073 cmd << ' ' << SgWritePoint(*it); 00074 cmd << '\n'; 00075 cmd << "WHITE"; 00076 for (SgSetIterator it(safe[SG_WHITE]); it; ++it) 00077 cmd << ' ' << SgWritePoint(*it); 00078 cmd << '\n'; 00079 cmd << "COLOR #980098"; 00080 for (SgSetIterator it(dame); it; ++it) 00081 cmd << ' ' << SgWritePoint(*it); 00082 cmd << '\n'; 00083 cmd << "CIRCLE"; 00084 for (SgSetIterator it(unsurroundable); it; ++it) 00085 cmd << ' ' << SgWritePoint(*it); 00086 cmd << '\n'; 00087 SgPointSet blackAndWhite = safe[SG_WHITE] & safe[SG_BLACK]; 00088 if (blackAndWhite.Size() > 0) 00089 { 00090 // Shouldn't happen 00091 cmd << "COLOR red "; 00092 for (SgSetIterator it(blackAndWhite); it; ++it) 00093 cmd << ' ' << SgWritePoint(*it); 00094 cmd << '\n'; 00095 } 00096 int nuBlack = safe[SG_BLACK].Size(); 00097 int nuWhite = safe[SG_WHITE].Size(); 00098 int nuPoints = m_bd.AllPoints().Size(); 00099 cmd << "TEXT Solver: " << cmd.Arg(0) 00100 << " B: " << nuBlack << " (" << (100 * nuBlack / nuPoints) << " %)" 00101 << " W: " << nuWhite << " (" << (100 * nuWhite / nuPoints) << " %)" 00102 << " Both: " << (nuBlack + nuWhite) 00103 << " (" << (100 * (nuBlack + nuWhite) / nuPoints) << " %)" 00104 << " Regions: " << totalRegions; 00105 } 00106 00107 /** List of safe points. 00108 If no color is given, safe points of both colors are listed. 00109 Arguments: benson|static [black|white]<br> 00110 Returns: number of point followed bu list of points in one line. 00111 */ 00112 void GoSafetyCommands::CmdSafe(GtpCommand& cmd) 00113 { 00114 cmd.CheckNuArgLessEqual(2); 00115 string type = cmd.Arg(0); 00116 int totalRegions = 0; 00117 SgBWSet safe = GetSafe(totalRegions, type); 00118 SgPointSet set = 00119 (cmd.NuArg() == 2 ? safe[BlackWhiteArg(cmd, 1)] : safe.Both()); 00120 cmd << set.Size(); 00121 for (SgSetIterator it(set); it; ++it) 00122 cmd << ' ' << SgWritePoint(*it); 00123 } 00124 00125 SgBWSet GoSafetyCommands::GetSafe(int& totalRegions, const string& type) 00126 { 00127 GoModBoard modBoard(m_bd); 00128 GoBoard& bd = modBoard.Board(); 00129 GoRegionBoard regionAttachment(bd); 00130 SgBWSet safe; 00131 if (type == "benson") 00132 { 00133 GoBensonSolver solver(bd, ®ionAttachment); 00134 solver.FindSafePoints(&safe); 00135 } 00136 else if (type == "static") 00137 { 00138 GoSafetySolver solver(bd, ®ionAttachment); 00139 solver.FindSafePoints(&safe); 00140 } 00141 else 00142 throw GtpFailure() << "invalid safety solver: " << type; 00143 SgPointSet proved = safe.Both(); 00144 for (SgBWIterator it; it; ++it) 00145 { 00146 SgBlackWhite c = *it; 00147 for (SgVectorIteratorOf<GoRegion> it(regionAttachment.AllRegions(c)); 00148 it; ++it) 00149 if ((*it)->Points().SubsetOf(proved)) 00150 ++totalRegions; 00151 } 00152 return safe; 00153 } 00154 00155 void GoSafetyCommands::Register(GtpEngine& e) 00156 { 00157 Register(e, "go_safe", &GoSafetyCommands::CmdSafe); 00158 Register(e, "go_safe_gfx", &GoSafetyCommands::CmdGfx); 00159 Register(e, "go_safe_dame_static", &GoSafetyCommands::CmdDameStatic); 00160 } 00161 00162 void GoSafetyCommands::Register(GtpEngine& engine, 00163 const std::string& command, 00164 GtpCallback<GoSafetyCommands>::Method method) 00165 { 00166 engine.Register(command, 00167 new GtpCallback<GoSafetyCommands>(this, method)); 00168 } 00169 00170 //----------------------------------------------------------------------------