00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "SgSystem.h"
00013 #include "SgProp.h"
00014
00015 #include <iomanip>
00016 #include <sstream>
00017 #include "SgRect.h"
00018 #include "SgUtil.h"
00019 #include "SgVector.h"
00020
00021 using namespace std;
00022 using SgPointUtil::InBoardRange;
00023 using SgPropUtil::PointToSgfString;
00024 using SgPropUtil::SgfStringToPoint;
00025 using SgPropUtil::EscapeSpecialCharacters;
00026 using SgUtil::InRange;
00027
00028
00029
00030 SgPropPointFmt SgPropUtil::GetPointFmt(int gameNumber)
00031 {
00032 switch (gameNumber)
00033 {
00034 case 2:
00035 case 11:
00036 return SG_PROPPOINTFMT_HEX;
00037 default:
00038 return SG_PROPPOINTFMT_GO;
00039 }
00040 }
00041
00042 string SgPropUtil::PointToSgfString(SgMove p, int boardSize,
00043 SgPropPointFmt fmt, int fileFormat)
00044 {
00045 SG_ASSERT(boardSize >= SG_MIN_SIZE && boardSize <= SG_MAX_SIZE);
00046 SG_ASSERT(p != SG_NULLMOVE);
00047 ostringstream out;
00048 switch (fmt)
00049 {
00050 case SG_PROPPOINTFMT_GO:
00051 {
00052 if (p == SG_PASS)
00053 {
00054 if (fileFormat < 4)
00055 out << "tt";
00056
00057 }
00058 else
00059 {
00060 int col = SgPointUtil::Col(p);
00061 int row = boardSize - SgPointUtil::Row(p) + 1;
00062 SG_ASSERT(row > 0);
00063 out << static_cast<char>('a' + col - 1)
00064 << static_cast<char>('a' + row - 1);
00065 }
00066 }
00067 break;
00068 case SG_PROPPOINTFMT_HEX:
00069 {
00070 SG_ASSERT(p != SG_PASS);
00071 int col = SgPointUtil::Col(p);
00072 int row = boardSize - SgPointUtil::Row(p) + 1;
00073 out << static_cast<char>('a' + col - 1) << row;
00074 }
00075 break;
00076 default:
00077 SG_ASSERT(false);
00078 }
00079 return out.str();
00080 }
00081
00082 string SgPropUtil::EscapeSpecialCharacters(const string& s, bool escapeColon)
00083 {
00084 ostringstream buffer;
00085 for (size_t i = 0; i < s.size(); ++i)
00086 {
00087 char c = s[i];
00088 if (c == ']' || c =='\\' || (c == ':' && escapeColon))
00089 buffer << '\\' << c;
00090 else if (c == '\r' || c == '\t')
00091 buffer << ' ';
00092 else
00093 buffer << c;
00094 }
00095 return buffer.str();
00096 }
00097
00098 SgMove SgPropUtil::SgfStringToPoint(const string& s, int boardSize,
00099 SgPropPointFmt fmt)
00100 {
00101 SG_ASSERT(boardSize >= SG_MIN_SIZE && boardSize <= SG_MAX_SIZE);
00102 SgPoint p = SG_NULLMOVE;
00103 switch (fmt)
00104 {
00105 case SG_PROPPOINTFMT_GO:
00106 {
00107 if (s.size() == 2
00108 && 'a' <= s[0] && s[0] <= 's'
00109 && 'a' <= s[1] && s[1] <= 's')
00110 {
00111 int col = s[0] - 'a' + 1;
00112 int row = s[1] - 'a' + 1;
00113 p = SgPointUtil::Pt(col, boardSize - row + 1);
00114 }
00115 else if (s.empty()
00116 || (s.size() == 2 && s[0] == 't' && s[1] == 't'))
00117 p = SG_PASS;
00118 }
00119 break;
00120 case SG_PROPPOINTFMT_HEX:
00121 {
00122 if (s.size() >= 2 && s.size() <= 3)
00123 {
00124 int col = s[0] - 'a' + 1;
00125 int row = s[1] - '1' + 1;
00126 if (s.size() == 3)
00127 row = row * 10 + (s[2] - '1' + 1);
00128 if (InRange(col, 1, boardSize) && InRange(row, 1, boardSize))
00129 p = SgPointUtil::Pt(col, boardSize - row + 1);
00130 }
00131 }
00132 break;
00133 default:
00134 SG_ASSERT(false);
00135 }
00136 return p;
00137 }
00138
00139
00140
00141 SgPropList::SgPropList()
00142 : m_list()
00143 { }
00144
00145 SgPropList::~SgPropList()
00146 {
00147 Clear();
00148 }
00149
00150 void SgPropList::Clear()
00151 {
00152 for (SgVectorIteratorOf<SgProp> iter(m_list); iter; ++iter)
00153 delete *iter;
00154 m_list.Clear();
00155 }
00156
00157 SgProp* SgPropList::Get(SgPropID id) const
00158 {
00159 for (SgVectorIteratorOf<SgProp> iter(m_list); iter; ++iter)
00160 {
00161 SgProp* prop = *iter;
00162 if (prop->MatchesID(id))
00163 return prop;
00164 }
00165 return 0;
00166 }
00167
00168 void SgPropList::Add(const SgProp* prop)
00169 {
00170 SG_ASSERT(prop);
00171
00172
00173
00174
00175 if (prop->ID() != SG_PROP_UNKNOWN)
00176 {
00177 if (prop->Flag(SG_PROPCLASS_ANNO_MOVE))
00178 Remove(SG_PROP_MOVE_ANNO, prop);
00179 else if (prop->Flag(SG_PROPCLASS_ANNO_POS))
00180 Remove(SG_PROP_POS_ANNO, prop);
00181 else if (prop->Flag(SG_PROPCLASS_MOVE))
00182 Remove(SG_PROP_MOVE, prop);
00183 else
00184 Remove(prop->ID(), prop);
00185 }
00186 m_list.Include(prop);
00187 }
00188
00189 void SgPropList::MoveToFront(SgPropID id)
00190 {
00191 SgProp* prop = Get(id);
00192 if (prop && m_list.Exclude(prop))
00193 m_list.PushFront(prop);
00194 }
00195
00196 bool SgPropList::Remove(const SgProp* prop)
00197 {
00198 if (prop)
00199 delete prop;
00200 return m_list.Exclude(const_cast<SgProp*>(prop));
00201 }
00202
00203 void SgPropList::Remove(SgPropID id, const SgProp* protectProp)
00204 {
00205 SgVectorOf<SgProp> toBeDeleted;
00206 for (SgVectorIteratorOf<SgProp> iter(m_list); iter; ++iter)
00207 {
00208 SgProp* prop = *iter;
00209 if (prop != protectProp && prop->MatchesID(id))
00210 {
00211
00212 toBeDeleted.PushBack(prop);
00213 delete prop;
00214 }
00215 }
00216 m_list.Exclude(toBeDeleted);
00217 }
00218
00219 bool SgPropList::AppendMoveAnnotation(string* s) const
00220 {
00221 SgProp* moveAnnoProp = Get(SG_PROP_MOVE_ANNO);
00222 if (! moveAnnoProp)
00223 return false;
00224 SgPropInt* intProp = dynamic_cast<SgPropInt*>(moveAnnoProp);
00225 int value = intProp ? intProp->Value() : 1;
00226 SgPropID id = moveAnnoProp->ID();
00227 if (id == SG_PROP_GOOD_MOVE)
00228 *s += (value == 2) ? "!!" : "!";
00229 else if (id == SG_PROP_BAD_MOVE)
00230 *s += (value == 2) ? "??" : "?";
00231 else if (id == SG_PROP_INTERESTING)
00232 *s += "!?";
00233 else if (id == SG_PROP_DOUBTFUL)
00234 *s += "?!";
00235 return true;
00236 }
00237
00238 SgProp* SgPropList::GetPropContainingText(const string& findText) const
00239 {
00240 for (SgVectorIteratorOf<SgProp> iter(m_list); iter; ++iter)
00241 {
00242 SgProp* prop = *iter;
00243 if (prop->ContainsText(findText))
00244 return prop;
00245 }
00246 return 0;
00247 }
00248
00249
00250
00251
00252 SgPropID SG_PROP_NONE = 0;
00253 SgPropID SG_PROP_UNKNOWN = 0;
00254
00255
00256 SgPropID SG_PROP_MOVE = 0;
00257 SgPropID SG_PROP_MOVE_BLACK = 0;
00258 SgPropID SG_PROP_MOVE_WHITE = 0;
00259
00260
00261 SgPropID SG_PROP_ADD_BLACK = 0;
00262 SgPropID SG_PROP_ADD_WHITE = 0;
00263 SgPropID SG_PROP_ADD_EMPTY = 0;
00264 SgPropID SG_PROP_PLAYER = 0;
00265
00266
00267 SgPropID SG_PROP_VALUE = 0;
00268 SgPropID SG_PROP_TERR_BLACK = 0;
00269 SgPropID SG_PROP_TERR_WHITE = 0;
00270
00271
00272 SgPropID SG_PROP_MARKS = 0;
00273 SgPropID SG_PROP_SELECT = 0;
00274 SgPropID SG_PROP_MARKED = 0;
00275 SgPropID SG_PROP_TRIANGLE = 0;
00276 SgPropID SG_PROP_SQUARE = 0;
00277 SgPropID SG_PROP_DIAMOND = 0;
00278 SgPropID SG_PROP_CIRCLE = 0;
00279 SgPropID SG_PROP_DIMMED = 0;
00280 SgPropID SG_PROP_LABEL = 0;
00281
00282
00283 SgPropID SG_PROP_TIMES = 0;
00284 SgPropID SG_PROP_TIME_BLACK = 0;
00285 SgPropID SG_PROP_TIME_WHITE = 0;
00286 SgPropID SG_PROP_OT_NU_MOVES = 0;
00287 SgPropID SG_PROP_OT_PERIOD = 0;
00288 SgPropID SG_PROP_OT_BLACK = 0;
00289 SgPropID SG_PROP_OT_WHITE = 0;
00290 SgPropID SG_PROP_LOSE_TIME = 0;
00291 SgPropID SG_PROP_OVERHEAD = 0;
00292
00293
00294 SgPropID SG_PROP_COUNT = 0;
00295 SgPropID SG_PROP_TIME_USED = 0;
00296 SgPropID SG_PROP_NUM_NODES = 0;
00297 SgPropID SG_PROP_NUM_LEAFS = 0;
00298 SgPropID SG_PROP_MAX_DEPTH = 0;
00299 SgPropID SG_PROP_DEPTH = 0;
00300 SgPropID SG_PROP_PART_DEPTH = 0;
00301 SgPropID SG_PROP_EVAL = 0;
00302 SgPropID SG_PROP_EXPECTED = 0;
00303
00304
00305 SgPropID SG_PROP_FORMAT = 0;
00306 SgPropID SG_PROP_SIZE = 0;
00307 SgPropID SG_PROP_GAME = 0;
00308 SgPropID SG_PROP_SPEC_BLACK = 0;
00309 SgPropID SG_PROP_SPEC_WHITE = 0;
00310 SgPropID SG_PROP_CHINESE = 0;
00311 SgPropID SG_PROP_APPLIC = 0;
00312
00313
00314 SgPropID SG_PROP_ANNOTATE = 0;
00315 SgPropID SG_PROP_COMMENT = 0;
00316 SgPropID SG_PROP_NAME = 0;
00317 SgPropID SG_PROP_CHECK = 0;
00318 SgPropID SG_PROP_SIGMA = 0;
00319 SgPropID SG_PROP_HOTSPOT = 0;
00320 SgPropID SG_PROP_FIGURE = 0;
00321
00322
00323 SgPropID SG_PROP_POS_ANNO = 0;
00324 SgPropID SG_PROP_GOOD_BLACK = 0;
00325 SgPropID SG_PROP_GOOD_WHITE = 0;
00326 SgPropID SG_PROP_EVEN_POS = 0;
00327 SgPropID SG_PROP_UNCLEAR = 0;
00328
00329
00330 SgPropID SG_PROP_MOVE_ANNO = 0;
00331 SgPropID SG_PROP_GOOD_MOVE = 0;
00332 SgPropID SG_PROP_BAD_MOVE = 0;
00333 SgPropID SG_PROP_INTERESTING = 0;
00334 SgPropID SG_PROP_DOUBTFUL = 0;
00335
00336
00337 SgPropID SG_PROP_INFO = 0;
00338 SgPropID SG_PROP_GAME_NAME = 0;
00339 SgPropID SG_PROP_GAME_COMMENT = 0;
00340 SgPropID SG_PROP_EVENT = 0;
00341 SgPropID SG_PROP_ROUND = 0;
00342 SgPropID SG_PROP_DATE = 0;
00343 SgPropID SG_PROP_PLACE = 0;
00344 SgPropID SG_PROP_PLAYER_BLACK = 0;
00345 SgPropID SG_PROP_PLAYER_WHITE = 0;
00346 SgPropID SG_PROP_RESULT = 0;
00347 SgPropID SG_PROP_USER = 0;
00348 SgPropID SG_PROP_TIME = 0;
00349 SgPropID SG_PROP_SOURCE = 0;
00350 SgPropID SG_PROP_COPYRIGHT = 0;
00351 SgPropID SG_PROP_ANALYSIS = 0;
00352 SgPropID SG_PROP_RANK_BLACK = 0;
00353 SgPropID SG_PROP_RANK_WHITE = 0;
00354 SgPropID SG_PROP_TEAM_BLACK = 0;
00355 SgPropID SG_PROP_TEAM_WHITE = 0;
00356 SgPropID SG_PROP_OPENING = 0;
00357 SgPropID SG_PROP_RULES = 0;
00358 SgPropID SG_PROP_HANDICAP = 0;
00359 SgPropID SG_PROP_KOMI = 0;
00360
00361
00362 SgPropID SG_PROP_FIND_MOVE = 0;
00363 SgPropID SG_PROP_FIND_TEXT = 0;
00364 SgPropID SG_PROP_BRANCH = 0;
00365 SgPropID SG_PROP_TERMINAL = 0;
00366
00367
00368 SgPropID SG_PROP_MOTIVE = 0;
00369 SgPropID SG_PROP_SEQUENCE = 0;
00370 SgPropID SG_PROP_NOT_EMPTY = 0;
00371 SgPropID SG_PROP_NOT_BLACK = 0;
00372 SgPropID SG_PROP_NOT_WHITE = 0;
00373
00374
00375
00376 bool SgProp::s_initialized = false;
00377
00378 int SgProp::s_numPropClasses = 0;
00379
00380 SgPropFlags SgProp::s_flags[SG_MAX_PROPCLASS];
00381
00382 string SgProp::s_label[SG_MAX_PROPCLASS];
00383
00384 SgProp* SgProp::s_prop[SG_MAX_PROPCLASS];
00385
00386 SgProp::~SgProp()
00387 {
00388 }
00389
00390 void SgProp::ChangeToOpponent()
00391 {
00392 m_id = OpponentProp(m_id);
00393 }
00394
00395 bool SgProp::ContainsText(const std::string& findText)
00396 {
00397 SG_UNUSED(findText);
00398 return false;
00399 }
00400
00401 SgPropFlags SgProp::Flags() const
00402 {
00403 return s_flags[m_id];
00404 }
00405
00406 bool SgProp::Initialized()
00407 {
00408 return s_initialized;
00409 }
00410
00411 string SgProp::Label() const
00412 {
00413 return s_label[m_id];
00414 }
00415
00416 SgPropID SgProp::Register(SgProp* prop, const char* label, SgPropFlags flags)
00417 {
00418 ++s_numPropClasses;
00419 SG_ASSERT(s_numPropClasses < SG_MAX_PROPCLASS);
00420 if (s_numPropClasses < SG_MAX_PROPCLASS)
00421 {
00422 s_flags[s_numPropClasses] = flags;
00423 s_label[s_numPropClasses] = label;
00424 s_prop[s_numPropClasses] = prop;
00425 if (prop)
00426 {
00427 SG_ASSERT(prop->m_id == 0);
00428 }
00429
00430 if (flags & SG_PROPCLASS_WHITE)
00431 SG_ASSERT(s_flags[s_numPropClasses-1] & SG_PROPCLASS_BLACK);
00432
00433 return s_numPropClasses;
00434 }
00435 else
00436 return 0;
00437 }
00438
00439 SgProp* SgProp::CreateProperty(SgPropID id)
00440 {
00441 SG_ASSERT(id <= s_numPropClasses);
00442 SG_ASSERT(s_prop[id]);
00443
00444
00445
00446 SgProp* prop = s_prop[id]->Duplicate();
00447 prop->m_id = id;
00448 return prop;
00449 }
00450
00451 SgPropID SgProp::GetIDOfLabel(const string& label)
00452 {
00453 for (int i = 1; i <= s_numPropClasses; ++i)
00454 if (s_label[i] == label)
00455 return i;
00456 return SG_PROP_NONE;
00457 }
00458
00459 SgPropID SgProp::OpponentProp(SgPropID id)
00460 {
00461
00462
00463
00464 SgPropFlags flags = s_flags[id];
00465
00466 if (flags & SG_PROPCLASS_BLACK)
00467 {
00468 ++id;
00469 SG_ASSERT(s_flags[id] & SG_PROPCLASS_WHITE);
00470 }
00471 else if (flags & SG_PROPCLASS_WHITE)
00472 {
00473 --id;
00474 SG_ASSERT(s_flags[id] & SG_PROPCLASS_BLACK);
00475 }
00476 return id;
00477 }
00478
00479 SgPropID SgProp::PlayerProp(SgPropID id, SgBlackWhite player)
00480 {
00481
00482 SgPropFlags flags = s_flags[id];
00483 SG_ASSERT(flags & (SG_PROPCLASS_BLACK | SG_PROPCLASS_WHITE));
00484 int mask = (player == SG_WHITE ? SG_PROPCLASS_WHITE : SG_PROPCLASS_BLACK);
00485 if (flags & mask)
00486 return id;
00487 else
00488 return OpponentProp(id);
00489 }
00490
00491 SgBlackWhite SgProp::Player() const
00492 {
00493 SG_ASSERT(Flag(SG_PROPCLASS_BLACK | SG_PROPCLASS_WHITE));
00494 if (Flags() & SG_PROPCLASS_BLACK)
00495 return SG_BLACK;
00496 else if (Flags() & SG_PROPCLASS_WHITE)
00497 return SG_WHITE;
00498 SG_ASSERT(false);
00499 return -1;
00500 }
00501
00502 bool SgProp::IsPlayer(SgBlackWhite player) const
00503 {
00504 SG_ASSERT_BW(player);
00505 return (Player() == player);
00506 }
00507
00508 bool SgProp::MatchesID(SgPropID id) const
00509 {
00510
00511 if (id == ID())
00512 return true;
00513
00514
00515 if (s_flags[id] & SG_PROPCLASS_ABSTRACT)
00516 {
00517 SgPropFlags fCategories = s_flags[id] & (~SG_PROPCLASS_ABSTRACT);
00518 if ((Flags() & fCategories) == fCategories)
00519 return true;
00520 }
00521
00522 return false;
00523 }
00524
00525 SgPropID SgProp::ConvertFindTextToPropID(const string& findText)
00526 {
00527 size_t length = findText.size();
00528 if ( (3 <= length && findText[1] == ' ' && findText[2] == '<')
00529 || (2 <= length && findText[1] == '<')
00530 || 1 == length
00531 )
00532 {
00533 switch (findText[0])
00534 {
00535 case 'A': return SG_PROP_ANNOTATE;
00536 case 'B': return SG_PROP_MOVE_BLACK;
00537 case 'C': return SG_PROP_COMMENT;
00538 case 'H': return SG_PROP_HOTSPOT;
00539 case 'I': return SG_PROP_INFO;
00540 case 'K': return SG_PROP_CHECK;
00541 case 'M': return SG_PROP_MARKS;
00542 case 'N': return SG_PROP_NAME;
00543 case 'S': return SG_PROP_SIGMA;
00544 case 'T': return SG_PROP_TRIANGLE;
00545 case 'W': return SG_PROP_MOVE_WHITE;
00546 case '!': return SG_PROP_GOOD_MOVE;
00547 case '?': return SG_PROP_BAD_MOVE;
00548 case '.': return SG_PROP_TERMINAL;
00549 case ':': return SG_PROP_BRANCH;
00550 default: break;
00551 }
00552 }
00553 return SG_PROP_NONE;
00554 }
00555
00556 void SgProp::Init()
00557 {
00558
00559 s_flags[0] = 0;
00560 s_label[0] = "";
00561 s_prop[0] = 0;
00562
00563
00564 SgProp* unknownProp = new SgPropUnknown(0);
00565 SgProp* simpleProp = new SgPropSimple(0);
00566 SgProp* intProp = new SgPropInt(0);
00567 SgProp* realProp = new SgPropReal(0);
00568 SgProp* multipleProp = new SgPropMultiple(0);
00569 SgProp* valueProp = new SgPropValue(0);
00570 SgProp* timeProp = new SgPropTime(0);
00571 SgProp* mSecProp = new SgPropMSec(0);
00572 SgProp* moveProp = new SgPropMove(0);
00573 SgProp* listProp = new SgPropPointList(0);
00574 SgProp* textProp = new SgPropText(0);
00575 SgProp* textListProp = new SgPropTextList(0);
00576 SgProp* playerProp = new SgPropPlayer(0);
00577 SgProp* addStoneProp = new SgPropAddStone(0);
00578
00579
00580 SG_PROP_NONE = 0;
00581 SG_PROP_UNKNOWN = Register(unknownProp, "");
00582 Register(simpleProp, "");
00583 Register(intProp, "");
00584 Register(realProp, "");
00585 Register(multipleProp, "");
00586 Register(valueProp, "");
00587 Register(timeProp, "");
00588 Register(mSecProp, "");
00589 Register(moveProp, "");
00590 Register(listProp, "");
00591 Register(textProp, "");
00592 Register(textListProp, "");
00593 Register(playerProp, "");
00594 Register(addStoneProp, "");
00595
00596
00597
00598
00599 SG_PROP_MOVE = Register(0, "", SG_PROPCLASS_MOVE + SG_PROPCLASS_ABSTRACT);
00600 SG_PROP_PLAYER = Register(playerProp, "PL");
00601 SG_PROP_ADD_BLACK = Register(addStoneProp, "AB",
00602 SG_PROPCLASS_BLACK + SG_PROPCLASS_NEWLINE);
00603 SG_PROP_ADD_WHITE = Register(addStoneProp, "AW",
00604 SG_PROPCLASS_WHITE + SG_PROPCLASS_NEWLINE);
00605 SG_PROP_ADD_EMPTY = Register(addStoneProp, "AE", SG_PROPCLASS_NEWLINE);
00606
00607
00608 SG_PROP_VALUE = Register(valueProp, "V");
00609 SG_PROP_TERR_BLACK = Register(listProp, "TB",
00610 SG_PROPCLASS_BLACK + SG_PROPCLASS_NEWLINE);
00611 SG_PROP_TERR_WHITE = Register(listProp, "TW",
00612 SG_PROPCLASS_WHITE + SG_PROPCLASS_NEWLINE);
00613
00614
00615 SG_PROP_MARKS = Register(0, "", SG_PROPCLASS_MARK + SG_PROPCLASS_ABSTRACT);
00616 SG_PROP_SELECT = Register(listProp, "SL", SG_PROPCLASS_MARK);
00617 SG_PROP_MARKED = Register(listProp, "MA", SG_PROPCLASS_MARK);
00618 SG_PROP_TRIANGLE = Register(listProp, "TR", SG_PROPCLASS_MARK);
00619 SG_PROP_SQUARE = Register(listProp, "SQ", SG_PROPCLASS_MARK);
00620 SG_PROP_DIAMOND = Register(listProp, "RG", SG_PROPCLASS_MARK);
00621 SG_PROP_CIRCLE = Register(listProp, "CR", SG_PROPCLASS_MARK);
00622 SG_PROP_DIMMED = Register(listProp, "DD", SG_PROPCLASS_MARK);
00623 SG_PROP_LABEL = Register(textListProp, "LB", SG_PROPCLASS_MARK);
00624
00625
00626 SG_PROP_TIMES = Register(0, "", SG_PROPCLASS_TIME + SG_PROPCLASS_ABSTRACT);
00627 SG_PROP_TIME_BLACK = Register(timeProp, "BL",
00628 SG_PROPCLASS_TIME + SG_PROPCLASS_BLACK);
00629 SG_PROP_TIME_WHITE = Register(timeProp, "WL",
00630 SG_PROPCLASS_TIME + SG_PROPCLASS_WHITE);
00631 SG_PROP_OT_BLACK = Register(intProp, "OB",
00632 SG_PROPCLASS_TIME + SG_PROPCLASS_BLACK
00633 + SG_PROPCLASS_NOTCLEAN);
00634 SG_PROP_OT_WHITE = Register(intProp, "OW",
00635 SG_PROPCLASS_TIME + SG_PROPCLASS_WHITE
00636 + SG_PROPCLASS_NOTCLEAN);
00637 SG_PROP_OT_NU_MOVES = Register(intProp, "OM",
00638 SG_PROPCLASS_TIME + SG_PROPCLASS_ROOT
00639 + SG_PROPCLASS_CUSTOM
00640 + SG_PROPCLASS_NOTCLEAN);
00641 SG_PROP_OT_PERIOD = Register(timeProp, "OP",
00642 SG_PROPCLASS_TIME + SG_PROPCLASS_ROOT
00643 + SG_PROPCLASS_CUSTOM + SG_PROPCLASS_NOTCLEAN);
00644 SG_PROP_OVERHEAD = Register(timeProp, "OV",
00645 SG_PROPCLASS_TIME + SG_PROPCLASS_ROOT
00646 + SG_PROPCLASS_CUSTOM + SG_PROPCLASS_NOTCLEAN);
00647 SG_PROP_LOSE_TIME = Register(simpleProp, "LT",
00648 SG_PROPCLASS_TIME + SG_PROPCLASS_ROOT
00649 + SG_PROPCLASS_CUSTOM + SG_PROPCLASS_NOTCLEAN);
00650
00651
00652
00653 SG_PROP_COUNT = Register(0, "CN",
00654 SG_PROPCLASS_STAT + SG_PROPCLASS_ABSTRACT);
00655 SG_PROP_TIME_USED = Register(mSecProp, "TU",
00656 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00657 + SG_PROPCLASS_NOTCLEAN);
00658 SG_PROP_NUM_NODES = Register(intProp, "NN",
00659 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00660 + SG_PROPCLASS_NOTCLEAN);
00661 SG_PROP_NUM_LEAFS = Register(intProp, "NL",
00662 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00663 + SG_PROPCLASS_NOTCLEAN);
00664 SG_PROP_MAX_DEPTH = Register(intProp, "MD",
00665 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00666 + SG_PROPCLASS_NOTCLEAN);
00667 SG_PROP_DEPTH = Register(intProp, "DE",
00668 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00669 + SG_PROPCLASS_NOTCLEAN);
00670 SG_PROP_PART_DEPTH = Register(intProp, "PD",
00671 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00672 + SG_PROPCLASS_NOTCLEAN);
00673 SG_PROP_EVAL = Register(valueProp, "EL",
00674 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00675 + SG_PROPCLASS_NOTCLEAN);
00676 SG_PROP_EXPECTED = Register(moveProp, "EX",
00677 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00678 + SG_PROPCLASS_NOTCLEAN);
00679
00680
00681 SG_PROP_FORMAT = Register(intProp, "FF", SG_PROPCLASS_ROOT);
00682 SG_PROP_SIZE = Register(intProp, "SZ", SG_PROPCLASS_ROOT);
00683 SG_PROP_GAME = Register(intProp, "GM", SG_PROPCLASS_ROOT);
00684
00685 SG_PROP_SPEC_BLACK = Register(intProp, "BS", SG_PROPCLASS_CUSTOM);
00686 SG_PROP_SPEC_WHITE = Register(intProp, "WS", SG_PROPCLASS_CUSTOM);
00687 SG_PROP_CHINESE = Register(intProp, "CI",
00688 SG_PROPCLASS_ROOT + SG_PROPCLASS_CUSTOM);
00689 SG_PROP_APPLIC = Register(textProp, "AP",
00690 SG_PROPCLASS_ROOT + SG_PROPCLASS_NOT_FF3);
00691
00692
00693 SG_PROP_ANNOTATE = Register(0, "",
00694 SG_PROPCLASS_ANNO + SG_PROPCLASS_ABSTRACT);
00695 SG_PROP_COMMENT = Register(textProp, "C",
00696 SG_PROPCLASS_ANNO + SG_PROPCLASS_NEWLINE);
00697 SG_PROP_NAME = Register(textProp, "N",
00698 SG_PROPCLASS_ANNO + SG_PROPCLASS_NEWLINE);
00699 SG_PROP_CHECK = Register(multipleProp, "CH",
00700 SG_PROPCLASS_ANNO + SG_PROPCLASS_CUSTOM);
00701 SG_PROP_SIGMA = Register(multipleProp, "SI",
00702 SG_PROPCLASS_ANNO + SG_PROPCLASS_CUSTOM);
00703 SG_PROP_HOTSPOT = Register(multipleProp, "HO",
00704 SG_PROPCLASS_ANNO + SG_PROPCLASS_CUSTOM);
00705 SG_PROP_FIGURE = Register(simpleProp, "FG",
00706 SG_PROPCLASS_ANNO + SG_PROPCLASS_NEWLINE);
00707
00708
00709 SG_PROP_POS_ANNO = Register(0, "",
00710 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_POS
00711 + SG_PROPCLASS_ABSTRACT);
00712 SG_PROP_GOOD_BLACK = Register(multipleProp, "GB",
00713 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_POS
00714 + SG_PROPCLASS_BLACK);
00715 SG_PROP_GOOD_WHITE = Register(multipleProp, "GW",
00716 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_POS
00717 + SG_PROPCLASS_WHITE);
00718 SG_PROP_EVEN_POS = Register(multipleProp, "DM",
00719 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_POS);
00720 SG_PROP_UNCLEAR = Register(multipleProp, "UC",
00721 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_POS);
00722
00723
00724 SG_PROP_MOVE_ANNO = Register(0, "",
00725 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_MOVE
00726 + SG_PROPCLASS_ABSTRACT);
00727 SG_PROP_GOOD_MOVE = Register(multipleProp, "TE",
00728 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_MOVE);
00729 SG_PROP_BAD_MOVE = Register(multipleProp, "BM",
00730 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_MOVE);
00731 SG_PROP_INTERESTING = Register(simpleProp, "IT",
00732 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_MOVE);
00733 SG_PROP_DOUBTFUL = Register(simpleProp, "DO",
00734 SG_PROPCLASS_ANNO + SG_PROPCLASS_ANNO_MOVE);
00735
00736
00737 SG_PROP_INFO = Register(0, "", SG_PROPCLASS_INFO + SG_PROPCLASS_ABSTRACT);
00738 SG_PROP_GAME_NAME = Register(textProp, "GN",
00739 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00740 SG_PROP_GAME_COMMENT = Register(textProp, "GC",
00741 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00742 SG_PROP_EVENT = Register(textProp, "EV",
00743 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00744 SG_PROP_ROUND = Register(textProp, "RO", SG_PROPCLASS_INFO);
00745 SG_PROP_DATE = Register(textProp, "DT",
00746 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00747 SG_PROP_PLACE = Register(textProp, "PC",
00748 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00749 SG_PROP_PLAYER_BLACK = Register(textProp, "PB",
00750 SG_PROPCLASS_INFO + SG_PROPCLASS_BLACK
00751 + SG_PROPCLASS_NEWLINE);
00752 SG_PROP_PLAYER_WHITE = Register(textProp, "PW",
00753 SG_PROPCLASS_INFO + SG_PROPCLASS_WHITE
00754 + SG_PROPCLASS_NEWLINE);
00755 SG_PROP_RESULT = Register(textProp, "RE",
00756 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00757 SG_PROP_USER = Register(textProp, "US",
00758 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00759 SG_PROP_TIME = Register(textProp, "TM", SG_PROPCLASS_INFO);
00760 SG_PROP_SOURCE = Register(textProp, "SO",
00761 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00762 SG_PROP_COPYRIGHT = Register(textProp, "CP", SG_PROPCLASS_INFO);
00763 SG_PROP_ANALYSIS = Register(textProp, "AN", SG_PROPCLASS_INFO);
00764 SG_PROP_RANK_BLACK = Register(textProp, "BR",
00765 SG_PROPCLASS_INFO + SG_PROPCLASS_BLACK);
00766 SG_PROP_RANK_WHITE = Register(textProp, "WR",
00767 SG_PROPCLASS_INFO + SG_PROPCLASS_WHITE);
00768 SG_PROP_TEAM_BLACK = Register(textProp, "BT",
00769 SG_PROPCLASS_INFO + SG_PROPCLASS_BLACK);
00770 SG_PROP_TEAM_WHITE = Register(textProp, "WT"
00771 , SG_PROPCLASS_INFO + SG_PROPCLASS_WHITE);
00772 SG_PROP_OPENING = Register(textProp, "ON",
00773 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00774 SG_PROP_RULES = Register(textProp, "RU",
00775 SG_PROPCLASS_INFO + SG_PROPCLASS_NEWLINE);
00776 SG_PROP_HANDICAP = Register(intProp, "HA", SG_PROPCLASS_INFO);
00777 SG_PROP_KOMI = Register(realProp, "KM", SG_PROPCLASS_INFO);
00778
00779
00780 SG_PROP_FIND_MOVE = Register(0, "", SG_PROPCLASS_ABSTRACT);
00781 SG_PROP_FIND_TEXT = Register(0, "", SG_PROPCLASS_ABSTRACT);
00782 SG_PROP_BRANCH = Register(0, "", SG_PROPCLASS_ABSTRACT);
00783 SG_PROP_TERMINAL = Register(0, "", SG_PROPCLASS_ABSTRACT);
00784
00785
00786 SG_PROP_MOTIVE = Register(textListProp, "MM",
00787 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00788 + SG_PROPCLASS_NOTCLEAN);
00789 SG_PROP_SEQUENCE = Register(listProp, "MS",
00790 SG_PROPCLASS_STAT + SG_PROPCLASS_CUSTOM
00791 + SG_PROPCLASS_NOTCLEAN);
00792 SG_PROP_NOT_EMPTY = Register(listProp, "NE",
00793 SG_PROPCLASS_MARK + SG_PROPCLASS_CUSTOM
00794 + SG_PROPCLASS_NOTCLEAN);
00795 SG_PROP_NOT_BLACK = Register(listProp, "NB",
00796 SG_PROPCLASS_MARK + SG_PROPCLASS_CUSTOM
00797 + SG_PROPCLASS_NOTCLEAN);
00798 SG_PROP_NOT_WHITE = Register(listProp, "NW",
00799 SG_PROPCLASS_MARK + SG_PROPCLASS_CUSTOM
00800 + SG_PROPCLASS_NOTCLEAN);
00801
00802 s_initialized = true;
00803 }
00804
00805 void SgProp::Fini()
00806 {
00807 s_initialized = false;
00808 }
00809
00810
00811
00812 SgProp* SgPropUnknown::Duplicate() const
00813 {
00814 return new SgPropUnknown(m_id, m_label, m_values);
00815 }
00816
00817 bool SgPropUnknown::ToString(std::vector<std::string>& values, int boardSize,
00818 SgPropPointFmt fmt, int fileFormat) const
00819 {
00820 SG_UNUSED(boardSize);
00821 SG_UNUSED(fmt);
00822 SG_UNUSED(fileFormat);
00823 values.clear();
00824 for (vector<string>::const_iterator it = m_values.begin();
00825 it != m_values.end(); ++it)
00826 values.push_back(EscapeSpecialCharacters(*it, false));
00827 return true;
00828 }
00829
00830 bool SgPropUnknown::FromString(const std::vector<std::string>& values,
00831 int boardSize, SgPropPointFmt fmt)
00832 {
00833 SG_UNUSED(boardSize);
00834 SG_UNUSED(fmt);
00835 m_values = values;
00836 return true;
00837 }
00838
00839
00840
00841 SgProp* SgPropSimple::Duplicate() const
00842 {
00843 return new SgPropSimple(m_id);
00844 }
00845
00846 bool SgPropSimple::ToString(std::vector<std::string>& values, int boardSize,
00847 SgPropPointFmt fmt, int fileFormat) const
00848 {
00849 SG_UNUSED(boardSize);
00850 SG_UNUSED(fmt);
00851 SG_UNUSED(fileFormat);
00852 values.assign(1, "");
00853 return true;
00854 }
00855
00856 bool SgPropSimple::FromString(const std::vector<std::string>& values,
00857 int boardSize, SgPropPointFmt fmt)
00858 {
00859 SG_UNUSED(values);
00860 SG_UNUSED(boardSize);
00861 SG_UNUSED(fmt);
00862 return true;
00863 }
00864
00865
00866
00867 SgProp* SgPropMultiple::Duplicate() const
00868 {
00869 return new SgPropMultiple(m_id, m_value);
00870 }
00871
00872
00873
00874 SgProp* SgPropInt::Duplicate() const
00875 {
00876 return new SgPropInt(m_id, m_value);
00877 }
00878
00879 bool SgPropInt::ToString(std::vector<std::string>& values, int boardSize,
00880 SgPropPointFmt fmt, int fileFormat) const
00881 {
00882 SG_UNUSED(fileFormat);
00883 SG_UNUSED(boardSize);
00884 SG_UNUSED(fmt);
00885 ostringstream buffer;
00886 buffer << m_value;
00887 values.assign(1, buffer.str());
00888 return true;
00889 }
00890
00891 bool SgPropInt::FromString(const std::vector<std::string>& values,
00892 int boardSize, SgPropPointFmt fmt)
00893 {
00894 SG_UNUSED(boardSize);
00895 SG_UNUSED(fmt);
00896 if (values.empty())
00897 {
00898 m_value = 0;
00899 return true;
00900 }
00901 istringstream in(values[0]);
00902 in >> m_value;
00903 return (! in.fail());
00904 }
00905
00906
00907
00908 SgProp* SgPropReal::Duplicate() const
00909 {
00910 return new SgPropReal(m_id, m_value, m_precision);
00911 }
00912
00913 bool SgPropReal::ToString(std::vector<std::string>& values, int boardSize,
00914 SgPropPointFmt fmt, int fileFormat) const
00915 {
00916 SG_UNUSED(boardSize);
00917 SG_UNUSED(fmt);
00918 SG_UNUSED(fileFormat);
00919 ostringstream buffer;
00920 if (m_precision > 0)
00921 buffer.precision(m_precision);
00922 buffer << fixed << m_value;
00923 values.assign(1, buffer.str());
00924 return true;
00925 }
00926
00927 bool SgPropReal::FromString(const std::vector<std::string>& values,
00928 int boardSize, SgPropPointFmt fmt)
00929 {
00930 SG_UNUSED(boardSize);
00931 SG_UNUSED(fmt);
00932 if (values.empty())
00933 {
00934 m_value = 0;
00935 return true;
00936 }
00937 istringstream in(values[0]);
00938 in >> m_value;
00939 return (! in.fail());
00940 }
00941
00942
00943
00944 void SgPropValue::ChangeToOpponent()
00945 {
00946 m_value = -m_value;
00947 }
00948
00949 SgProp* SgPropValue::Duplicate() const
00950 {
00951 return new SgPropValue(m_id, m_value);
00952 }
00953
00954
00955
00956 SgPropTime::~SgPropTime()
00957 {
00958 }
00959
00960 SgProp* SgPropTime::Duplicate() const
00961 {
00962 return new SgPropTime(m_id, m_value, m_precision);
00963 }
00964
00965
00966
00967 SgPropMSec::~SgPropMSec()
00968 {
00969 }
00970
00971 SgProp* SgPropMSec::Duplicate() const
00972 {
00973 return new SgPropMSec(m_id, m_value);
00974 }
00975
00976
00977
00978 SgPropPointList::SgPropPointList(SgPropID id,
00979 const SgVector<SgPoint>& vector)
00980 : SgProp(id),
00981 m_list(vector)
00982 {
00983 }
00984
00985 SgPropPointList::~SgPropPointList()
00986 {
00987 }
00988
00989 SgProp* SgPropPointList::Duplicate() const
00990 {
00991 return new SgPropPointList(ID(), Value());
00992 }
00993
00994 bool SgPropPointList::ToString(std::vector<std::string>& values,
00995 int boardSize, SgPropPointFmt fmt,
00996 int fileFormat) const
00997 {
00998
00999 if (Value().IsEmpty())
01000 return false;
01001 values.clear();
01002 for (SgVectorIterator<SgPoint> it(Value()); it; ++it)
01003 {
01004 if (! SgIsSpecialMove(*it))
01005 values.push_back(PointToSgfString(*it, boardSize, fmt,
01006 fileFormat));
01007 }
01008 return true;
01009 }
01010
01011 bool SgPropPointList::FromString(const std::vector<std::string>& values,
01012 int boardSize, SgPropPointFmt fmt)
01013 {
01014 for (vector<string>::const_iterator it = values.begin();
01015 it != values.end(); ++it)
01016 {
01017 string s = *it;
01018 if (s.size() == 5 && s[2] == ':')
01019 {
01020
01021 string s1 = s.substr(0, 2);
01022 string s2 = s.substr(3, 2);
01023 SgPoint p1 = SgfStringToPoint(s1, boardSize, fmt);
01024 SgPoint p2 = SgfStringToPoint(s2, boardSize, fmt);
01025 if (InBoardRange(p1) && InBoardRange(p2))
01026 {
01027 SgRect rect(p1, p2);
01028 for (SgRectIterator iter(rect); iter; ++iter)
01029 Value().PushBack(*iter);
01030 }
01031 else
01032 {
01033 return false;
01034 }
01035 }
01036 else
01037 {
01038
01039 SgPoint p = SgfStringToPoint(s, boardSize, fmt);
01040 if (InBoardRange(p) || p == SG_PASS)
01041
01042 Value().PushBack(p);
01043 else
01044 return false;
01045 }
01046 }
01047 return true;
01048 }
01049
01050
01051
01052 SgProp* SgPropText::Duplicate() const
01053 {
01054 return new SgPropText(m_id, m_text);
01055 }
01056
01057 bool SgPropText::ToString(std::vector<std::string>& values, int boardSize,
01058 SgPropPointFmt fmt, int fileFormat) const
01059 {
01060 SG_UNUSED(fileFormat);
01061 SG_UNUSED(boardSize);
01062 SG_UNUSED(fmt);
01063 values.assign(1, EscapeSpecialCharacters(m_text, false));
01064 return true;
01065 }
01066
01067 bool SgPropText::FromString(const std::vector<std::string>& values,
01068 int boardSize, SgPropPointFmt fmt)
01069 {
01070 SG_UNUSED(boardSize);
01071 SG_UNUSED(fmt);
01072 if (values.size() == 0)
01073 m_text = "";
01074 else
01075 m_text = values[0];
01076 return true;
01077 }
01078
01079 bool SgPropText::ContainsText(const string& findText)
01080 {
01081 return (m_text.find(findText) != string::npos);
01082 }
01083
01084
01085
01086 SgPropTextList::SgPropTextList(SgPropID id, const SgVector<SgPoint>& points,
01087 SgVectorOf<std::string> strings)
01088 : SgProp(id),
01089 m_points(points),
01090 m_strings()
01091 {
01092 for (SgVectorIteratorOf<string> it(strings); it; ++it)
01093 {
01094 m_strings.PushBack(new string(*(*it)));
01095 }
01096 }
01097
01098 SgPropTextList::~SgPropTextList()
01099 {
01100 for (SgVectorIteratorOf<string> it(m_strings); it; ++it)
01101 {
01102 delete *it;
01103 }
01104 }
01105
01106 SgProp* SgPropTextList::Duplicate() const
01107 {
01108 return new SgPropTextList(m_id, m_points, m_strings);
01109 }
01110
01111 bool SgPropTextList::GetStringAtPoint(SgPoint p, string* s) const
01112 {
01113 int index = m_points.Index(p);
01114 if (index >= 0)
01115 {
01116 *s = *m_strings[index];
01117 return true;
01118 }
01119 return false;
01120 }
01121
01122 void SgPropTextList::AddStringAtPoint(SgPoint p, const string& s)
01123 {
01124 ClearStringAtPoint(p);
01125 m_points.PushBack(p);
01126 m_strings.PushBack(new string(s));
01127 }
01128
01129 void SgPropTextList::AppendToStringAtPoint(SgPoint p, const string& s)
01130 {
01131 string value;
01132 GetStringAtPoint(p, &value);
01133 value += s;
01134 AddStringAtPoint(p, value);
01135 }
01136
01137 void SgPropTextList::ClearStringAtPoint(SgPoint p)
01138 {
01139 int index = m_points.Index(p);
01140 if (index >= 0)
01141 {
01142 m_points.DeleteAt(index);
01143 delete m_strings[index];
01144 m_strings.DeleteAt(index);
01145 }
01146 }
01147
01148 bool SgPropTextList::ToString(std::vector<std::string>& values,
01149 int boardSize, SgPropPointFmt fmt,
01150 int fileFormat) const
01151 {
01152
01153 if (m_points.IsEmpty())
01154 return false;
01155 values.clear();
01156 int index = 0;
01157 for (SgVectorIterator<SgPoint> it(m_points); it; ++it)
01158 {
01159 ostringstream buffer;
01160 buffer << PointToSgfString(*it, boardSize, fmt, fileFormat) << ':'
01161 << EscapeSpecialCharacters(*m_strings[index], true)
01162 ;
01163 values.push_back(buffer.str());
01164 ++index;
01165 }
01166 return true;
01167 }
01168
01169 bool SgPropTextList::FromString(const std::vector<std::string>& values,
01170 int boardSize, SgPropPointFmt fmt)
01171 {
01172 for (vector<string>::const_iterator it = values.begin();
01173 it != values.end(); ++it)
01174 {
01175 string s = *it;
01176 if (s.size() >= 2)
01177 {
01178 string pointString = s.substr(0, 2);
01179 SgPoint p = SgfStringToPoint(pointString, boardSize, fmt);
01180 if (InBoardRange(p) && s.size() >= 3 && s[2] == ':')
01181 {
01182 string text = s.substr(3);
01183 AddStringAtPoint(p, text);
01184 return true;
01185 }
01186 }
01187 }
01188 return false;
01189 }
01190
01191 bool SgPropTextList::ContainsText(const string& findText)
01192 {
01193 for (SgVectorIteratorOf<string> it(m_strings); it; ++it)
01194 {
01195 if ((*it)->find(findText) != string::npos)
01196 return true;
01197 }
01198 return false;
01199 }
01200
01201
01202
01203 SgProp* SgPropPlayer::Duplicate() const
01204 {
01205 return new SgPropPlayer(m_id, m_player);
01206 }
01207
01208 bool SgPropPlayer::ToString(std::vector<std::string>& values, int boardSize,
01209 SgPropPointFmt fmt, int fileFormat) const
01210 {
01211 SG_UNUSED(fileFormat);
01212 SG_UNUSED(boardSize);
01213 SG_UNUSED(fmt);
01214 values.assign(1, m_player == SG_WHITE ? "W" : "B");
01215 return true;
01216 }
01217
01218 bool SgPropPlayer::FromString(const std::vector<std::string>& values,
01219 int boardSize, SgPropPointFmt fmt)
01220 {
01221 SG_UNUSED(boardSize);
01222 SG_UNUSED(fmt);
01223 if (values.size() == 0)
01224 return false;
01225 m_player = (values[0] == "W" || values[0] == "w") ? SG_WHITE : SG_BLACK;
01226 return true;
01227 }
01228
01229 void SgPropPlayer::ChangeToOpponent()
01230 {
01231 m_player = SgOppBW(m_player);
01232 }
01233
01234
01235
01236 SgPropAddStone::~SgPropAddStone()
01237 {
01238 }
01239
01240 SgProp* SgPropAddStone::Duplicate() const
01241 {
01242 return new SgPropAddStone(m_id, Value());
01243 }
01244
01245
01246
01247 SgProp* SgPropMove::Duplicate() const
01248 {
01249 return new SgPropMove(m_id, m_move);
01250 }
01251
01252 bool SgPropMove::ToString(std::vector<std::string>& values, int boardSize,
01253 SgPropPointFmt fmt, int fileFormat) const
01254 {
01255 values.assign(1, PointToSgfString(m_move, boardSize, fmt, fileFormat));
01256 return true;
01257 }
01258
01259 bool SgPropMove::FromString(const std::vector<std::string>& values,
01260 int boardSize, SgPropPointFmt fmt)
01261 {
01262 if (values.size() == 0)
01263 return false;
01264 m_move = SgfStringToPoint(values[0], boardSize, fmt);
01265 return m_move != SG_NULLMOVE;
01266 }
01267
01268
01269