00001
00002
00003
00004
00005
00006
00007
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
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
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
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
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
00090
00091
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
00117
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
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
00165
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
00180
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