Fire Emblem地图楼梯方向识别Rust实现问题排查
修复Fire Emblem地图楼梯方向判断逻辑错误
核心问题分析
你的代码大概率存在两个关键问题:
- 未明确规则优先级:规则1(相邻楼梯判断)应优先于规则2(障碍物限制)执行
- 无相邻楼梯时,未正确遍历所有可能方向并过滤掉指向障碍物的选项,也未处理无合法方向时的默认值返回
规则梳理与实现思路
先明确判断逻辑的优先级顺序:
- 优先检查相邻楼梯:
- 若当前瓷砖上下方向存在楼梯瓷砖,直接返回垂直方向(≡)
- 若左右方向存在楼梯瓷砖,直接返回水平方向(|||)
- 无相邻楼梯时,执行障碍物限制逻辑:
- 遍历所有可能的楼梯方向(垂直/水平),检查该朝向指向的瓷砖是否属于
LowObstacle或HighObstacle - 选择第一个合法的方向;若两个方向都不合法,返回默认值(比如垂直方向)
- 遍历所有可能的楼梯方向(垂直/水平),检查该朝向指向的瓷砖是否属于
修复后的代码示例(以Rust为例)
use std::fmt; // 定义楼梯方向枚举 #[derive(Debug, Clone, Copy, PartialEq)] pub enum StairDirection { Vertical, // ≡ Horizontal, // ||| Default, // 特殊情况默认值 } impl fmt::Display for StairDirection { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { StairDirection::Vertical => write!(f, "≡"), StairDirection::Horizontal => write!(f, "|||"), StairDirection::Default => write!(f, "≡"), // 默认显示垂直 } } } // 假设TerrainGroup枚举定义 #[derive(Debug, Clone, Copy, PartialEq)] pub enum TerrainGroup { Stair, LowObstacle, HighObstacle, Other, } pub struct GameBoard { tiles: Vec<Vec<TerrainGroup>>, width: usize, height: usize, } impl GameBoard { // 获取指定坐标的地形分组 fn get_terrain_group(&self, x: usize, y: usize) -> Option<TerrainGroup> { self.tiles.get(y)?.get(x).copied() } // 判断指定坐标是否为楼梯瓷砖 fn is_stair(&self, x: usize, y: usize) -> bool { self.get_terrain_group(x, y) == Some(TerrainGroup::Stair) } // 修复后的楼梯方向判断方法 pub fn stair_direction(&self, x: usize, y: usize) -> StairDirection { // 规则1:优先检查相邻楼梯 let has_vertical_neighbor = (y > 0 && self.is_stair(x, y - 1)) || (y < self.height - 1 && self.is_stair(x, y + 1)); let has_horizontal_neighbor = (x > 0 && self.is_stair(x - 1, y)) || (x < self.width - 1 && self.is_stair(x + 1, y)); if has_vertical_neighbor { return StairDirection::Vertical; } if has_horizontal_neighbor { return StairDirection::Horizontal; } // 规则2:无相邻楼梯时,检查障碍物限制 // 检查垂直方向指向的瓷砖是否合法(非障碍物) let vertical_valid = match y { 0 => self.get_terrain_group(x, y + 1).map(|g| !matches!(g, TerrainGroup::LowObstacle | TerrainGroup::HighObstacle)).unwrap_or(false), h if h == self.height - 1 => self.get_terrain_group(x, y - 1).map(|g| !matches!(g, TerrainGroup::LowObstacle | TerrainGroup::HighObstacle)).unwrap_or(false), _ => { let up_valid = self.get_terrain_group(x, y - 1).map(|g| !matches!(g, TerrainGroup::LowObstacle | TerrainGroup::HighObstacle)).unwrap_or(false); let down_valid = self.get_terrain_group(x, y + 1).map(|g| !matches!(g, TerrainGroup::LowObstacle | TerrainGroup::HighObstacle)).unwrap_or(false); up_valid || down_valid } }; // 检查水平方向指向的瓷砖是否合法 let horizontal_valid = match x { 0 => self.get_terrain_group(x + 1, y).map(|g| !matches!(g, TerrainGroup::LowObstacle | TerrainGroup::HighObstacle)).unwrap_or(false), w if w == self.width - 1 => self.get_terrain_group(x - 1, y).map(|g| !matches!(g, TerrainGroup::LowObstacle | TerrainGroup::HighObstacle)).unwrap_or(false), _ => { let left_valid = self.get_terrain_group(x - 1, y).map(|g| !matches!(g, TerrainGroup::LowObstacle | TerrainGroup::HighObstacle)).unwrap_or(false); let right_valid = self.get_terrain_group(x + 1, y).map(|g| !matches!(g, TerrainGroup::LowObstacle | TerrainGroup::HighObstacle)).unwrap_or(false); left_valid || right_valid } }; // 选择合法方向,都不合法则返回默认值 match (vertical_valid, horizontal_valid) { (true, _) => StairDirection::Vertical, (_, true) => StairDirection::Horizontal, _ => StairDirection::Default, } } }
关键修复点说明
- 规则优先级明确:先处理相邻楼梯的情况,确保符合规则1的要求
- 边界处理完善:针对地图边缘的瓷砖,单独判断朝向的合法性(比如顶部瓷砖只能向下检查)
- 合法方向过滤:无相邻楼梯时,先验证垂直/水平方向是否指向非障碍物,再选择方向
- 特殊情况兜底:当所有方向都被障碍物阻挡时,返回默认值
内容的提问来源于stack exchange,提问作者Lnio Yarschov
相关产品推荐
相关产品推荐

