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