递归实现的Roguelike地图路径寻路评分函数异常排查
问题原因与解决方案
核心问题1:递归采用深度优先搜索(DFS)而非广度优先搜索(BFS)
你当前的递归实现是深度优先搜索,这种遍历方式会优先深入路径尽头,给远处的单元格先赋值较大的score。当后续更近的路径到达同一单元格时,因为单元格已经不是初始的.,守卫条件map[player_x][player_y] == '.'会直接返回,无法将其更新为正确的最小距离,最终导致数值混乱。
举个具体例子:(2,1)这个位置,会先被左分支递归的深层调用(score=3)赋值,而原本应该由初始调用的上分支(score=1)赋值,但此时单元格已被占用,无法覆盖为正确的小数值。
核心问题2:char类型与int类型的赋值不匹配
你的map是char类型,但直接将int类型的score赋值给它,存储的是对应ASCII码值而非字符数字。比如score=1会被存为ASCII值1(不可见控制字符),虽然你输出时可能转成了int显示出数字,但后续如果score超过9,或者直接输出char,会出现异常显示。
解决方案
1. 替换为广度优先搜索(BFS)实现
最短路径的距离填充必须用BFS,因为BFS按距离层级遍历,每个单元格第一次被访问时就是最短距离,无需担心被后续长路径覆盖。用队列实现BFS的代码如下:
#include <queue> #include <array> const int map_size = 5; std::array<std::array<char, map_size>, map_size> map; void monster_vision(int start_x, int start_y) { // 队列存储坐标(x,y)和当前距离score std::queue<std::pair<std::pair<int, int>, int>> q; q.push({{start_x, start_y}, 0}); // 标记起点为字符'0' map[start_x][start_y] = '0'; // 四个方向的偏移量 const int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; while (!q.empty()) { auto current = q.front(); q.pop(); int x = current.first.first; int y = current.first.second; int score = current.second; // 遍历四个相邻方向 for (const auto& dir : dirs) { int nx = x + dir[0]; int ny = y + dir[1]; // 检查边界有效性,且单元格未被访问(值为'.') if (nx >= 0 && nx < map_size && ny >= 0 && ny < map_size && map[nx][ny] == '.') { // 将score转为字符数字存入map map[nx][ny] = '0' + (score + 1); // 将新单元格加入队列,距离+1 q.push({{nx, ny}, score + 1}); } } } }
2. 修正类型赋值问题
将int类型的score转为字符数字后再赋值给char类型的map,即使用'0' + score,这样存储的是字符'0'、'1'、'2'等,直接输出就能显示正确的数字字符。
验证效果
调用monster_vision(2,2)后,map会生成你预期的对称距离数值:
##### #212# #101# #212# #####
内容的提问来源于stack exchange,提问作者aallfik11
相关产品推荐
相关产品推荐

