<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>src/path.cpp</filename>
    </added>
    <added>
      <filename>src/path.h</filename>
    </added>
    <added>
      <filename>src/solver.cpp</filename>
    </added>
    <added>
      <filename>src/solver.h</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,10 @@
+2009-03-14 Graeme Gott &lt;graeme@gottcode.org&gt;
+	* Add hint support to board class.
+	* Add solver class.
+
+2009-03-07 Graeme Gott &lt;graeme@gottcode.org&gt;
+	* Add path class.
+
 2009-03-03 Graeme Gott &lt;graeme@gottcode.org&gt;
 	* Improve dialog text.
 	* Use one SVG file per theme.</diff>
      <filename>ChangeLog</filename>
    </modified>
    <modified>
      <diff>@@ -24,8 +24,10 @@ unix: !macx {
 HEADERS = src/board.h \
 	src/cell.h \
 	src/maze.h \
+	src/path.h \
 	src/scores.h \
 	src/settings.h \
+	src/solver.h \
 	src/theme.h \
 	src/window.h
 
@@ -33,8 +35,10 @@ SOURCES = src/board.cpp \
 	src/cell.cpp \
 	src/main.cpp \
 	src/maze.cpp \
+	src/path.cpp \
 	src/scores.cpp \
 	src/settings.cpp \
+	src/solver.cpp \
 	src/theme.cpp \
 	src/window.cpp
 </diff>
      <filename>cutemaze.pro</filename>
    </modified>
    <modified>
      <diff>@@ -20,6 +20,7 @@
 #include &quot;board.h&quot;
 
 #include &quot;maze.h&quot;
+#include &quot;solver.h&quot;
 #include &quot;theme.h&quot;
 
 #include &lt;QKeyEvent&gt;
@@ -43,13 +44,16 @@ Board::Board(QMainWindow* parent)
 	m_paused(false),
 	m_total_targets(3),
 	m_maze(0),
+	m_solver(0),
 	m_show_path(true),
 	m_smooth_movement(true),
 	m_col_delta(0),
 	m_row_delta(0),
 	m_player_angle(360),
 	m_player_steps(0),
-	m_player_total_time(0)
+	m_player_total_time(0),
+	m_hint(-1, -1),
+	m_hint_angle(0)
 {
 #if !defined(QTOPIA_PHONE)
 	setMinimumSize(448, 448);
@@ -100,6 +104,7 @@ Board::Board(QMainWindow* parent)
 Board::~Board()
 {
 	delete m_maze;
+	delete m_solver;
 	delete m_theme;
 }
 
@@ -188,7 +193,8 @@ void Board::loadGame()
 	// Remove any targets with matching movement
 	for (int i = 0; i &lt; m_targets.size(); ++i) {
 		if (m_maze-&gt;cell(m_targets[i].x(), m_targets[i].y()).pathMarker() || m_player == m_targets[i]) {
-			m_targets.takeAt(i);
+			QPoint target = m_targets.takeAt(i);
+			m_solver-&gt;removeTarget(target);
 			--i;
 		}
 	}
@@ -242,6 +248,26 @@ void Board::pauseGame(bool paused)
 
 // ============================================================================
 
+void Board::hint()
+{
+	if (!m_done) {
+		m_hint = m_solver-&gt;hint(m_player);
+		if (m_hint.x() &lt; m_player.x()) {
+			m_hint_angle = 270;
+		} else if (m_hint.x() &gt; m_player.x()) {
+			m_hint_angle = 90;
+		} else if (m_hint.y() &lt; m_player.y()) {
+			m_hint_angle = 360;
+		} else {
+			m_hint_angle = 180;
+		}
+		m_hint = m_hint - m_player + QPoint(3,3);
+		update();
+	}
+}
+
+// ============================================================================
+
 void Board::loadSettings()
 {
 	QSettings settings;
@@ -326,6 +352,7 @@ void Board::keyPressEvent(QKeyEvent* event)
 		if (m_smooth_movement) {
 			m_move_animation-&gt;start();
 		}
+		m_hint = QPoint(-1, -1);
 
 		// Add path marker
 		if (m_maze-&gt;cell(position.x(), position.y()).pathMarker() == 0) {
@@ -342,7 +369,8 @@ void Board::keyPressEvent(QKeyEvent* event)
 	// Check for collisions with targets
 	for (int i = 0; i &lt; m_targets.size(); ++i) {
 		if (m_player == m_targets.at(i)) {
-			m_targets.takeAt(i);
+			QPoint target = m_targets.takeAt(i);
+			m_solver-&gt;removeTarget(target);
 			--i;
 		}
 	}
@@ -463,6 +491,11 @@ void Board::generate(unsigned int seed)
 	std::random_shuffle(locations.begin(), locations.end());
 	m_player = m_start = locations.first();
 	m_targets = locations.mid(1, m_total_targets);
+
+	// Find solutions
+	delete m_solver;
+	m_solver = new Solver(m_maze, m_start, m_targets);
+	m_hint = QPoint(-1, -1);
 }
 
 // ============================================================================
@@ -632,6 +665,29 @@ void Board::renderMaze(int frame)
 
 	painter.restore();
 
+	// Draw hint
+	if (m_hint.x() != -1) {
+		painter.save();
+		switch (m_hint_angle) {
+		case 90:
+			painter.translate(-m_unit, 0);
+			break;
+		case 180:
+			painter.translate(0, -m_unit);
+			break;
+		case 270:
+			painter.translate(m_unit, 0);
+			break;
+		case 360:
+			painter.translate(0, m_unit);
+			break;
+		default:
+			break;
+		};
+		m_theme-&gt;draw(painter, m_hint.x(), m_hint.y(), Theme::Hint, m_hint_angle);
+		painter.restore();
+	}
+
 	// Draw player
 	m_theme-&gt;draw(painter, 3, 3, Theme::Player, m_player_angle);
 }</diff>
      <filename>src/board.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -27,6 +27,7 @@ class QMainWindow;
 class QTimeLine;
 class QTimer;
 class Maze;
+class Solver;
 class Theme;
 
 class Board : public QWidget
@@ -46,6 +47,7 @@ public slots:
 	void loadGame();
 	void saveGame();
 	void pauseGame(bool paused);
+	void hint();
 	void loadSettings();
 
 protected:
@@ -72,6 +74,7 @@ private:
 	Maze* m_maze;
 	QPoint m_start;
 	QList&lt;QPoint&gt; m_targets;
+	Solver* m_solver;
 	QLabel* m_status_time_message;
 	QLabel* m_status_steps_message;
 	QLabel* m_status_remain_message;
@@ -97,6 +100,8 @@ private:
 	unsigned int m_controls_left;
 	unsigned int m_controls_right;
 	unsigned int m_controls_flag;
+	QPoint m_hint;
+	int m_hint_angle;
 };
 
 #endif // BOARD_H</diff>
      <filename>src/board.h</filename>
    </modified>
    <modified>
      <diff>@@ -153,6 +153,7 @@ void Theme::scale(int unit)
 	cache(&quot;start&quot;, m_pixmap[Start], bounds);
 	cache(&quot;target&quot;, m_pixmap[Target], bounds);
 	for (int i = 0; i &lt; 4; ++i) {
+		cache(&quot;hint&quot;, m_pixmap_rotated[Hint][i], bounds, i * 90);
 		cache(&quot;marker&quot;, m_pixmap_rotated[Marker][i], bounds, i * 90);
 		cache(&quot;player&quot;, m_pixmap_rotated[Player][i], bounds, i * 90);
 	}</diff>
      <filename>src/theme.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -43,6 +43,7 @@ public:
 		TotalElements
 	};
 	enum RotatedElement {
+		Hint,
 		Marker,
 		Player,
 		TotalRotatedElements</diff>
      <filename>src/theme.h</filename>
    </modified>
    <modified>
      <diff>@@ -336,6 +336,7 @@ void Window::initActions()
 
 	game_menu-&gt;addAction(tr(&quot;Quit Game&quot;), qApp, SLOT(quit()));
 	game_menu-&gt;addAction(tr(&quot;Settings&quot;), m_settings, SLOT(exec()));
+	game_menu-&gt;addAction(tr(&quot;Hint&quot;), m_board, SLOT(hint()));
 	game_menu-&gt;addAction(tr(&quot;High Scores&quot;), m_scores, SLOT(exec()));
 	m_pause_action = game_menu-&gt;addAction(tr(&quot;Pause Game&quot;));
 	game_menu-&gt;addAction(tr(&quot;New Game&quot;), m_board, SLOT(newGame()));
@@ -354,6 +355,8 @@ void Window::initActions()
 	action = toolbar-&gt;addAction(icons.at(0), tr(&quot;New&quot;), m_board, SLOT(newGame()));
 	action-&gt;setShortcut(tr(&quot;Ctrl+N&quot;));
 	m_pause_action = toolbar-&gt;addAction(icons.at(1), tr(&quot;Pause&quot;));
+	action = toolbar-&gt;addAction(tr(&quot;Hint&quot;), m_board, SLOT(hint()));
+	action-&gt;setShortcut(tr(&quot;H&quot;));
 	toolbar-&gt;addAction(icons.at(2), tr(&quot;Scores&quot;), m_scores, SLOT(exec()));
 	toolbar-&gt;addAction(icons.at(3), tr(&quot;Settings&quot;), m_settings, SLOT(exec()));
 	action = toolbar-&gt;addAction(icons.at(4), tr(&quot;Quit&quot;), this, SLOT(close()));
@@ -365,6 +368,7 @@ void Window::initActions()
 
 	game_menu-&gt;addAction(tr(&quot;New&quot;), m_board, SLOT(newGame()), tr(&quot;Ctrl+N&quot;));
 	m_pause_action = game_menu-&gt;addAction(tr(&quot;Pause&quot;));
+	game_menu-&gt;addAction(tr(&quot;Hint&quot;), m_board, SLOT(hint()), tr(&quot;H&quot;));
 	game_menu-&gt;addAction(tr(&quot;Scores&quot;), m_scores, SLOT(exec()));
 	game_menu-&gt;addAction(tr(&quot;Settings&quot;), m_settings, SLOT(exec()));
 	game_menu-&gt;addAction(tr(&quot;Quit&quot;), this, SLOT(close()), tr(&quot;Ctrl+Q&quot;));</diff>
      <filename>src/window.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@
    xmlns:svg=&quot;http://www.w3.org/2000/svg&quot;
    xmlns=&quot;http://www.w3.org/2000/svg&quot;
    version=&quot;1.0&quot;
-   width=&quot;750&quot;
+   width=&quot;826&quot;
    height=&quot;96&quot;
    id=&quot;svg2&quot;&gt;
   &lt;defs
@@ -290,5 +290,20 @@
          id=&quot;rect2944&quot;
          style=&quot;opacity:1;fill:#008000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0&quot; /&gt;
     &lt;/g&gt;
+    &lt;g
+       transform=&quot;translate(762,32)&quot;
+       id=&quot;hint&quot;&gt;
+      &lt;rect
+         width=&quot;64&quot;
+         height=&quot;64&quot;
+         x=&quot;0&quot;
+         y=&quot;0&quot;
+         id=&quot;rect2446&quot;
+         style=&quot;fill:#000000;fill-opacity:0;stroke:none;stroke-opacity:1&quot; /&gt;
+      &lt;path
+         d=&quot;M 32,40 L 40,56 L 24,56 L 32,40 z&quot;
+         id=&quot;path2448&quot;
+         style=&quot;fill:#ff0000;fill-opacity:1;stroke:#800000;stroke-width:2;stroke-linecap:square;stroke-linejoin:bevel;marker-start:none;marker-mid:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1&quot; /&gt;
+    &lt;/g&gt;
   &lt;/g&gt;
 &lt;/svg&gt;</diff>
      <filename>themes/Mouse.svg</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@
    xmlns:svg=&quot;http://www.w3.org/2000/svg&quot;
    xmlns=&quot;http://www.w3.org/2000/svg&quot;
    version=&quot;1.0&quot;
-   width=&quot;750&quot;
+   width=&quot;826&quot;
    height=&quot;96&quot;
    id=&quot;svg2&quot;&gt;
   &lt;defs
@@ -255,4 +255,19 @@
          style=&quot;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0&quot; /&gt;
     &lt;/g&gt;
   &lt;/g&gt;
+  &lt;g
+     transform=&quot;translate(762,32)&quot;
+     id=&quot;hint&quot;&gt;
+    &lt;rect
+       width=&quot;64&quot;
+       height=&quot;64&quot;
+       x=&quot;0&quot;
+       y=&quot;0&quot;
+       id=&quot;rect2446&quot;
+       style=&quot;fill:#000000;fill-opacity:0;stroke:none;stroke-opacity:1&quot; /&gt;
+    &lt;path
+       d=&quot;M 32,40 L 40,56 L 24,56 L 32,40 z&quot;
+       id=&quot;path2448&quot;
+       style=&quot;fill:#ff0000;fill-opacity:1;stroke:#800000;stroke-width:2;stroke-linecap:square;stroke-linejoin:bevel;marker-start:none;marker-mid:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1&quot; /&gt;
+  &lt;/g&gt;
 &lt;/svg&gt;</diff>
      <filename>themes/Penguin.svg</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>147631c7c28a3bd7b89acf88abf0be9c16cedccf</id>
    </parent>
  </parents>
  <author>
    <name>Graeme Gott</name>
    <email>graeme@gottcode.org</email>
  </author>
  <url>http://github.com/gottcode/cutemaze/commit/030706cdfee9411fa1e4b10143b58bd748c2df37</url>
  <id>030706cdfee9411fa1e4b10143b58bd748c2df37</id>
  <committed-date>2009-03-15T09:21:25-07:00</committed-date>
  <authored-date>2009-03-14T15:13:56-07:00</authored-date>
  <message>Add hint support.</message>
  <tree>d20ccdf6f7ad2f7ae31e25d32105f3f9a6a3734a</tree>
  <committer>
    <name>Graeme Gott</name>
    <email>graeme@gottcode.org</email>
  </committer>
</commit>
