You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化国际象棋车合法移动方法的Ruby实现:语法简化或算法改进

优化国际象棋车合法移动方法的Ruby实现:语法简化或算法改进

嘿,你的方法逻辑是完全正确的,但确实有点重复冗余——四个几乎一样的循环确实不够优雅。我来分享几种Ruby风格的简化方式,让代码更简洁易读,同时保持功能不变。

一、最直观的简化:利用Range与迭代器

Ruby的Range和高阶方法能帮我们摆脱重复的循环,直接生成目标坐标:

def valid_rook_moves
  # 生成同一列的所有合法移动(排除当前位置)
  column_moves = (0..7).reject { |nx| nx == @x }.map { |nx| [nx, @y] }
  # 生成同一行的所有合法移动(排除当前位置)
  row_moves = (0..7).reject { |ny| ny == @y }.map { |ny| [@x, ny] }
  # 合并两类移动并返回
  column_moves + row_moves
end

解释:

  • (0..7)直接生成棋盘上所有合法的坐标值(0到7的整数)
  • reject过滤掉当前位置的坐标,避免把自身位置加入移动列表
  • map把单个坐标值转换成[x,y]格式的位置数组
  • 最后合并列和行的移动结果,和你原方法的输出完全一致

比如当@x=0且@y=0时,这段代码会生成和你示例完全相同的输出,逻辑清晰且没有重复代码。

二、更紧凑的写法:用flat_map简化判断

如果喜欢更紧凑的代码,可以用flat_map把过滤和转换合并成一步:

def valid_rook_moves
  # 生成列移动:如果nx不是当前x,就生成坐标,否则返回空数组
  column_moves = (0..7).flat_map { |nx| nx == @x ? [] : [[nx, @y]] }
  # 生成行移动:同理
  row_moves = (0..7).flat_map { |ny| ny == @y ? [] : [[@x, ny]] }
  column_moves + row_moves
end

flat_map会自动把嵌套的数组展开,省去了单独的过滤步骤,代码更短但依然保持可读性。

三、Ruby风格的组合写法:用product方法

还可以用product(笛卡尔积)来快速生成坐标组合,这种写法很有Ruby特色:

def valid_rook_moves
  [
    # 列坐标组合:所有x值(除当前x)和当前y的乘积
    (0..7).to_a.reject { |i| i == @x }.product([@y]),
    # 行坐标组合:当前x和所有y值(除当前y)的乘积
    [[@x]].product((0..7).to_a.reject { |i| i == @y })
  ].flatten(1)
end

product方法会把两个数组的元素两两组合,正好符合我们“固定一个坐标,遍历另一个”的需求,最后用flatten(1)把嵌套的数组层级拉平,得到最终的移动列表。

为什么这些写法更好?

  • 消除重复代码:原方法的四个循环逻辑几乎完全一致,优化后的代码把重复逻辑抽象成了通用的范围处理,维护起来更方便
  • 可读性更高:代码直接表达了“生成列移动”“生成行移动”的意图,而不是用底层的循环步骤来实现
  • Ruby风格:充分利用了Ruby的Enumerable模块方法,让代码更简洁优雅

备注:内容来源于stack exchange,提问作者jbk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 09:35:31