00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "SgSystem.h"
00016 #include "SgNode.h"
00017
00018 #include <sstream>
00019 #include "SgPointSet.h"
00020 #include "SgProp.h"
00021 #include "SgVector.h"
00022
00023 using namespace std;
00024
00025
00026
00027 SgNode::SgNode()
00028 : m_son(0),
00029 m_father(0),
00030 m_brother(0),
00031 m_props(),
00032 m_marked(false)
00033 {
00034 #ifndef NDEBUG
00035 ++s_alloc;
00036 #endif
00037 }
00038
00039 SgNode::~SgNode()
00040 {
00041 if (HasLeftBrother())
00042 {
00043 SgNode* left = LeftBrother();
00044
00045
00046 left->m_brother = m_son;
00047 LinkWithBrother(left);
00048 }
00049 else if (HasFather())
00050 {
00051 if (HasSon())
00052 {
00053
00054
00055 m_father->m_son = m_son;
00056 m_son->m_father = m_father;
00057 LinkWithBrother(m_son);
00058 }
00059 else
00060 {
00061
00062
00063 m_father->m_son = m_brother;
00064 }
00065 }
00066 else
00067
00068
00069 SG_ASSERT(m_son == 0);
00070
00071 #ifndef NDEBUG
00072 ++s_free;
00073 #endif
00074 }
00075
00076 void SgNode::CopySubtree(const SgNode* node, SgNode* copy)
00077 {
00078 for (const SgNode* son = node->LeftMostSon(); son;
00079 son = son->RightBrother())
00080 {
00081 SgNode* sonCopy = copy->NewRightMostSon();
00082 sonCopy->CopyAllPropsFrom(*son);
00083 CopySubtree(son, sonCopy);
00084 }
00085 }
00086
00087 SgNode* SgNode::CopyTree() const
00088 {
00089 SgNode* newNode = new SgNode();
00090 if (newNode)
00091 {
00092 newNode->CopyAllPropsFrom(*this);
00093 CopySubtree(this, newNode);
00094 }
00095 return newNode;
00096 }
00097
00098 bool SgNode::HasLeftBrother() const
00099 {
00100 return HasFather() && Father()->LeftMostSon() != this;
00101 }
00102
00103 bool SgNode::IsOnMain() const
00104 {
00105
00106
00107 const SgNode* t = this;
00108 while (true)
00109 {
00110 SgNode* father = t->m_father;
00111 if (father == 0)
00112 return true;
00113 if (father->m_son != t)
00114 return false;
00115 t = father;
00116 }
00117 }
00118
00119
00120
00121 void SgNode::LinkWithBrother(SgNode* node)
00122 {
00123 while (node->HasRightBrother())
00124 {
00125 node = node->RightBrother();
00126 node->m_father = m_father;
00127 }
00128 node->m_brother = m_brother;
00129 }
00130
00131 SgVector<SgPoint> SgNode::VectorProp(SgPropID prop) const
00132 {
00133 SgPropPointList* lp = dynamic_cast<SgPropPointList*>(Get(prop));
00134 if (lp)
00135 return lp->Value();
00136 return SgVector<SgPoint>();
00137 }
00138
00139 int SgNode::NumSons() const
00140 {
00141 int n = 0;
00142 if (HasSon())
00143 {
00144 SgNode* node = LeftMostSon();
00145 ++n;
00146 while (node->HasRightBrother())
00147 {
00148 node = node->RightBrother();
00149 ++n;
00150 }
00151 }
00152 return n;
00153 }
00154
00155 int SgNode::NumLeftBrothers() const
00156 {
00157 int numBrothers = 0;
00158 SgNode* node = Father();
00159 if (node)
00160 {
00161 node = node->LeftMostSon();
00162 while (node != this)
00163 {
00164 node = node->RightBrother();
00165 ++numBrothers;
00166 }
00167 }
00168 return numBrothers;
00169 }
00170
00171 SgNode* SgNode::Root() const
00172 {
00173 SgNode* node = const_cast<SgNode*>(this);
00174 while (node->HasFather())
00175 node = node->Father();
00176 return node;
00177 }
00178
00179 SgNode* SgNode::LeftBrother() const
00180 {
00181 if (! HasFather() || ! HasLeftBrother())
00182 return 0;
00183 SgNode* node = Father()->LeftMostSon();
00184 while (node->RightBrother() != this)
00185 node = node->RightBrother();
00186 return node;
00187 }
00188
00189 SgNode* SgNode::RightMostSon() const
00190 {
00191 SgNode* node = LeftMostSon();
00192 if (node)
00193 {
00194 while (node->HasRightBrother())
00195 node = node->RightBrother();
00196 }
00197 return node;
00198 }
00199
00200 SgNode* SgNode::NextDepthFirst() const
00201 {
00202 if (HasSon())
00203 return LeftMostSon();
00204 else
00205 {
00206 SgNode* node = const_cast<SgNode*>(this);
00207 while (node->HasFather() && ! node->HasRightBrother())
00208 node = node->Father();
00209 if (node->HasRightBrother())
00210 node = node->RightBrother();
00211 return node;
00212 }
00213 }
00214
00215 SgNode* SgNode::PrevDepthFirst() const
00216 {
00217 SgNode* node = const_cast<SgNode*>(this);
00218 if (HasLeftBrother() || ! HasFather())
00219 {
00220 if (HasLeftBrother())
00221 node = LeftBrother();
00222 while (node->HasSon())
00223 node = node->RightMostSon();
00224 }
00225 else
00226 node = Father();
00227 return node;
00228 }
00229
00230 void SgNode::PathToRoot(SgVectorOf<SgNode>* path) const
00231 {
00232 path->Clear();
00233 for (SgNode* node = const_cast<SgNode*>(this); node;
00234 node = node->Father())
00235 path->PushBack(node);
00236 }
00237
00238 SgNode* SgNode::NodeInDirection(Direction dir) const
00239 {
00240 SgNode* node = 0;
00241 switch (dir)
00242 {
00243 case PREVIOUS:
00244 node = Father();
00245 break;
00246 case NEXT:
00247 node = LeftMostSon();
00248 break;
00249 case NEXT_RIGHTMOST:
00250 node = RightMostSon();
00251 break;
00252 case PREV_DEPTHFIRST:
00253 node = PrevDepthFirst();
00254 break;
00255 case NEXT_DEPTHFIRST:
00256 node = NextDepthFirst();
00257 break;
00258 case PREV_TERMINAL:
00259 node = PrevDepthFirst();
00260 while (! node->IsTerminal())
00261 node = node->PrevDepthFirst();
00262 break;
00263 case NEXT_TERMINAL:
00264 node = NextDepthFirst();
00265 while (! node->IsTerminal())
00266 node = node->NextDepthFirst();
00267 break;
00268 case PREV_BRANCH:
00269 node = Father();
00270 while (node && node->HasFather() && ! node->IsBranchPoint())
00271 node = node->Father();
00272 break;
00273 case NEXT_BRANCH:
00274 node = LeftMostSon();
00275 while (node && ! node->IsTerminal() && ! node->IsBranchPoint())
00276 node = node->LeftMostSon();
00277 break;
00278 case LEFT_BROTHER:
00279 if (HasLeftBrother())
00280 node = LeftBrother();
00281 else if (HasBrother())
00282 node = Father()->RightMostSon();
00283 break;
00284 case RIGHT_BROTHER:
00285 if (HasRightBrother())
00286 node = RightBrother();
00287 else if (HasBrother())
00288 node = Father()->LeftMostSon();
00289 break;
00290 case MAIN_BRANCH:
00291 {
00292 SgNode* t = const_cast<SgNode*>(this);
00293 while (t->HasFather())
00294 {
00295 if (t->HasLeftBrother())
00296 node = t->Father();
00297 t = t->Father();
00298 }
00299 }
00300 break;
00301 case START_OF_GAME:
00302 node = Root();
00303 break;
00304 case END_OF_GAME:
00305 node = const_cast<SgNode*>(this);
00306 while (! node->IsTerminal())
00307 node = node->LeftMostSon();
00308 break;
00309 default:
00310 SG_ASSERT(false);
00311 }
00312 return node;
00313 }
00314
00315 bool SgNode::ContainsText(const string& findText)
00316 {
00317
00318 SG_ASSERT(SgProp::ConvertFindTextToPropID(findText) == SG_PROP_NONE);
00319 return m_props.GetPropContainingText(findText) != 0;
00320 }
00321
00322
00323 void SgNode::AddComment(const std::string& comment)
00324 {
00325 SgPropText* textProp = static_cast<SgPropText*>(Get(SG_PROP_COMMENT));
00326 if (textProp)
00327 textProp->AppendText(comment);
00328 else
00329 {
00330 textProp = new SgPropText(SG_PROP_COMMENT, comment);
00331 Add(textProp);
00332 }
00333 }
00334
00335 bool SgNode::HasProp(SgPropID id) const
00336 {
00337 if (id == SG_PROP_TERMINAL)
00338 return IsTerminal();
00339 else if (id == SG_PROP_BRANCH)
00340 return IsBranchPoint();
00341 else
00342 return Get(id) != 0;
00343 }
00344
00345
00346
00347
00348 void SgNode::ShortestPathTo(SgNode* node, int* numBack,
00349 SgVectorOf<SgNode>* path) const
00350 {
00351
00352
00353 SgNode* x = const_cast<SgNode*>(this);
00354 SgNode* y = node;
00355 SgNode* common = 0;
00356 while (true)
00357 {
00358 if (x)
00359 {
00360 if (x->IsMarked())
00361 {
00362 common = x;
00363 break;
00364 }
00365 x->Mark();
00366 x = x->m_father;
00367 }
00368 if (y)
00369 {
00370 if (y->IsMarked())
00371 {
00372 common = y;
00373 break;
00374 }
00375 y->Mark();
00376 y = y->m_father;
00377 }
00378 if (! x && ! y)
00379 {
00380 break;
00381 }
00382 }
00383
00384
00385
00386 for (x = common; x && x->IsMarked(); x = x->m_father)
00387 {
00388 x->Unmark();
00389 }
00390
00391
00392 *numBack = 0;
00393
00394 for (x = const_cast<SgNode*>(this); x != common; x = x->m_father)
00395 {
00396 SG_ASSERT(x->IsMarked());
00397 x->Unmark();
00398 ++(*numBack);
00399 }
00400
00401
00402 path->Clear();
00403 for (x = node; x != common; x = x->m_father)
00404 {
00405 SG_ASSERT(x->IsMarked());
00406 x->Unmark();
00407 path->PushBack(x);
00408 }
00409 path->Reverse();
00410 }
00411
00412 void SgNode::PromoteNode()
00413 {
00414 if (HasLeftBrother())
00415 {
00416 SgNode* brotherOfThis = m_brother;
00417 m_brother = m_father->m_son;
00418 m_father->m_son = this;
00419 SgNode* x = this;
00420 while (x->m_brother != this)
00421 x = x->m_brother;
00422 x->m_brother = brotherOfThis;
00423 }
00424 }
00425
00426 void SgNode::PromotePath()
00427 {
00428 SgNode* node = this;
00429 while (node)
00430 {
00431 node->PromoteNode();
00432 node = node->Father();
00433 }
00434 }
00435
00436 void SgNode::DeleteSubtree()
00437 {
00438
00439
00440 while (HasSon())
00441 delete LeftMostSon();
00442 }
00443
00444 void SgNode::DeleteBranches()
00445 {
00446 SgNode* main = LeftMostSon();
00447 while (main)
00448 {
00449 SgNode* brother = main->RightBrother();
00450 while (brother)
00451 {
00452 SgNode* nextToDelete = brother->RightBrother();
00453 brother->DeleteSubtree();
00454 delete brother;
00455 brother = nextToDelete;
00456 }
00457 main = main->LeftMostSon();
00458 }
00459 }
00460
00461 void SgNode::DeleteTree()
00462 {
00463 SgNode* root = Root();
00464 root->DeleteSubtree();
00465 delete root;
00466 }
00467
00468 SgNode* SgNode::NewFather()
00469 {
00470 SgNode* n = new SgNode();
00471 if (HasLeftBrother())
00472 {
00473 SgNode* left = LeftBrother();
00474 left->m_brother = n;
00475 }
00476 else
00477 m_father->m_son = n;
00478 n->m_son = this;
00479 n->m_brother = m_brother;
00480 n->m_father = m_father;
00481 m_brother = 0;
00482 m_father = n;
00483 return n;
00484 }
00485
00486 SgNode* SgNode::NewRightBrother()
00487 {
00488 SgNode* n = new SgNode();
00489 n->m_brother = m_brother;
00490 n->m_father = m_father;
00491 m_brother = n;
00492 return n;
00493 }
00494
00495 SgNode* SgNode::NewLeftMostSon()
00496 {
00497 SgNode* n = new SgNode();
00498 n->m_father = this;
00499 n->m_brother = m_son;
00500 m_son = n;
00501 return n;
00502 }
00503
00504 SgNode* SgNode::NewRightMostSon()
00505 {
00506 if (HasSon())
00507 return RightMostSon()->NewRightBrother();
00508 else
00509 return NewLeftMostSon();
00510 }
00511
00512 SgNode* SgNode::LinkTrees(const SgVectorOf<SgNode>& roots)
00513 {
00514 SgNode* super = new SgNode();
00515 SgNode* previous = 0;
00516 for (SgVectorIteratorOf<SgNode> iter(roots); iter; ++iter)
00517 {
00518 SgNode* root = *iter;
00519 SG_ASSERT(! root->HasFather());
00520 if (previous)
00521 previous->m_brother = root;
00522 else
00523 super->m_son = root;
00524 root->m_father = super;
00525 previous = root;
00526 }
00527 return super;
00528 }
00529
00530 void SgNode::AppendTo(SgNode* n)
00531 {
00532 SG_ASSERT(! HasFather());
00533 SG_ASSERT(! HasBrother());
00534 SG_ASSERT(n);
00535 if (n->HasSon())
00536 {
00537 SgNode* t = n->RightMostSon();
00538 t->m_brother = this;
00539 }
00540 else
00541 n->m_son = this;
00542 m_father = n;
00543 }
00544
00545 SgNode* SgNode::TopProp(SgPropID id) const
00546 {
00547 SgNode* node = const_cast<SgNode*>(this);
00548 while (node->HasFather() && ! node->Get(id))
00549 node = node->Father();
00550
00551 return node;
00552 }
00553
00554 int SgNode::GetIntProp(SgPropID id) const
00555 {
00556 SgPropInt* prop = static_cast<SgPropInt*>(Get(id));
00557 if (prop)
00558 return prop->Value();
00559 else
00560 return 0;
00561 }
00562
00563 bool SgNode::GetIntProp(SgPropID id, int* value) const
00564 {
00565 SgPropInt* prop = static_cast<SgPropInt*>(Get(id));
00566 if (prop)
00567 { *value = prop->Value();
00568 return true;
00569 }
00570
00571 return false;
00572 }
00573
00574 bool SgNode::HasNodeMove() const
00575 {
00576 return HasProp(SG_PROP_MOVE_BLACK) || HasProp(SG_PROP_MOVE_WHITE);
00577 }
00578
00579 SgBlackWhite SgNode::NodePlayer() const
00580 {
00581 SG_ASSERT(HasNodeMove());
00582 if (HasProp(SG_PROP_MOVE_BLACK))
00583 return SG_BLACK;
00584 return SG_WHITE;
00585 }
00586
00587 SgPoint SgNode::NodeMove() const
00588 {
00589 SgPoint p;
00590 if (GetIntProp(SG_PROP_MOVE_BLACK, &p))
00591 return p;
00592 else if (GetIntProp(SG_PROP_MOVE_WHITE, &p))
00593 return p;
00594 else
00595 return SG_NULLMOVE;
00596 }
00597
00598 double SgNode::GetRealProp(SgPropID id) const
00599 {
00600 SgPropReal* prop = dynamic_cast<SgPropReal*>(Get(id));
00601 if (prop)
00602 return prop->Value();
00603 else
00604 return 0;
00605 }
00606
00607 void SgNode::SetIntProp(SgPropID id, int value)
00608 {
00609 SgPropInt* prop = dynamic_cast<SgPropInt*>(Get(id));
00610 if (prop)
00611 prop->SetValue(value);
00612 else
00613 {
00614 prop = dynamic_cast<SgPropInt*>(SgProp::CreateProperty(id));
00615 prop->SetValue(value);
00616 Add(prop);
00617 }
00618 }
00619
00620 void SgNode::SetRealProp(SgPropID id, double value, int precision)
00621 {
00622 SgPropReal* prop = dynamic_cast<SgPropReal*>(Get(id));
00623 if (prop)
00624 prop->SetValue(value);
00625 else
00626 {
00627 prop = static_cast<SgPropReal*>(SgProp::CreateProperty(id));
00628 prop->SetValue(value, precision);
00629 Add(prop);
00630 }
00631 }
00632
00633 bool SgNode::GetStringProp(SgPropID id, string* value) const
00634 {
00635 SgPropText* prop = dynamic_cast<SgPropText*>(Get(id));
00636 if (prop)
00637 {
00638 *value = prop->Value();
00639 return true;
00640 }
00641 return false;
00642 }
00643
00644 void SgNode::SetStringProp(SgPropID id, const string& value)
00645 {
00646 SgPropText* prop = dynamic_cast<SgPropText*>(Get(id));
00647 if (prop)
00648 prop->SetValue(value);
00649 else
00650 {
00651 prop = static_cast<SgPropText*>(SgProp::CreateProperty(id));
00652 prop->SetValue(value);
00653 Add(prop);
00654 }
00655 }
00656
00657 void SgNode::SetListProp(SgPropID id, const SgVector<SgPoint>& value)
00658 {
00659 SgPropPointList* prop = dynamic_cast<SgPropPointList*>(Get(id));
00660 if (prop)
00661 prop->SetValue(value);
00662 else
00663 {
00664 prop = static_cast<SgPropPointList*>(SgProp::CreateProperty(id));
00665 prop->SetValue(value);
00666 Add(prop);
00667 }
00668 }
00669
00670 void SgNode::SetListProp(SgPropID id, const SgPointSet& value)
00671 {
00672 SgVector<SgPoint> valueList;
00673 value.ToVector(&valueList);
00674 SetListProp(id, valueList);
00675 }
00676
00677 void SgNode::CopyAllPropsFrom(const SgNode& sourceNode)
00678 {
00679 for (SgPropListIterator it(sourceNode.Props()); it; ++it)
00680 {
00681 SgProp* copy = (*it)->Duplicate();
00682 Add(copy);
00683 }
00684 }
00685
00686 SgProp* SgNode::CopyPropFrom(const SgNode& sourceNode, SgPropID id)
00687 {
00688 SgProp* sourceProp = sourceNode.Get(id);
00689 if (sourceProp)
00690 {
00691 SgProp* copy = sourceProp->Duplicate();
00692 Add(copy);
00693 return copy;
00694 }
00695 else
00696 return 0;
00697 }
00698
00699 SgProp* SgNode::AddMoveProp(SgMove move, SgBlackWhite player)
00700 {
00701 SG_ASSERT_BW(player);
00702 SgPropID id =
00703 (player == SG_BLACK) ? SG_PROP_MOVE_BLACK : SG_PROP_MOVE_WHITE;
00704 SgPropMove* moveProp = new SgPropMove(id, move);
00705 Add(moveProp);
00706 return moveProp;
00707 }
00708
00709 SgBlackWhite SgNode::Player() const
00710 {
00711 SG_ASSERT(Get(SG_PROP_PLAYER));
00712 return static_cast<SgPropPlayer*>(Get(SG_PROP_PLAYER))->Value();
00713 }
00714
00715 int SgNode::CountNodes(bool fSetPropOnThisNode)
00716 {
00717 int n = 1;
00718 for (SgSonNodeIterator son(this); son; ++son)
00719 n += (*son)->CountNodes(false);
00720
00721 if (fSetPropOnThisNode || IsBranchPoint())
00722 SetIntProp(SG_PROP_NUM_NODES, n);
00723 return n;
00724 }
00725
00726 #ifndef NDEBUG
00727 int SgNode::s_alloc = 0;
00728
00729 int SgNode::s_free = 0;
00730
00731 void SgNode::GetStatistics(int* numAlloc, int* numUsed)
00732 {
00733 *numAlloc = s_alloc;
00734 *numUsed = s_alloc - s_free;
00735 }
00736 #endif
00737
00738 void SgNode::MemCheck()
00739 {
00740 SG_ASSERT(s_alloc == s_free);
00741 }
00742
00743 string SgNode::TreeIndex(const SgNode* node)
00744 {
00745 ostringstream s;
00746 if (! node)
00747 s << "NIL";
00748 else
00749 {
00750 SgNode* father = node->Father();
00751 if (! father)
00752 s << '1';
00753 else
00754 {
00755 s << TreeIndex(father) << '.';
00756 SgNode* son = father->LeftMostSon();
00757 int index = 1;
00758 while ((son != node) && son)
00759 {
00760 ++index;
00761 son = son->RightBrother();
00762 }
00763 if (son == node)
00764 s << index;
00765 else
00766 SG_ASSERT(false);
00767 }
00768 }
00769 return s.str();
00770 }
00771
00772
00773
00774 SgNodeIterator::SgNodeIterator(SgNode* rootOfSubtree, bool postOrder)
00775 : m_postOrder(postOrder),
00776 m_rootOfSubtree(rootOfSubtree)
00777 {
00778 m_nextNode = m_rootOfSubtree;
00779 if (m_postOrder)
00780 {
00781 while (m_nextNode->HasSon())
00782 m_nextNode = m_nextNode->LeftMostSon();
00783 }
00784 }
00785
00786 SgNodeConstIterator::SgNodeConstIterator(const SgNode* rootOfSubtree,
00787 bool postOrder)
00788 : m_postOrder(postOrder),
00789 m_rootOfSubtree(rootOfSubtree)
00790 {
00791 m_nextNode = m_rootOfSubtree;
00792 if (m_postOrder)
00793 {
00794 while (m_nextNode->HasSon())
00795 m_nextNode = m_nextNode->LeftMostSon();
00796 }
00797 }
00798
00799 bool SgNodeIterator::Next()
00800 {
00801 if (m_nextNode)
00802 {
00803 if (m_postOrder)
00804 {
00805 if (m_nextNode == m_rootOfSubtree)
00806 m_nextNode = 0;
00807 else if (m_nextNode->HasRightBrother())
00808 {
00809 m_nextNode = m_nextNode->RightBrother();
00810 while (m_nextNode->HasSon())
00811 m_nextNode = m_nextNode->LeftMostSon();
00812 }
00813 else
00814 {
00815 SG_ASSERT(m_nextNode->HasFather());
00816 m_nextNode = m_nextNode->Father();
00817 }
00818 }
00819 else
00820 {
00821 m_nextNode = m_nextNode->NextDepthFirst();
00822 if (m_nextNode == m_rootOfSubtree)
00823 m_nextNode = 0;
00824 }
00825 return true;
00826 }
00827 else
00828 return false;
00829 }
00830
00831 bool SgNodeConstIterator::Next()
00832 {
00833 if (m_nextNode)
00834 {
00835 if (m_postOrder)
00836 {
00837 if (m_nextNode == m_rootOfSubtree)
00838 m_nextNode = 0;
00839 else if (m_nextNode->HasRightBrother())
00840 {
00841 m_nextNode = m_nextNode->RightBrother();
00842 while (m_nextNode->HasSon())
00843 m_nextNode = m_nextNode->LeftMostSon();
00844 }
00845 else
00846 {
00847 SG_ASSERT(m_nextNode->HasFather());
00848 m_nextNode = m_nextNode->Father();
00849 }
00850 }
00851 else
00852 {
00853 m_nextNode = m_nextNode->NextDepthFirst();
00854 if (m_nextNode == m_rootOfSubtree)
00855 m_nextNode = 0;
00856 }
00857 return true;
00858 }
00859 else
00860 return false;
00861 }
00862
00863
00864