如何在Swift的N×N二维数组中生成起点到终点的随机路径?
嘿,这个问题其实挺常见的——GameplayKit虽然常和图结构绑定,但处理无障碍物的网格路径生成完全没问题,甚至不用提前构建复杂的图。我给你几个实用的方案,从贴合你需求的GameplayKit实现到轻量的手动写法都有:
方案1:基于GameplayKit的网格路径生成(最贴合你的需求)
其实GameplayKit里的GKGridGraph就是专门为网格场景设计的,你不需要手动搭建图结构,直接把你的N×N数组对应成网格图就行:
- 第一步:初始化网格图,指定网格宽高(也就是你的N值),同时禁用对角线移动,正好匹配你的规则:
let gridGraph = GKGridGraph(fromGridStartingAt: SIMD2<Int>(0, 0), width: N, height: N, diagonalsAllowed: false)
- 第二步:把你的起点、终点坐标转成
GKGridGraphNode节点:
let startNode = gridGraph.node(atGridPosition: SIMD2<Int>(startX, startY))! let endNode = gridGraph.node(atGridPosition: SIMD2<Int>(endX, endY))!
- 第三步:生成随机路径。用GameplayKit自带的随机源,搭配
GKRandomPathfinderStrategy就能生成随机化的路径:
let randomStrategy = GKRandomPathfinderStrategy(randomSource: GKRandomSource.sharedRandom()) let pathNodes = gridGraph.findPath(from: startNode, to: endNode, using: randomStrategy)
- 最后一步:把路径节点转成你需要的二维数组坐标,遍历
pathNodes,每个节点的gridPosition就是对应的(x,y)坐标啦。
方案2:手动实现随机游走(无需GameplayKit,更轻量)
如果不想依赖GameplayKit,手动写个随机游走逻辑也很简单,核心是每次从当前位置的上下左右四个方向里选一个没走过的方向,直到抵达终点。需要注意加个访问矩阵避免死循环:
- 先初始化一个和N×N数组同大小的布尔矩阵
visited,把起点标记为已访问。 - 当前位置设为起点,把起点加入路径列表。
- 循环执行以下步骤:
- 收集当前位置所有合法的相邻位置(必须在网格范围内,且未被访问过)。
- 如果终点就在相邻位置里,直接把终点加入路径,结束循环。
- 如果有可选方向,随机挑一个,标记为已访问,加入路径,更新当前位置。
- 如果没有可选方向,就回溯到上一个位置(这就是简单的回溯逻辑),直到找到还有可选方向的位置。
- 这个方法的好处是完全自定义,你可以随时调整路径的“随机程度”,比如偶尔让它偏向某个方向,或者限制回溯的次数。
方案3:基于迷宫生成思路的路径生成(更自然流畅)
如果你想要更自然、少来回绕的路径,可以借鉴迷宫生成的算法思路,比如随机DFS或者Prim算法,只需要生成起点到终点的路径即可:
- 本质还是回溯,但在选择方向时优先挑未探索过的区域,生成的路径会更“流畅”,不会有太多重复走回头路的情况。
- 实现逻辑和方案2类似,只是在可选方向的筛选上,优先保留未访问的区域,再从中随机选择。
小提示:如果只是需要随机有效路径、不依赖GameplayKit的其他功能,方案2和3的灵活性更高;如果后续可能要添加障碍物或者结合GameplayKit的其他系统,方案1的扩展性更好,因为
GKGridGraph可以很方便地添加/移除障碍节点。
内容的提问来源于stack exchange,提问作者Hantex
相关产品推荐
相关产品推荐

