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


Sun Mar 13 2011 Doxygen 1.7.1