《算法七》(深度寻路算法)
深度寻路算法:
二维地图:二维数组
二维数组上标识特定数值作为地图上对象
应用于RGB游戏中比较广泛
缺点:1.二维地图,只可以走直线
2.不一定能找到最佳路径
怎么寻路:
1.一个方向只能试探一次
顺时针: 上 右 下 左
逆时针: 上 左 下 右
2.需要标记已经走过,走过了的不能再走
深度寻路算法逻辑:
1.地图
2 辅助地图
3.起点 终点
4.准备栈
5.标记起点走过
7起点入栈
8 寻路:
8.1 准备变量
8.2 确定试探点
8.3 改变当前点试探方向
8.4 试探试探点能不能走
8.5 走
8.6 标记当前点已经走过
8.7 当前点入栈
深度寻路代码:
int _tmain(int argc, _TCHAR* argv[])
{
//1 地图
int map[ROWS][COLS] = {
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 0, 1, 1 },
{ 1, 0, 1, 0, 1, 0, 1, 1 },
{ 1, 0, 1, 0, 1, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 0, 1, 1 },
{ 1, 0, 0, 0, 1, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 }
};
//2 辅助地图
pathNode pathMap[ROWS][COLS] = { 0 };
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
pathMap[i][j].val = map[i][j];
}
}
//4 起点 终点
MyPoint beginPos;
MyPoint endPos;
printf("请输入起点(x,y)\n");
scanf("%d,%d", &(beginPos.col), &(beginPos.row) );
printf("请输入终点(x,y)\n");
scanf("%d,%d", &(endPos.col), &(endPos.row));
//5 准备栈
MyStack<MyPoint> stack;
//6 标记起点走过
pathMap[beginPos.row][beginPos.col].isFind = true;
//7 起点入栈
stack.push(beginPos);
//8 寻路
//8.1 准备变量
//当前角色位置
MyPoint currentPos = beginPos;
//角色试探点
MyPoint searchPos;
bool isFindEnd = false;
initDraw();//准备图形界面
while (1){
searchPos = currentPos;
switch (pathMap[currentPos.row][currentPos.col].dir)
{
case p_up:
//8.2 确定试探点
searchPos.row--;
//8.3 改变当前点试探方向
pathMap[currentPos.row][currentPos.col].dir = p_right;
//8.4 试探试探点能不能走
if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
{//能走
//8.5 走
currentPos = searchPos;
//8.6 标记当前点已经走过
pathMap[currentPos.row][currentPos.col].isFind = true;
//8.7 当前点入栈
stack.push(currentPos);
}
break;
case p_right:
//8.2 确定试探点
searchPos.col++;
//8.4 改变当前点试探方向
pathMap[currentPos.row][currentPos.col].dir = p_down;
//8.3 试探试探点能不能走
if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
{//能走
//8.5 走
currentPos = searchPos;
//8.6 标记当前点已经走过
pathMap[currentPos.row][currentPos.col].isFind = true;
//8.7 当前点入栈
stack.push(currentPos);
}
break;
case p_down:
//8.2 确定试探点
searchPos.row++;
//8.4 改变当前点试探方向
pathMap[currentPos.row][currentPos.col].dir = p_left;
//8.3 试探试探点能不能走
if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
{//能走
//8.5 走
currentPos = searchPos;
//8.6 标记当前点已经走过
pathMap[currentPos.row][currentPos.col].isFind = true;
//8.7 当前点入栈
stack.push(currentPos);
}
break;
case p_left:
//8.2 确定试探点
searchPos.col--;
//8.3 试探试探点能不能走
if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
{//能走
//8.5 走
currentPos = searchPos;
//8.6 标记当前点已经走过
pathMap[currentPos.row][currentPos.col].isFind = true;
//8.7 当前点入栈
stack.push(currentPos);
}
else{//不能走
//8.8 回退
//8.8.1 退栈
stack.pop();
//8.8.2 当前点变为栈顶元素
currentPos = stack.getTop();
}
break;
}
printMap(map, currentPos);
drawMap(map, currentPos);
//找到终点 循环结束
if (currentPos.row == endPos.row &&
currentPos.col == endPos.col){
isFindEnd = true;
break;
}
//栈为空:回到起点 循环结束
if (stack.isEmpty())
break;
}
//9 打印整个路径
if (isFindEnd){
printf("path:");
while (!stack.isEmpty()){
//9.1 打印栈顶元素
printf("(%d,%d)\n", stack.getTop().row, stack.getTop().col);
//9.2 退栈
stack.pop();
}
}
while (1);
return 0;
}
完整代码:
//定义栈
//定义栈
template<class T>
class MyStack{
T* pBuff;
size_t capacity;
size_t len;
public:
MyStack(){
pBuff = NULL;
capacity = len =0;
}
~MyStack(){
if(pBuff){
delete[] pBuff;
}
pBuff = NULL;
capacity = len =0;
}
void push(const T& data);//入栈
void pop(void);//出栈
T getTop(void);//获取栈顶元素
bool isEmpty(void);//判断是否为空
};
template<class T>
void MyStack<T>::push(const T& data){//入栈
if (len >= capacity){
capacity = capacity + (((capacity >> 1) > 1) ? (capacity >> 1) : 1 );
T* pNew = new T[capacity];
if (pBuff){
memcpy(pNew, pBuff, sizeof(T)*len);
delete[] pBuff;
}
pBuff = pNew;
}
pBuff[len++] = data;
}
template<class T>
//出栈
void MyStack<T>::pop(void){
len--;
}
template<class T>
//获取栈顶元素
T MyStack<T>::getTop(void){
return pBuff[len - 1];
}
template<class T>
//判断是否为空
bool MyStack<T>::isEmpty(void){
return (len==0);
}
// 深度寻路算法.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "MyStack.h"
//#include <windows.h>
#include <graphics.h>
/*
RPG游戏中 地图
深度寻路算法
1.二维地图,只能走直线
2.不一定能找到最佳路径
广度寻路算法
A星寻路算法
寻路:
1.一个方向只能试探一次
顺时针: 上 右 下 左
逆时针: 上 左 下 右
2.需要标记已经走过,走过了的不能再走
*/
//x 横 列数
#define COLS 8
//y 竖 行数
#define ROWS 8
//每个格子大小
#define SPACE 50
//方向枚举
enum direct{p_up,p_right,p_down,p_left};
//辅助地图元素类型
struct pathNode{
int val; //这个点上是什么
direct dir; //试探方向
bool isFind; //有没有走过 0 false 没走过 1 true 走过
};
//点结构
struct MyPoint{
int row; //y
int col; //x
};
//图片全局变量
IMAGE g_wall, g_road, g_people;
void printMap(int map[ROWS][COLS], MyPoint pos);
void initDraw();
void drawMap(int map[ROWS][COLS], MyPoint pos);
int _tmain(int argc, _TCHAR* argv[])
{
//1 地图
int map[ROWS][COLS] = {
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 0, 1, 1 },
{ 1, 0, 1, 0, 1, 0, 1, 1 },
{ 1, 0, 1, 0, 1, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 0, 1, 1 },
{ 1, 0, 0, 0, 1, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 }
};
//2 辅助地图
pathNode pathMap[ROWS][COLS] = { 0 };
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
pathMap[i][j].val = map[i][j];
}
}
//4 起点 终点
MyPoint beginPos;
MyPoint endPos;
printf("请输入起点(x,y)\n");
scanf("%d,%d", &(beginPos.col), &(beginPos.row) );
printf("请输入终点(x,y)\n");
scanf("%d,%d", &(endPos.col), &(endPos.row));
//5 准备栈
MyStack<MyPoint> stack;
//6 标记起点走过
pathMap[beginPos.row][beginPos.col].isFind = true;
//7 起点入栈
stack.push(beginPos);
//8 寻路
//8.1 准备变量
//当前角色位置
MyPoint currentPos = beginPos;
//角色试探点
MyPoint searchPos;
bool isFindEnd = false;
initDraw();//准备图形界面
while (1){
searchPos = currentPos;
switch (pathMap[currentPos.row][currentPos.col].dir)
{
case p_up:
//8.2 确定试探点
searchPos.row--;
//8.3 改变当前点试探方向
pathMap[currentPos.row][currentPos.col].dir = p_right;
//8.4 试探试探点能不能走
if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
{//能走
//8.5 走
currentPos = searchPos;
//8.6 标记当前点已经走过
pathMap[currentPos.row][currentPos.col].isFind = true;
//8.7 当前点入栈
stack.push(currentPos);
}
break;
case p_right:
//8.2 确定试探点
searchPos.col++;
//8.4 改变当前点试探方向
pathMap[currentPos.row][currentPos.col].dir = p_down;
//8.3 试探试探点能不能走
if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
{//能走
//8.5 走
currentPos = searchPos;
//8.6 标记当前点已经走过
pathMap[currentPos.row][currentPos.col].isFind = true;
//8.7 当前点入栈
stack.push(currentPos);
}
break;
case p_down:
//8.2 确定试探点
searchPos.row++;
//8.4 改变当前点试探方向
pathMap[currentPos.row][currentPos.col].dir = p_left;
//8.3 试探试探点能不能走
if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
{//能走
//8.5 走
currentPos = searchPos;
//8.6 标记当前点已经走过
pathMap[currentPos.row][currentPos.col].isFind = true;
//8.7 当前点入栈
stack.push(currentPos);
}
break;
case p_left:
//8.2 确定试探点
searchPos.col--;
//8.3 试探试探点能不能走
if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
{//能走
//8.5 走
currentPos = searchPos;
//8.6 标记当前点已经走过
pathMap[currentPos.row][currentPos.col].isFind = true;
//8.7 当前点入栈
stack.push(currentPos);
}
else{//不能走
//8.8 回退
//8.8.1 退栈
stack.pop();
//8.8.2 当前点变为栈顶元素
currentPos = stack.getTop();
}
break;
}
printMap(map, currentPos);
drawMap(map, currentPos);
//找到终点 循环结束
if (currentPos.row == endPos.row &&
currentPos.col == endPos.col){
isFindEnd = true;
break;
}
//栈为空:回到起点 循环结束
if (stack.isEmpty())
break;
}
//9 打印整个路径
if (isFindEnd){
printf("path:");
while (!stack.isEmpty()){
//9.1 打印栈顶元素
printf("(%d,%d)\n", stack.getTop().row, stack.getTop().col);
//9.2 退栈
stack.pop();
}
}
LOGFONT font = { 0 };
font.lfHeight = 25;
font.lfWeight = 10;
settextstyle(&font);
outtextxy((COLS*SPACE - 110) / 2, (ROWS*SPACE - 25) / 2, L"恭喜你通关!");
while (1);
return 0;
}
void printMap(int map[ROWS][COLS], MyPoint pos){
system("cls");//清屏
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
if (i == pos.row && j == pos.col){//人
printf("人");
}
else if (map[i][j] == 1){//障碍
printf("墙");
}
else{//路
printf(" ");
}
}
printf("\n");
}
Sleep(500);
}
void initDraw(){
initgraph(COLS*SPACE, ROWS*SPACE, SHOWCONSOLE);
loadimage(&g_wall, L"wall.jpg", SPACE, SPACE, true);
loadimage(&g_road, L"road.jpg", SPACE, SPACE, true);
loadimage(&g_people, L"people.jpg", SPACE, SPACE, true);
}
void drawMap(int map[ROWS][COLS], MyPoint pos){
cleardevice();//清屏
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
if (i == pos.row && j == pos.col){//人
putimage(j*SPACE, i*SPACE, &g_people);
}
else if (map[i][j] == 1){//障碍
putimage(j*SPACE, i*SPACE, &g_wall);
}
else{//路
putimage(j*SPACE, i*SPACE, &g_road);
}
}
}
}

浙公网安备 33010602011771号