1、深度寻路算法规则
深度寻路的规则是沿着一个固定的方向进行行走,等到了一个岔路口再继续选择方向,如果碰上了死胡同再退回下一个岔路口重新选择方向。走过的路不会重新走,一次只走一个岔路口。
2、程序实现
类似于深度遍历算法,深度寻路也是利用栈(stack)实现。首先定义起点与终点,接着定义当前位置与将要走的位置。程序中路径设置为:下、左、右、上。当往下走的时候ROW不变,COL++ ;其余方形类似。在程序中设置了可以走的条件为:1、不是墙2、没有走过。满足以上2个条件就可以尽情的行走。
3、具体程序如下:
为了方便,我在程序中尽可能的多注释。
// 深度寻路.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<graphics.h>
#include<stack>
using namespace std;
#pragma comment(lib,"ws2_32")
#define ROW 11 //11行
#define COL 9 //9列
#define CELLSIZE 64 //定义单元格大小
struct MapNode //地图
{
int value;//0 或 1
bool isWalk;//判断是否走过
int preDir;//尝试走的方向
};
struct MapPoint
{
int row, col;//地图的行与列
};
enum WalkDir //走路的方向,遵循 下 左 右 上
{
em_Dowm,//0
em_Up,//1
em_left,//2
em_right,//3
};
int gMap[ROW][COL] = {
//1代表走不通,0代表路径
{
1, 1, 1, 1, 1, 1, 1, 1, 1 },
{
1, 0, 1, 0, 0, 0, 0, 0, 1 },
{
1, 0, 1, 0, 1, 1, 0, 1, 1 },
{
1, 0, 1, 0, 0, 0, 1, 0, 1 },
{
1, 0, 1, 0, 1, 0, 1, 0, 1 },
{
1, 0, 1, 0, 1, 0, 1, 0, 1 },
{
1, 0, 1, 0, 1, 0, 0, 0, 1 },
{
1, 0, 1, 0, 1, 0, 1, 0, 1 },
{
1, 0, 0, 0, 1, 1, 1, 0, 1 },
{
1, 0, 1, 0, 0, 0, 1, 0, 0 },
{
1, 1, 1, 1, 1, 1, 1, 1, 1 }
};
MapNode gMapNode[ROW][COL];//地图
//图片遍历
IMAGE backGroundImage, tankImage, wallImage;//背景 坦克 墙
void InitMapNode();//初始化地图
void LoadMapSource();//加载照片
void ShowBackGround(int pMap[ROW][COL]);//显示背景
void ShowTank(int x, int y);//显示坦克图像
int _tmain(int argc, _TCHAR* argv[])
{
initgraph(CELLSIZE*COL, CELLSIZE*ROW, SHOWCONSOLE);//初始化图形键面库
LoadMapSource();//加载图像
InitMapNode();//初始化地图节点
MapPoint startPos = {
1, 1 }, endPos = {
9, 8 };//定义起点与终点
stack<MapPoint>pathStack;//栈 先进后出
pathStack.push(startPos);
bool isFindEnd = false;//标记是否走过
MapPoint currentPos = startPos, tryPos = startPos;//当前人物所处位置,将要走的位置
while (!isFindEnd)//没有走过
{
tryPos = currentPos;//复位,将尝试点变成当前点
switch (gMapNode[currentPos.row][currentPos.col].preDir)
{
case em_Dowm://向下走
{
tryPos.row++;
gMapNode[currentPos.row][currentPos.col].preDir = em_left;//下如果走不通就走左
//判断是否往下走的2个条件:1、是不是墙(0)2、是否走过了
if (gMapNode[tryPos.row][tryPos.col].value==0 && gMapNode[tryPos.row][tryPos.col].isWalk==false)
{
gMapNode[tryPos.row][tryPos.col].isWalk = true;//走过的话就标记已经走过
currentPos = tryPos;//尝试点变为当前点
pathStack.push(currentPos);//当前点入栈
}
}
break;
case em_Up:
{
tryPos.row--;
//gMapNode[currentPos.row][currentPos.col].preDir = em_left;
if (gMapNode[tryPos.row][tryPos.col].value == 0 && gMapNode[tryPos.row][tryPos.col].isWalk == false)
{
gMapNode[tryPos.row][tryPos.col].isWalk = true;
currentPos = tryPos;
pathStack.push(currentPos);
}
else
{
pathStack.pop();//出栈
if (pathStack.size()>0)
{
currentPos = pathStack.top();//取出上一个点作为当前点,这里主要是走到死胡同的时候就退后一步
}
}
}
break;
case em_left:
{
tryPos.col--;
gMapNode[currentPos.row][currentPos.col].preDir = em_right;
if (gMapNode[tryPos.row][tryPos.col].value == 0 && gMapNode[tryPos.row][tryPos.col].isWalk == false)
{
gMapNode[tryPos.row][tryPos.col].isWalk = true;
currentPos = tryPos;
pathStack.push(currentPos);
}
}
break;
case em_right:
{
tryPos.col++;
gMapNode[currentPos.row][currentPos.col].preDir = em_Up;
if (gMapNode[tryPos.row][tryPos.col].value == 0 && gMapNode[tryPos.row][tryPos.col].isWalk == false)
{
gMapNode[tryPos.row][tryPos.col].isWalk = true;
currentPos = tryPos;
pathStack.push(currentPos);
}
}
break;
}
ShowTank(currentPos.col*CELLSIZE, currentPos.row*CELLSIZE);//显示坦克路径
//判断是否走到了终点
if (currentPos.row==endPos.row && currentPos.col==endPos.col)
{
isFindEnd = true;
}
if (pathStack.empty())
{
break;
}
Sleep(300);//程序运行太快,给它延迟300ms
}
//整个循环结束了
if (isFindEnd=true)
{
printf("到达终点了!!!");
int size = pathStack.size();
for (int i = 0; i < size; i++)
{
MapPoint tp = pathStack.top();
printf("(%d,%d)", tp.row, tp.col);
pathStack.pop();
}
printf("\n");
}
else
{
printf("找不到路径");
}
while (1);
return 0;
}
void InitMapNode()//初始化地图
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
gMapNode[i][j].value = gMap[i][j];//给地图赋值
}
}
}
void LoadMapSource()
{
loadimage(&backGroundImage, "image/bk.bmp", CELLSIZE*COL, CELLSIZE*ROW, true);
loadimage(&tankImage, "image/tank.bmp", CELLSIZE * 4, CELLSIZE * 160, true);
loadimage(&wallImage, "image/wall.bmp", CELLSIZE, CELLSIZE, true);
}
void ShowBackGround(int pMap[ROW][COL])
{
putimage(0,0,&backGroundImage);//背景图像
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
if (pMap[i][j]==1)
{
putimage(j*CELLSIZE, i*CELLSIZE, &wallImage);
}
}
}
}
void ShowTank(int x, int y)
{
ShowBackGround(gMap);//在背景图上显示坦克
putimage(x, y, CELLSIZE, CELLSIZE, &tankImage, 0, CELLSIZE, SRCPAINT);
putimage(x, y, CELLSIZE, CELLSIZE, &tankImage, 0, 0, SRCAND);
}
4、最终结果