如何避免ArrayList生成类以撒的结合Roguelike房间时出现重叠?
嘿,这个问题我做类以撒Roguelike的时候也踩过坑!核心问题其实是你现在只靠门的布尔值来管理房间,但没给每个房间绑定唯一的位置坐标——这就导致绕圈移动后,程序认不出“回到初始位置”这件事,反而生成新房间造成重叠。下面给你几个具体的解决思路:
你当前的ArrayList只是堆了一堆房间对象,但每个房间没有“我在地图哪个位置”的标识。比如从初始房间A往东到B,再往南到C,往西到D,最后往北走时,程序只会检查D的North门是否开启,完全意识不到这个“北边”对应的就是最初的A,于是直接生成新房间,自然就重叠了。
1. 给房间添加坐标属性
给你的Room类加上int x和int y两个字段,用网格坐标标记房间位置:
- 初始房间设为
(0, 0) - 往东移动→新房间坐标
(currentX + 1, currentY) - 往西移动→
(currentX - 1, currentY) - 往北移动→
(currentX, currentY + 1)(如果你的坐标系是Y轴向上为正,反之为负就调整成currentY - 1) - 往南移动→
(currentX, currentY - 1)
之后生成新房间前,先遍历ArrayList(或用更高效的容器)检查是否存在对应坐标的房间:有就直接复用,没有再创建新的。
2. 必须双向同步门的状态
你提到的“房间1上方的房间2将South设为true”,这里一定要记得双向绑定:
比如从房间A(0,0)往北创建房间B(0,1),不仅要把B的South = true,还要把A的North = true。这样后续从B往南走时,程序能通过坐标找到A,同时门的状态也完全匹配,不会出现“门开了但找不到对应房间”的情况。
3. 用HashMap替代ArrayList(效率升级)
如果地图规模会变大,用ArrayList遍历找坐标房间会越来越慢,换成HashMap<Coordinate, Room>(自定义一个Coordinate类存x和y当键),能直接O(1)定位房间,效率提升明显。示例代码大概是这样:
// 自定义Coordinate类,重写equals和hashCode方法 class Coordinate { int x; int y; // 构造方法、getter/setter @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Coordinate that = (Coordinate) o; return x == that.x && y == that.y; } @Override public int hashCode() { return Objects.hash(x, y); } } // 管理房间的容器 HashMap<Coordinate, Room> roomMap = new HashMap<>(); // 移动时的逻辑示例(以东向移动为例) Coordinate currentCoord = new Coordinate(currentRoom.getX(), currentRoom.getY()); Coordinate targetCoord = new Coordinate(currentCoord.x + 1, currentCoord.y); if (roomMap.containsKey(targetCoord)) { // 目标房间已存在,直接切换 currentRoom = roomMap.get(targetCoord); } else { // 创建新房间并同步门状态 Room newRoom = new Room(targetCoord.x, targetCoord.y); currentRoom.setEast(true); newRoom.setWest(true); roomMap.put(targetCoord, newRoom); currentRoom = newRoom; }
4. 移动前的固定检查流程
每次处理移动请求时,严格按这个逻辑走:
- 根据当前房间坐标和移动方向,计算目标坐标
- 检查地图容器中是否存在该坐标的房间
- 存在→直接切换到该房间;不存在→创建新房间+双向同步门状态+加入容器
这样就能彻底避免绕圈后生成重复房间的问题,因为你是靠坐标唯一标识来定位房间,而不是只依赖门的状态。
- 测试时可以打印每个房间的坐标,能快速排查是否生成了重复位置的房间
- 如果用自定义
Coordinate当HashMap的键,一定要重写equals()和hashCode(),否则HashMap会识别不出相同坐标的对象
内容的提问来源于stack exchange,提问作者224634

