Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoGtpCommandUtil.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoGtpCommandUtil.cpp
00003 */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "SgSystem.h"
00007 #include "GoGtpCommandUtil.h"
00008 
00009 #include <limits>
00010 #include "GoBoard.h"
00011 #include "GtpEngine.h"
00012 #include "SgDebug.h"
00013 #include "SgPointArray.h"
00014 
00015 using namespace std;
00016 using SgPointUtil::Pt;
00017 
00018 //----------------------------------------------------------------------------
00019 
00020 namespace {
00021 
00022 /** Comparison of gogui-analyze_commands lines for
00023     SortResponseAnalyzeCommands
00024 */
00025 bool LessAnalyzeLabel(const string& line1, const string& line2)
00026 {
00027     // Analyze label is the second entry in the line, separator is '/'
00028     size_t pos1 = line1.find("/");
00029     size_t pos2 = line2.find("/");
00030     if (pos1 == string::npos || pos2 == string::npos)
00031     {
00032         // Shouldn't happen in well-formed lines
00033         SG_ASSERT(false);
00034         return true;
00035     }
00036     return (line1.substr(pos1) < line2.substr(pos2));
00037 }
00038 
00039 } // namespace
00040 
00041 //----------------------------------------------------------------------------
00042 
00043 SgEmptyBlackWhite GoGtpCommandUtil::EmptyBlackWhiteArg(const GtpCommand& cmd,
00044                                                        std::size_t number)
00045 {
00046     string value = cmd.ArgToLower(number);
00047     if (value == "e" || value == "empty")
00048         return SG_EMPTY;
00049     if (value == "b" || value == "black")
00050         return SG_BLACK;
00051     if (value == "w" || value == "white")
00052         return SG_WHITE;
00053     throw GtpFailure() << "argument " << (number + 1)
00054                        << " must be black, white or empty";
00055 }
00056 
00057 SgBlackWhite GoGtpCommandUtil::BlackWhiteArg(const GtpCommand& cmd,
00058                                              std::size_t number)
00059 {
00060     string value = cmd.ArgToLower(number);
00061     if (value == "b" || value == "black")
00062         return SG_BLACK;
00063     if (value == "w" || value == "white")
00064         return SG_WHITE;
00065     throw GtpFailure() << "argument " << (number + 1)
00066                        << " must be black or white";
00067 }
00068 
00069 SgPoint GoGtpCommandUtil::EmptyPointArg(const GtpCommand& cmd,
00070                                         std::size_t number,
00071                                         const GoBoard& board)
00072 {
00073     SgPoint point = PointArg(cmd, number, board);
00074     if (board.GetColor(point) != SG_EMPTY)
00075         throw GtpFailure() << "point " << SgWritePoint(point)
00076                            << " must be empty";
00077     return point;
00078 }
00079 
00080 SgVector<SgPoint> GoGtpCommandUtil::GetHandicapStones(int size, int n)
00081 {
00082     SgVector<SgPoint> stones;
00083     if (n == 0)
00084         return stones;
00085     // GTP locations are defined up to size 25, but SG_MAX_SIZE could be
00086     // smaller
00087     if (size > SG_MAX_SIZE || size > 25)
00088         throw GtpFailure("no standard handicap locations defined");
00089     int line1 = -1;
00090     int line2 = -1;
00091     int line3 = -1;
00092     if (size >= 13)
00093     {
00094         line1 = 4;
00095         line3 = size - 3;
00096     }
00097     else if (size >= 7)
00098     {
00099         line1 = 3;
00100         line3 = size - 2;
00101     }
00102     if (size >= 9 && size % 2 != 0)
00103         line2 = size / 2 + 1;
00104     if (line1 < 0 || n == 1 || n > 9 || (n > 4 && line2 < 0))
00105         throw GtpFailure("no standard handicap locations defined");
00106     if (n >= 1)
00107         stones.PushBack(Pt(line1, line1));
00108     if (n >= 2)
00109         stones.PushBack(Pt(line3, line3));
00110     if (n >= 3)
00111         stones.PushBack(Pt(line1, line3));
00112     if (n >= 4)
00113         stones.PushBack(Pt(line3, line1));
00114     if (n >= 5 && n % 2 != 0)
00115     {
00116         stones.PushBack(Pt(line2, line2));
00117         --n;
00118     }
00119     if (n >= 5)
00120         stones.PushBack(Pt(line1, line2));
00121     if (n >= 6)
00122         stones.PushBack(Pt(line3, line2));
00123     if (n >= 7)
00124         stones.PushBack(Pt(line2, line1));
00125     if (n >= 8)
00126         stones.PushBack(Pt(line2, line3));
00127     return stones;
00128 }
00129 
00130 SgMove GoGtpCommandUtil::MoveArg(const GtpCommand& cmd, std::size_t number,
00131                                  const GoBoard& board)
00132 {
00133     if (cmd.ArgToLower(number) == "pass")
00134         return SG_PASS;
00135     return PointArg(cmd, number, board);
00136 }
00137 
00138 void GoGtpCommandUtil::ParseMultiStoneArgument(GtpCommand& cmd,
00139                                                const GoBoard& board,
00140                                                SgBlackWhite& toPlay,
00141                                                SgBlackWhite& defender,
00142                                                SgVector<SgPoint>& crucial)
00143 {
00144     toPlay = GoGtpCommandUtil::BlackWhiteArg(cmd, 0);
00145     SgDebug() << "Set " << SgBW(toPlay) << " to play\n";
00146     SgPoint point = GoGtpCommandUtil::StoneArg(cmd, 1, board);
00147     defender = board.GetColor(point);
00148     SG_ASSERT(defender == SG_BLACK || defender == SG_WHITE);
00149     crucial.PushBack(point);
00150     for (size_t i = 2; i < cmd.NuArg(); ++i)
00151     {
00152         SgPoint p = GoGtpCommandUtil::StoneArg(cmd, i, board);
00153         if (board.GetColor(p) != defender)
00154             throw GtpFailure("Crucial stones must be same color");
00155         else
00156             crucial.PushBack(p);
00157     }
00158 }
00159 
00160 SgPoint GoGtpCommandUtil::PointArg(const GtpCommand& cmd,
00161                                    const GoBoard& board)
00162 {
00163     cmd.CheckNuArg(1);
00164     return PointArg(cmd, 0, board);
00165 }
00166 
00167 SgPoint GoGtpCommandUtil::PointArg(const GtpCommand& cmd, std::size_t number,
00168                                    const GoBoard& board)
00169 {
00170     string arg = cmd.Arg(number);
00171     istringstream in(arg);
00172     SgPoint p;
00173     in >> SgReadPoint(p);
00174     if (! in)
00175         throw GtpFailure() << "invalid point " << arg;
00176     if (p == SG_PASS)
00177         throw GtpFailure("expected point, not pass");
00178     if (SgMoveUtil::IsCouponMove(p))
00179         throw GtpFailure("expected point, not coupon move");
00180     if (! board.IsValidPoint(p))
00181         throw GtpFailure() << "point outside board " << arg;
00182     return p;
00183 }
00184 
00185 SgVector<SgPoint> GoGtpCommandUtil::PointListArg(const GtpCommand& cmd,
00186                                                std::size_t number,
00187                                                const GoBoard& board)
00188 {
00189     SgVector<SgPoint> result;
00190     for (size_t i = number; i < cmd.NuArg(); ++i)
00191         result.PushBack(PointArg(cmd, i, board));
00192     return result;
00193 }
00194 
00195 void GoGtpCommandUtil::RespondNumberArray(GtpCommand& cmd,
00196                                           const SgPointArray<int>& array,
00197                                           int scale, const GoBoard& board)
00198 {
00199     SgPointArray<string> result("\"\"");
00200     for (GoBoard::Iterator it(board); it; ++it)
00201     {
00202         SgPoint p(*it);
00203         if (array[p] != numeric_limits<int>::min())
00204         {
00205             ostringstream out;
00206             out << (array[p] / scale);
00207             result[p] = out.str();
00208         }
00209     }
00210     cmd << '\n' << SgWritePointArray<string>(result, board.Size());
00211 }
00212 
00213 string GoGtpCommandUtil::SortResponseAnalyzeCommands(const string& response)
00214 {
00215     vector<string> allLines;
00216     istringstream in(response);
00217     string line;
00218     while (getline(in, line))
00219         allLines.push_back(line);        
00220     sort(allLines.begin(), allLines.end(), LessAnalyzeLabel);
00221     ostringstream sortedResponse;
00222     for (vector<string>::const_iterator it = allLines.begin();
00223          it != allLines.end(); ++it)
00224         sortedResponse << *it << '\n';
00225     return sortedResponse.str();
00226 }
00227 
00228 SgPoint GoGtpCommandUtil::StoneArg(const GtpCommand& cmd, std::size_t number,
00229                                    const GoBoard& board)
00230 {
00231     SgPoint point = PointArg(cmd, number, board);
00232     if (board.GetColor(point) == SG_EMPTY)
00233         throw GtpFailure() << "point " << SgWritePoint(point)
00234                            << " must be occupied";
00235     return point;
00236 }
00237 
00238 //----------------------------------------------------------------------------
00239 


17 Jun 2010 Doxygen 1.4.7