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


Sun Mar 13 2011 Doxygen 1.7.1