在Elixir中实现二叉树迷宫算法时如何更新网格单元格
Elixir实现二叉树迷宫生成的解决思路
你的核心问题是没利用好Elixir的不可变数据累积特性——Enum.map只适合转换单个元素,没法处理需要同时更新两个单元格并维护全局网格状态的场景,换成Enum.reduce就能解决。
关键修改点
- 用
Enum.reduce代替Enum.map,以原迷宫的grid作为初始累积状态,每次迭代都返回更新后的grid - 调用
open_to拿到两个更新后的单元格后,把它们都放入累积的grid中 - 最后返回包含更新后grid的迷宫实例
修改后的代码示例
def generate(mz) do updated_grid = Enum.reduce(mz.grid, mz.grid, fn({{x, y}, _c1}, acc_grid) -> neighbors = [Grid.cell_to(mz, x, y, :north), Grid.cell_to(mz, x, y, :east)] c2_dir = select_the_neighbor(neighbors) if c2_dir do {c1_new, c2_new} = Grid.open_to(mz, x, y, c2_dir) # 根据方向获取邻居单元格的坐标,你需要实现这个辅助函数 {c2_x, c2_y} = Grid.neighbor_coords(x, y, c2_dir) # 依次更新当前单元格和邻居单元格到累积网格 acc_grid |> Map.put({x, y}, c1_new) |> Map.put({c2_x, c2_y}, c2_new) else acc_grid end end) # 返回更新后的迷宫结构体 %{mz | grid: updated_grid} end
补充说明
- 辅助函数
Grid.neighbor_coords/3逻辑很简单:比如传入(x, y, :north)就返回{x, y-1},传入:east返回{x+1, y},根据你的网格坐标系调整即可 Enum.reduce的累积器acc_grid会始终保存当前最新的网格状态,后续遍历到邻居单元格时,拿到的已经是更新后的版本- 因为Elixir数据不可变,每次
Map.put都会生成新的map,不会污染原数据,完全符合函数式编程的要求
内容的提问来源于stack exchange,提问作者mszmurlo
相关产品推荐
相关产品推荐

