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