// Mole.h
//
// IEEE Challenge 13 - The Hard Life Of A Mole
//
http://www.ieee.org/portal/cms_docs_iportals/iportals/membership/
//
/students/scholarshipsawardscontests/
//
/IEEEXtreme2008_Competitition_book_2.pdf
//
// by Adrian Dale 15/12/2008 / 26/07/2009
#pragma once
#include "boost/multi_array.hpp"
#include <vector>
#include <stack>
using namespace
std;
// Struct to hold coords of a position on our grid.
struct Move
{
Move():x(0),y(0) {}
Move(int
xi, int yi):x(xi),y(yi) {}
int
x;
int
y;
};
typedef vector<Move>
MoveListType;
typedef char
MapDataCellType;
typedef
boost::multi_array<MapDataCellType, 2> MapDataType;
// A WorkingMapCell holds per cell info that we need
for our
// solving algorithm
class WorkingMapCell
{
public:
WorkingMapCell() :
mCostToStart(0), mVisited(false)
{
mCheapestMove.x = 0; mCheapestMove.y = 0; }
~WorkingMapCell() {}
//
What's at this cell
MapDataCellType mCell;
inline
void SetCell(MapDataCellType squ) {mCell = squ;}
//
Cost to travel from this cell to the start
int
mCostToStart;
//
Cheapest direction to start
Move mCheapestMove;
//
Has our algorithm checked this cell yet?
bool
mVisited;
inline
void SetVisited(bool
visited) {mVisited = visited;}
};
typedef boost::multi_array<WorkingMapCell,
2> WorkMapDataType;
typedef stack<Move>
MoveStackType;
// This class holds our map and provides operations on
it.
class Underground
{
public:
//
Solve() calls separate functions so that we can break the solution
//
down into steps for display on our window in the GUI version
//
It will return -1 if it needs to be called again, otherwise it returns
//
the cost of the cheapest solution.
int
Solve();
//
What does a move to square x,y cost?
//
(Tunnels are 0, soil is 1, etc)
int
MoveCost(int x, int
y) const;
//
What is at square x,y?
inline
MapDataCellType GetSquareType(int x, int y) const
{return mMapData[x][y];}
//
Locate our start/end points
Move FindSquare(
MapDataCellType squType ) const;
//
Standard row/column accessor functions
inline
int GetRowCount() const
{ return mRows; }
inline
int GetColumnCount() const
{ return mCols; }
#ifdef _DEBUG
//
Used for debugging - dumps to stdout, which isn't much
//
use for our windows app
void
DumpMap() const;
#endif
private:
//
ReadInput reads our map data from stdin
void
ReadInput();
//
Set up the map ready to be solved
void
Solve_Init();
//
Perform a first pass of the solution
void
Solve_FirstPass();
//
Code used by Solve_FirstPass that is called for each
//
direction away from the square we need to check
void
ProcessDirection(MoveStackType &moveStack, int
x, int y);
//
Refine our initial cut of the solution
int
RescanCheapest();
//
Code called for each direction from the square
//
currently being scanned.
bool
RescanCheapestCell(WorkingMapCell * workCell,
WorkingMapCell *
neighbourCell, int x, int
y, int xx, int
yy);
//
Calculates the cost of the cheapest route by walking back from B to A,
//
and summing up the costs once that route is known.
int
SolutionCost();
int
mRows;
int
mCols;
//
Cache this info so we don't need to keep asking for it
Move mStartPos;
Move mEndPos;
//
Our map data, as read from the file
MapDataType mMapData;
//
Copy of the map used by our solver to solve the puzzle
WorkMapDataType mWorkMap;
};