Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

LevelNode.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  */
00009 #include "LevelNode.h"
00010 
00011 #include "Level.h"
00012 #include "NodeDrawer.h"
00013 
00014 #include <math.h>
00015 #include <assert.h>
00016 
00017 //-----------------------------------------------------------------
00018 /**
00019  * Default state is STATE_FAR.
00020  */
00021 LevelNode::LevelNode(const std::string &codename, const Path &datafile,
00022                 const V2 &loc, const std::string &poster)
00023 : m_codename(codename), m_poster(poster), m_datafile(datafile), m_loc(loc)
00024 {
00025     m_state = STATE_FAR;
00026     m_depth = 1;
00027     m_bestMoves = -1;
00028 }
00029 //-----------------------------------------------------------------
00030 /**
00031  * Free self and all children.
00032  */
00033 LevelNode::~LevelNode()
00034 {
00035     t_children::iterator end = m_children.end();
00036     for (t_children::iterator i = m_children.begin(); i != end; ++i) {
00037         delete *i;
00038     }
00039 }
00040 //-----------------------------------------------------------------
00041 /**
00042  * Set state for this node and open his followers.
00043  */
00044 void
00045 LevelNode::setState(eState state)
00046 {
00047     t_children::iterator end = m_children.end();
00048     switch (state) {
00049         case STATE_HIDDEN:
00050         case STATE_FAR:
00051         case STATE_OPEN:
00052             break;
00053         case STATE_SOLVED:
00054             for (t_children::iterator i = m_children.begin();
00055                     i != end; ++i)
00056             {
00057                 if ((*i)->getState() < STATE_OPEN) {
00058                     (*i)->setState(STATE_OPEN);
00059                 }
00060             }
00061             break;
00062         default:
00063             assert(!"unknown level node state");
00064             break;
00065     }
00066     m_state = state;
00067 }
00068 //-----------------------------------------------------------------
00069 void
00070 LevelNode::bestSolution(int moves, const std::string &author)
00071 {
00072     m_bestMoves = moves;
00073     m_bestAuthor = author;
00074 }
00075 //-----------------------------------------------------------------
00076 /**
00077  * Returns true when cursor is in radius around node.
00078  */
00079 bool
00080 LevelNode::isUnder(const V2 &cursor) const
00081 {
00082     double dx = m_loc.getX() - cursor.getX();
00083     double dy = m_loc.getY() - cursor.getY();
00084 
00085     return (sqrt(dx * dx + dy * dy) < DOT_RADIUS);
00086 }
00087 //-----------------------------------------------------------------
00088 /**
00089  * Find selected node under cursor.
00090  * Only solved and open nodes are traversed.
00091  * @return selected node or NULL
00092  */
00093 LevelNode *
00094 LevelNode::findSelected(const V2 &cursor)
00095 {
00096     if (m_state >= STATE_OPEN) {
00097         if (isUnder(cursor)) {
00098             return this;
00099         }
00100         else {
00101             t_children::const_iterator end = m_children.end();
00102             for (t_children::const_iterator i = m_children.begin();
00103                     i != end; ++i)
00104             {
00105                 LevelNode *selected = (*i)->findSelected(cursor);
00106                 if (selected) {
00107                     return selected;
00108                 }
00109             }
00110         }
00111     }
00112     return NULL;
00113 }
00114 //-----------------------------------------------------------------
00115 /**
00116  * Find named node in whole tree.
00117  * @return named node or NULL
00118  */
00119 LevelNode *
00120 LevelNode::findNamed(const std::string &codename)
00121 {
00122     if (m_codename == codename) {
00123         return this;
00124     }
00125     else {
00126         t_children::const_iterator end = m_children.end();
00127         for (t_children::const_iterator i = m_children.begin();
00128                 i != end; ++i)
00129         {
00130             LevelNode *named = (*i)->findNamed(codename);
00131             if (named) {
00132                 return named;
00133             }
00134         }
00135     }
00136     return NULL;
00137 }
00138 //-----------------------------------------------------------------
00139 /**
00140  * Returns true when all nodes are solved.
00141  */
00142 bool
00143 LevelNode::areAllSolved() const
00144 {
00145     if (m_state != STATE_SOLVED) {
00146         return false;
00147     }
00148     t_children::const_iterator end = m_children.end();
00149     for (t_children::const_iterator i = m_children.begin(); i != end; ++i) {
00150         if (!(*i)->areAllSolved()) {
00151             return false;
00152         }
00153     }
00154     return true;
00155 }
00156 //-----------------------------------------------------------------
00157 Level *
00158 LevelNode::createLevel() const
00159 {
00160     return new Level(m_codename, m_datafile, m_depth);
00161 }
00162 //-----------------------------------------------------------------
00163 /**
00164  * Add child node.
00165  * NOTE: cycles in graph are not supported.
00166  */
00167 void
00168 LevelNode::addChild(LevelNode *new_node)
00169 {
00170     m_children.push_back(new_node);
00171 
00172     new_node->setDepth(m_depth + 1);
00173     if (m_state == STATE_SOLVED && new_node->getState() < STATE_OPEN) {
00174         new_node->setState(STATE_OPEN);
00175     }
00176 }
00177 //-----------------------------------------------------------------
00178 /**
00179  * Draws self and path to all children.
00180  * Children are drawed recursive.
00181  */
00182 void
00183 LevelNode::drawPath(const NodeDrawer *drawer) const
00184 {
00185     if (m_state > STATE_HIDDEN) {
00186         t_children::const_iterator end = m_children.end();
00187         for (t_children::const_iterator i = m_children.begin();
00188                 i != end; ++i)
00189         {
00190             if ((*i)->getState() > STATE_HIDDEN) {
00191                 drawer->drawEdge(this, *i);
00192                 (*i)->drawPath(drawer);
00193             }
00194         }
00195         drawer->drawNode(this);
00196     }
00197 }
00198 

Generated on Wed Jun 1 09:54:31 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2