/****************************************************
* Functions to solve mazes. *
* *
* Datafile must still contain size as first data. *
* *
* Four functions are only stubs. *
****************************************************/ #include <iostream>
#include <fstream>
#include “Maze.h”
using namespace std;
struct Node
{
int npi;
int npos;
enum Direction nhead;
};
Node nNode[400];
int ni = 0;
// The following enumerated type indicates directions within the maze enum Direction {DOWN, LEFT, UP, RIGHT}; // This struct is used for locations within the maze struct Position
{
int H, V;
}; // The maze itself is indicated by # for the walls
// All other locations in the maze can be any other character
// Global variables defining the maze to be solved
int mazeWidth, mazeHeight;
char* maze; int* posi;
int i=0;
//int sameposi[17 * 17] = { 0 };
// These functions provide access to the maze
// as well as provide manipulation of direction
// of motion and maze location
// See implementation for details void FindEntrance(int&);
bool AtExit(int);
void ReportPosition(int);
void WheresRight(int,Direction,int&);
bool Wall(int);
void TurnRight(Direction&);
void TurnBack(Direction&);
void MoveForward(int&,Direction);
void WheresAhead(int,Direction,int&);
void TurnLeft(Direction&);
bool is_DeadEnd(int);
//void BackToNode(int&,Direction&);
bool is_node(int);
void RememberNode(int, Direction);
//bool is_nsame(int);
//void issame(int);
void DeleteNode(void);
// This function loads the maze from the specified file
// returning the maze and its dimensions
// The height of the maze is not actually used anywhere but here bool LoadMaze(const char fname[])
{
ifstream ifs(fname);//这里是先输入文件的属性中的地址加上文件名字和类型 如C:\maze1.txt
if (ifs.good())//ifs.good是判断文件是否为无错误的文件
{
ifs >> mazeWidth >> mazeHeight;
maze = new char[mazeHeight*mazeWidth + 1];
for (int i=0;i<mazeHeight;i++)
for (int j=0;j<mazeWidth;j++)
ifs >> maze[i*mazeWidth+j];
ifs.close();
return true;
}
else
{
cerr << “File not found.” << endl;
return false;
}
} // This function solves the maze using the ‘hand on left wall’
// rule, printing the maze position as it proceeds void SolveMaze()
{
int pos, other;
Direction heading;
posi = new int[mazeHeight*mazeWidth + 1];
FindEntrance(pos);
heading = DOWN;
while (!AtExit(pos))
{
//ReportPosition(pos);
posi[i] = pos;
i++;
//issame(pos);
if (is_node(pos))
{
RememberNode(pos, heading);//后进先出
}
if(i>=mazeWidth*mazeHeight)
{
cout<<“array too small\n”;
system(“pause”);
abort();
}
WheresRight(pos,heading,other);
if (!Wall(other))
{
TurnRight(heading);
MoveForward(pos,heading);
}
else
{
WheresAhead(pos,heading,other);
if (!Wall(other))
MoveForward(pos,heading);
else
{
if (is_DeadEnd(pos))
{
TurnBack(heading);
}
else
{
TurnLeft(heading);
MoveForward(pos, heading);
}
}
}
}
posi[i]=pos;
i++;
DeleteNode();
if(i>=mazeHeight*mazeWidth)
{
cout<<“array too small\n”;
abort();
}
int counter=0;
for(int j=0;j<i;j++)
{
if(posi[j]<0)
continue;
cout << “Current position: (” << posi[j]/mazeWidth << ‘,’ << posi[j]%mazeWidth << ‘)’ <<posi[j]<< endl;
counter++;
}
cout<<“total steps:”<<counter<<endl;
cout << “Maze solved” << endl;
delete[] posi;
delete[] maze;
//system(“pause”);//调试的时候自己去掉吧
} // This function scans the maze array for the first non-wall item
// It assumes that the entrance is in the top row of the maze array
void FindEntrance(int& pos)
{
pos= 0;
while (Wall(pos)) pos++;
} // This function returns true if the maze position is the exit
// identified by being in the last row of the array bool AtExit(int pos)
{
return (pos >= (mazeHeight-1)*mazeWidth);
} // This function displays the position in the maze
// At this time it specifies row and column of the array void ReportPosition(int pos)
{
cout << “Current position: (” << pos/mazeWidth << ‘,’ << pos%mazeWidth << ‘)’ << endl;
} // This function takes a maze position and a heading and determines
// the position to the right of this position void WheresRight(int pos, Direction heading, int& right)
{
right=pos;
switch (heading)
{
case DOWN:
{
right–;
break;
}
case LEFT:
{
right-=mazeWidth;
break;
}
case UP:
{
right++;
break;
}
case RIGHT:
{
right+=mazeWidth;
}
} } // This function returns true if maze position is wall bool Wall(int pos)
{
return (maze[pos] == ‘#’);
} // This function changes heading by turning right
// Take current heading and adjust so that direction is to the right void TurnRight(Direction& heading)
{
//to be finished.
switch (heading)
{
case DOWN:
heading = LEFT;
break;
case LEFT:
heading = UP;
break;
case UP:
heading = RIGHT;
break;
case RIGHT:
heading = DOWN;
break;
}
} void TurnBack(Direction& heading)
{
//to be finished.
switch (heading)
{
case DOWN:
heading = UP;
break;
case LEFT:
heading = RIGHT;
break;
case UP:
heading =DOWN;
break;
case RIGHT:
heading = LEFT;
break;
}
} // This function changes position in the maze by determining
// the next position in the current direction void MoveForward(int& pos, Direction heading)
{
//to be finished.
switch (heading)
{
case DOWN:
pos+=mazeWidth;
break;
case LEFT:
pos–;
break;
case UP:
pos-=mazeWidth;
break;
case RIGHT:
pos++;
break;
}
} // This function determines the position in the direction
// currently heading void WheresAhead(int pos, Direction heading, int& ahead)
{
//to be finished.
ahead = pos;
switch (heading)
{
case DOWN:
ahead += mazeWidth;
break;
case LEFT:
ahead–;
break;
case UP:
ahead -=mazeWidth;
break;
case RIGHT:
ahead++;
break;
}
} // This function changes heading by turning left void TurnLeft(Direction& heading)
{
//to be finished.
switch (heading)
{
case DOWN:
heading = RIGHT;
break;
case LEFT:
heading = DOWN;
break;
case UP:
heading = LEFT;
break;
case RIGHT:
heading = UP;
break;
}
} bool is_node(int pos)
{
int r_num = 0;
if (!Wall(pos + 1)) r_num++;
if (!Wall(pos – 1)) r_num++;
if (!Wall(pos + mazeWidth)) r_num++;
if (!Wall(pos – mazeWidth)) r_num++;
if (r_num > 2) return 1;
return 0;
}
/*
void BackToNode(int& pos,Direction& heading)
{
i = nNode[ni].npi;
switch (nNode[ni].nhead)//模拟从死胡同走出来的情况
{
case DOWN:
heading = UP;
break;
case LEFT:
heading=RIGHT;
break;
case UP:
heading=DOWN;
break;
case RIGHT:
heading=LEFT;
break;
}
posi[i-1] = nNode[ni].npos;
pos = nNode[ni].npos;
ni–;
} bool is_nsame(int pos)
{
for (int j = 1; j <= ni; j++)
{
if (nNode[j].npos == pos&&(ni!=j))
{
return 1;
}
}
return 0;
}*/ /*void issame(int pos)
{
for (int j = 0; j < i-1; j++)
{
if (j!=i&&posi[j] == pos)
{
posi[j] = -1;
posi[i – 1] = -1;
sameposi[pos] = 1;
break;
}
}
}*/
bool is_DeadEnd(int pos)
{
int pwall = 0;
if (Wall(pos + 1)) pwall++;
if (Wall(pos – 1)) pwall++;
if (Wall(pos + mazeWidth)) pwall++;
if (Wall(pos – mazeWidth)) pwall++;
if (pwall == 3) return 1;
return 0;
} void RememberNode(int pos, Direction heading)
{
nNode[ni].npos = pos;
nNode[ni].nhead = heading;
nNode[ni].npi = i-1;
ni++;
} void DeleteNode()
{
for (int j = 0; j < ni; j++)
{
for (int z = 0; z < j; z++)
{
if (nNode[j].npos == nNode[z].npos&&j != z)
{
for (int k = nNode[z].npi; k < nNode[j].npi; k++)
{
posi[k] = -1;
}
}
}
}
}