Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgNode.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgNode.h
00003     Trees of nodes with properties.
00004 
00005     Module SgNode defines trees and operations on those trees. The abstract
00006     data type 'Node' represents a node in a tree; each node has a list of
00007     properties associated with it. Typical properties are moves, territory,
00008     values, and comments.
00009 
00010     Each node in the tree corresponds to a board position. The move leading
00011     to a position is stored in that node. The root node is the position where
00012     no move has as yet been played. Root nodes cannot have any brothers.
00013     There is no concept of "current position", as each node encodes both the
00014     tree it is in and its relation to other nodes in that tree. (The current
00015     position in the game is handled by GoGame.)
00016 
00017     The special node pointer 0 has no father, no sons, no brother,
00018     and no properties.
00019     It is usually returned from procedures to indicate failure.
00020     Because the tree is usually traversed depth-first, it is safe to assume
00021     that it is faster to go to the leftmost than to the rightmost son, and
00022     faster to go to the right brother than to the left brother.
00023 */
00024 //----------------------------------------------------------------------------
00025 
00026 #ifndef SG_NODE_H
00027 #define SG_NODE_H
00028 
00029 #include <string>
00030 #include "SgProp.h"
00031 #include "SgPointSet.h"
00032 #include "SgVector.h"
00033 
00034 //----------------------------------------------------------------------------
00035 
00036 /** Node in tree.
00037     Procedures for moving around in the tree return 0 if the desti-
00038     nation doesn't exist.
00039     References to "left" and "right" picture the tree with the root at the
00040     top and the main line of play going down the left side.
00041 */
00042 class SgNode
00043 {
00044 public:
00045     enum Direction {
00046         PREVIOUS,
00047         NEXT,
00048         NEXT_RIGHTMOST,
00049         PREV_DEPTHFIRST,
00050         NEXT_DEPTHFIRST,
00051         PREV_TERMINAL,
00052         NEXT_TERMINAL,
00053         PREV_BRANCH,
00054         NEXT_BRANCH,
00055         LEFT_BROTHER,
00056         RIGHT_BROTHER,
00057         MAIN_BRANCH,
00058         START_OF_GAME,
00059         END_OF_GAME
00060     };
00061 
00062     SgNode();
00063 
00064     ~SgNode();
00065 
00066     /** Return a newly allocated copy of this node and its subtree. */
00067     SgNode* CopyTree() const;
00068 
00069     /**  @todo: distinguish SgVector<SgPoint>, SgVector<int> etc. */
00070     // @todo add const& version when conversion is done.
00071     // const SgVector<SgPoint>& VectorProp(SgPropID prop) const;
00072     SgVector<SgPoint> VectorProp(SgPropID prop) const;
00073 
00074     bool HasFather() const
00075     {
00076         return (m_father != 0);
00077     }
00078 
00079     bool IsRoot() const
00080     {
00081         return (m_father == 0);
00082     }
00083 
00084     bool HasLeftBrother() const;
00085 
00086     bool HasRightBrother() const
00087     {
00088         return (m_brother != 0);
00089     }
00090 
00091     bool HasSon() const
00092     {
00093         return (m_son != 0);
00094     }
00095 
00096     /** HasLeftBrother(node) OR HasRightBrother(node) */
00097     bool HasBrother() const
00098     {
00099         return HasLeftBrother() || HasRightBrother();
00100     }
00101 
00102     /** True of the node is on the main branch of the tree, that is
00103         none of its ancestors has a left brother.
00104     */
00105     bool IsOnMain() const;
00106 
00107     /** NOT HasSon(node) */
00108     bool IsTerminal() const
00109     {
00110         return (m_son == 0);
00111     }
00112 
00113     /** NumSons(node) >= 2 */
00114     bool IsBranchPoint() const
00115     {
00116         return (m_son && m_son->m_brother);
00117     }
00118 
00119     int NumSons() const;
00120 
00121     int NumLeftBrothers() const;
00122 
00123     SgNode* Root() const;
00124 
00125     SgNode* Father() const
00126     {
00127         return m_father;
00128     }
00129 
00130     SgNode* LeftBrother() const;
00131 
00132     SgNode* RightBrother() const
00133     {
00134         return m_brother;
00135     }
00136 
00137     SgNode* LeftMostSon() const
00138     {
00139         return m_son;
00140     }
00141 
00142     SgNode* RightMostSon() const;
00143 
00144     /** Depth-first traversal of the tree. */
00145     SgNode* NextDepthFirst() const;
00146 
00147     /** Inverse operation of NextDepthFirst. */
00148     SgNode* PrevDepthFirst() const;
00149 
00150     /** Return the next node in the given direction.
00151         Returns 0 if there is no such node.
00152     */
00153     SgNode* NodeInDirection(Direction dir) const;
00154 
00155     /** Return whether this node contains a property that matches the given
00156         text.
00157         Doesn't handle text representing special properties.
00158     */
00159     bool ContainsText(const std::string& findText);
00160 
00161     /** Returns all nodes on path from this node up to the root. */
00162     void PathToRoot(SgVectorOf<SgNode>* path) const;
00163 
00164     /** Find the closest common ancestor of the two nodes.
00165         Returns the path from this node to 'node': how many times
00166         to go one node back, and a vector of the nodes to execute from
00167         there (excluding the common ancestor).
00168     */
00169     void ShortestPathTo(SgNode* node, int* numBack,
00170                         SgVectorOf<SgNode>* path) const;
00171 
00172     /** Promote this node to first son.
00173         Moves all its left brothers one position to the right.
00174     */
00175     void PromoteNode();
00176 
00177     /** The tree above this node is changed such that this node is on
00178         the main path.
00179         (first in depth-first search).
00180     */
00181     void PromotePath();
00182 
00183     /** Deletes all nodes below this node, but not this node itself. */
00184     void DeleteSubtree();
00185 
00186     /** Deletes everything below the current node except the main branch. */
00187     void DeleteBranches();
00188 
00189     /** Deletes the tree that this node is part of.
00190         Same as:
00191         @verbatim
00192         SgNode* root = Root();
00193         root->DeleteSubtree();
00194         delete root;
00195         @endverbatim
00196     */
00197     void DeleteTree();
00198 
00199     SgNode* NewFather();
00200 
00201     SgNode* NewRightBrother();
00202 
00203     SgNode* NewLeftMostSon();
00204 
00205     /** Insert a node at the appropriate place in the tree. */
00206     SgNode* NewRightMostSon();
00207 
00208     /** Append this tree to '*n'. */
00209     void AppendTo(SgNode* n);
00210 
00211     /** Add a new node and add all trees in 'roots' as subtrees of that
00212         node.
00213     */
00214     static SgNode* LinkTrees(const SgVectorOf<SgNode>& roots);
00215 
00216     SgPropList& Props()
00217     {
00218         return m_props;
00219     }
00220 
00221     const SgPropList& Props() const
00222     {
00223         return m_props;
00224     }
00225 
00226     void Add(const SgProp* prop)
00227     {
00228         // Check for root properties in root or one below root (linked nodes
00229         // in game collection).
00230         SG_ASSERT(! prop->Flag(SG_PROPCLASS_ROOT) || ! HasFather()
00231                   || ! Father()->HasFather());
00232         m_props.Add(prop);
00233     }
00234 
00235     SgProp* Get(SgPropID id) const
00236     {
00237         return m_props.Get(id);
00238     }
00239 
00240     /** HasProp also handles abstract node properties like SG_PROP_TERMINAL
00241         and SG_PROP_BRANCH, while Get only returns real properties.
00242     */
00243     bool HasProp(SgPropID id) const;
00244 
00245     /** has SG_PROP_MOVE_BLACK or SG_PROP_MOVE_WHITE */
00246     bool HasNodeMove() const;
00247 
00248     /** Player of move.
00249         REQUIRES: HasNodeMove()
00250     */
00251     SgBlackWhite NodePlayer() const;
00252 
00253     SgPoint NodeMove() const;
00254 
00255     /** Return the most recent node that has the given property, starting
00256         backwards from this node.
00257         Return this node if it has the wanted property; return the root of the
00258         tree if no node with that property was found.
00259     */
00260     SgNode* TopProp(SgPropID id) const;
00261 
00262     /** Return the value of the given property at this node.
00263         Or 0 if there is no such property. The property must be of class
00264         SgPropInt (or a derived class).
00265     */
00266     int GetIntProp(SgPropID id) const;
00267 
00268     /** return if property exists. If true, return its value in *value */
00269     bool GetIntProp(SgPropID id, int* value) const;
00270 
00271     /** Value of the given property at this node.
00272         Returns 0 if there is no such property.
00273         The property must be of class SgPropReal.
00274     */
00275     double GetRealProp(SgPropID id) const;
00276 
00277     /** Set the value of the given property at this node to 'value'.
00278         Create such a property if it doesn't exist yet. The property must be
00279         of class SgPropInt (or a derived class).
00280     */
00281     void SetIntProp(SgPropID id, int value);
00282 
00283     /** Set the value of the given property at this node.
00284         Create  such a property if it doesn't exist yet.
00285         The property must be of class SgPropReal.
00286         @param  id
00287         @param value
00288         @param precision Precision; 0 means default precision (6)
00289     */
00290     void SetRealProp(SgPropID id, double value, int precision = 0);
00291 
00292     /** Set the value of the given property at this node to 'value'.
00293         Create such a property if it doesn't exist yet. The property must be
00294         of class SgPropText (or a derived class).
00295     */
00296     void SetStringProp(SgPropID id, const std::string& value);
00297 
00298     /** Return the value of the given property at this node.
00299         Or 0 if there is no such property. The property must be of class
00300         SgPropText (or a derived class).
00301     */
00302     bool GetStringProp(SgPropID id, std::string* value) const;
00303 
00304     /** Set the value of the given property at this node to 'value'.
00305         Create such a property if it doesn't exist yet. The property must be
00306         of class SgPropPointList (or a derived class).
00307     */
00308     void SetListProp(SgPropID id, const SgVector<SgPoint>& value);
00309     void SetListProp(SgPropID id, const SgPointSet& value);
00310 
00311     /** Add comment to existing SG_PROP_COMMENT of this node, or create a new
00312         SG_PROP_COMMENT with this text.
00313     */
00314     void AddComment(const std::string& comment);
00315 
00316     /** If it exists, copy the property with the given 'id' from 'sourceNode'
00317         to this node, and return it.
00318         If the property doesn't exist, return 0.
00319     */
00320     SgProp* CopyPropFrom(const SgNode& sourceNode, SgPropID id);
00321 
00322     /** Copy all properties from 'sourceNode' to this node. */
00323     void CopyAllPropsFrom(const SgNode& sourceNode);
00324 
00325     /** Add a move property to this node with 'move' played by 'player'.
00326         @return the property added.
00327         @warning Only for games which use SgMoveProp
00328         @todo Too game dependent for a member of SgNode, move somewhere else
00329     */
00330     SgProp* AddMoveProp(SgMove move, SgBlackWhite player);
00331 
00332     /** Return the player, if explicitely set.
00333         REQUIRES: Get(SG_PROP_PLAYER)
00334     */
00335     SgBlackWhite Player() const;
00336 
00337     /** Count the nodes in this subtree and sets SG_PROP_NUM_NODES for each
00338         interior node in the subtree that has at least two sons, plus for this
00339         node if 'fSetPropOnThisNode' is set.
00340         Return the number of nodes in the subtree, including this node.
00341     */
00342     int CountNodes(bool fSetPropOnThisNode);
00343 
00344     static void CopySubtree(const SgNode* node, SgNode* copy);
00345 
00346 #ifndef NDEBUG
00347     /** Total number of nodes allocated, still in use. */
00348     static void GetStatistics(int* numAlloc, int* numUsed);
00349 #endif
00350 
00351     static void MemCheck();
00352 
00353     /** Location of node in tree.
00354         This function builds a unique string from the location of a node
00355         in the tree. It is a list of integers separated by dots, each integer
00356         represents the child index (counting from 1) for each node in
00357         the path from the root to the given node.
00358         For example
00359         @verbatim
00360         root -- node1 -- node2
00361              |
00362              +- node3
00363 
00364         root  "1"
00365         node1 "1.1"
00366         node2 "1.1.1"
00367         node3 "1.2"
00368         @endverbatim
00369         A null node pointer has the TreeIndex "NIL".
00370     */
00371     static std::string TreeIndex(const SgNode* node);
00372 
00373 private:
00374     //friend class SgNodeIterator;
00375 
00376     SgNode* m_son;
00377 
00378     SgNode* m_father;
00379 
00380     SgNode* m_brother;
00381 
00382     SgPropList m_props;
00383 
00384     bool m_marked;
00385 
00386     void LinkWithBrother(SgNode* node);
00387 
00388     void Mark()
00389     {
00390         m_marked = true;
00391     }
00392 
00393     void Unmark()
00394     {
00395         m_marked = false;
00396     }
00397 
00398     bool IsMarked() const
00399     {
00400         return m_marked;
00401     }
00402 
00403     /** Not implemented. */
00404     SgNode(const SgNode&);
00405 
00406     /** Not implemented. */
00407     SgNode& operator=(const SgNode&);
00408 
00409 #ifndef NDEBUG
00410     static int s_alloc;
00411 
00412     static int s_free;
00413 #endif
00414 };
00415 
00416 //----------------------------------------------------------------------------
00417 
00418 /** Iterator for iterating through all the sons of a SgNode */
00419 class SgSonNodeIterator
00420 {
00421 public:
00422     SgSonNodeIterator(SgNode* node)
00423         : m_nextNode(node->LeftMostSon())
00424     { }
00425 
00426     void operator++()
00427     {
00428         m_nextNode = m_nextNode->RightBrother();
00429     }
00430 
00431     SgNode* operator*() const
00432     {
00433         SG_ASSERT(m_nextNode);
00434         return m_nextNode;
00435     }
00436 
00437     operator bool() const
00438     {
00439         return m_nextNode != 0;
00440     }
00441 
00442 private:
00443     SgNode* m_nextNode;
00444 
00445     /** Not implemented. */
00446     SgSonNodeIterator(const SgSonNodeIterator&);
00447 
00448     /** Not implemented. */
00449     SgSonNodeIterator& operator=(const SgSonNodeIterator&);
00450 };
00451 
00452 //----------------------------------------------------------------------------
00453 
00454 /** Iterator for iterating through all the sons of a Node */
00455 class SgSonNodeConstIterator
00456 {
00457 public:
00458     SgSonNodeConstIterator(const SgNode* node)
00459         : m_nextNode(node->LeftMostSon())
00460     { }
00461 
00462     void operator++()
00463     {
00464         m_nextNode = m_nextNode->RightBrother();
00465     }
00466 
00467     const SgNode* operator*() const
00468     {
00469         SG_ASSERT(m_nextNode);
00470         return m_nextNode;
00471     }
00472 
00473     operator bool() const
00474     {
00475         return m_nextNode != 0;
00476     }
00477 
00478 private:
00479     SgNode* m_nextNode;
00480 
00481     /** Not implemented. */
00482     SgSonNodeConstIterator(const SgSonNodeConstIterator&);
00483 
00484     /** Not implemented. */
00485     SgSonNodeConstIterator& operator=(const SgSonNodeConstIterator&);
00486 };
00487 
00488 //----------------------------------------------------------------------------
00489 
00490 /** Iterator for iterating through all nodes in subtree. */
00491 class SgNodeIterator
00492 {
00493 public:
00494     /** Create an iterator for iterating through all nodes in the subtree
00495         of 'rootOfSubtree', including the node itself.
00496         If 'preOrder' (default), return internal nodes before their sons; if
00497         'postOrder', then return the leaves before the internal nodes.
00498     */
00499     SgNodeIterator(SgNode* rootOfSubtree, bool postOrder = false);
00500 
00501     /** Abort the iteration.
00502         The next call to operator bool will return false.
00503     */
00504     void Abort()
00505     {
00506         m_nextNode = 0;
00507     }
00508 
00509     void operator++()
00510     {
00511         SG_ASSERT(m_nextNode);
00512         Next();
00513     }
00514 
00515     SgNode* operator*() const
00516     {
00517         SG_ASSERT(m_nextNode);
00518         return m_nextNode;
00519     };
00520 
00521     operator bool() const
00522     {
00523         return m_nextNode != 0;
00524     }
00525 
00526 private:
00527     /** Find next node in the tree. Return false when done with all nodes. */
00528     bool Next();
00529 
00530     bool m_postOrder;
00531 
00532     SgNode* const m_rootOfSubtree;
00533 
00534     SgNode* m_nextNode;
00535 
00536     /** Not implemented. */
00537     SgNodeIterator(const SgNodeIterator&);
00538 
00539     /** Not implemented. */
00540     SgNodeIterator& operator=(const SgNodeIterator&);
00541 };
00542 
00543 //----------------------------------------------------------------------------
00544 
00545 /** Iterator for iterating through all nodes in subtree. */
00546 class SgNodeConstIterator
00547 {
00548 public:
00549     /** Create an iterator for iterating through all nodes in the subtree
00550         of 'rootOfSubtree', including the node itself.
00551         If 'preOrder' (default), return internal nodes before their sons; if
00552         'postOrder', then return the leaves before the internal nodes.
00553     */
00554     SgNodeConstIterator(const SgNode* rootOfSubtree, bool postOrder = false);
00555 
00556     /** Find next node in the tree. Return false when done with all nodes. */
00557     bool Next();
00558 
00559     /** Abort the iteration.
00560         The next call to operator bool will return false.
00561     */
00562     void Abort()
00563     {
00564         m_nextNode = 0;
00565     }
00566 
00567     void operator++()
00568     {
00569         SG_ASSERT(m_nextNode);
00570         Next();
00571     }
00572 
00573     const SgNode* operator*() const
00574     {
00575         SG_ASSERT(m_nextNode);
00576         return m_nextNode;
00577     };
00578 
00579     operator bool() const
00580     {
00581         return m_nextNode != 0;
00582     }
00583 
00584 private:
00585     bool m_postOrder;
00586 
00587     const SgNode* const m_rootOfSubtree;
00588 
00589     const SgNode* m_nextNode;
00590 
00591     /** Not implemented. */
00592     SgNodeConstIterator(const SgNodeConstIterator&);
00593 
00594     /** Not implemented. */
00595     SgNodeConstIterator& operator=(const SgNodeConstIterator&);
00596 };
00597 
00598 //----------------------------------------------------------------------------
00599 
00600 #endif // SG_NODE_H


17 Jun 2010 Doxygen 1.4.7