深度寻路算法:
二维地图:二维数组
二维数组上标识特定数值作为地图上对象
应用于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 准备栈 MyStackstack; //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; }
完整代码:
//定义栈 //定义栈 templateclass 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 void MyStack ::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 //出栈 void MyStack ::pop(void){ len--; } template //获取栈顶元素 T MyStack ::getTop(void){ return pBuff[len - 1]; } template //判断是否为空 bool MyStack ::isEmpty(void){ return (len==0); } // 深度寻路算法.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "MyStack.h" //#include #include /* 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 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); } } } }