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