00001 //---------------------------------------------------------------------------- 00002 /** @file GoSetupUtil.cpp 00003 See GoSetupUtil.h */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "SgSystem.h" 00007 #include "GoSetupUtil.h" 00008 00009 #include <cstdio> 00010 #include "GoBoard.h" 00011 #include "GoSetup.h" 00012 00013 using SgPointUtil::Pt; 00014 00015 //---------------------------------------------------------------------------- 00016 namespace { 00017 00018 bool IsBlackChar(int c) 00019 { 00020 return c == 'x' || c == 'X' || c == '@'; 00021 } 00022 00023 bool IsWhiteChar(int c) 00024 { 00025 return c == '0' || c == 'o' || c == 'O'; 00026 } 00027 00028 bool IsEmptyChar(int c) 00029 { 00030 return c == '.' || c == '+'; 00031 } 00032 00033 bool IsIgnoreChar(int c) 00034 { 00035 return c == ' ' || c == '\t'; 00036 } 00037 00038 bool ReadLine(std::streambuf& in, GoSetup& setup, int row, int& currLength) 00039 { 00040 int col = 0; 00041 for (int c = in.sbumpc(); c != EOF && c != '\n'; c = in.sbumpc()) 00042 { 00043 if (IsBlackChar(c) || IsWhiteChar(c) || IsEmptyChar(c)) 00044 { 00045 ++col; 00046 if (col > SG_MAX_SIZE) 00047 return false; // bad data? 00048 } 00049 else if (! IsIgnoreChar(c)) 00050 throw SgException("bad input data for ReadLine"); 00051 00052 SgPoint p = Pt(col, row); 00053 if (IsBlackChar(c)) 00054 { 00055 setup.m_stones[SG_BLACK].Include(p); 00056 } 00057 else if (IsWhiteChar(c)) 00058 { 00059 setup.m_stones[SG_WHITE].Include(p); 00060 } 00061 } 00062 currLength = col; 00063 return currLength > 0; 00064 } 00065 00066 } // namespace 00067 00068 //---------------------------------------------------------------------------- 00069 00070 GoSetup GoSetupUtil::CreateSetupFromStream(std::streambuf& in, int& boardSize) 00071 { 00072 GoSetup setup; 00073 boardSize = 0; 00074 00075 int currLength = 0; 00076 for (int row = 1; ReadLine(in, setup, row, currLength); ++row) 00077 { 00078 if (currLength != boardSize) 00079 { 00080 if (boardSize == 0) 00081 boardSize = currLength; // length established 00082 else 00083 throw SgException("bad input data for CreateSetupFromStream"); 00084 } 00085 if (row > boardSize) 00086 break; 00087 } 00088 00089 // The standard display format has rows in decreasing order, so flip rows 00090 // from top to bottom. 00091 SgPointSetUtil::Rotate(2, setup.m_stones[SG_BLACK], boardSize); 00092 SgPointSetUtil::Rotate(2, setup.m_stones[SG_WHITE], boardSize); 00093 return setup; 00094 } 00095 00096 GoSetup GoSetupUtil::CreateSetupFromString(std::string& in, 00097 int& boardSize) 00098 { 00099 std::stringbuf inBuf(in); 00100 return GoSetupUtil::CreateSetupFromStream(inBuf, boardSize); 00101 } 00102 00103 GoSetup GoSetupUtil::CurrentPosSetup(const GoBoard& bd) 00104 { 00105 GoSetup setup; 00106 setup.m_player = bd.ToPlay(); 00107 for (GoBoard::Iterator it2(bd); it2; ++it2) 00108 { 00109 SgPoint p = *it2; 00110 if (bd.Occupied(p)) 00111 setup.m_stones[bd.GetColor(p)].Include(p); 00112 } 00113 return setup; 00114 } 00115 00116 //----------------------------------------------------------------------------