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

重构Ruby二十一点游戏方法:通过Rubocop测试并保持DRY

重构思路与解决方案

首先,你的代码核心问题在于重复处理玩家和庄家的卡牌逻辑,这不仅违反DRY原则,还导致了Rubocop检测到的圈复杂度超标。我们可以通过提取通用的点数计算逻辑,将重复的代码抽象为可复用的辅助方法,同时合并冗余的步骤。

步骤1:提取通用点数计算方法

先写一个单独的方法,负责计算一组卡牌值(不管是玩家还是庄家的)对应的点数,把face card(J/Q/K)和整数卡牌的处理逻辑整合到一起:

def calculate_points(card_values)
  card_values.sum do |card|
    if %w[jack queen king].include?(card)
      10
    elsif card.is_a?(Integer)
      card
    else
      0 # A的处理你提到单独进行,这里先返回0不影响后续单独计算
    end
  end
end

这里用Ruby的sum方法替代手动累加,代码更简洁,sum可以直接处理块返回的数值,比手动初始化变量再累加更符合Ruby风格。

步骤2:重构原有方法为单一更新逻辑

原来的convert_face_cards和add_integer_points其实是在完成同一个目标:计算并更新玩家和庄家的总点数。我们可以把它们合并成一个方法,直接调用上面的辅助方法:

def update_player_and_dealer_points(keep_score)
  keep_score['player_points'] = calculate_points(keep_score['player_card_values'])
  keep_score['dealer_points'] = calculate_points(keep_score['dealer_card_values'])
end

为什么这样改进?

  1. 遵循DRY原则:玩家和庄家的点数计算逻辑完全复用同一个辅助方法,消除了重复的循环和条件判断。
  2. 降低圈复杂度:原来的convert_face_cards有两个循环+两个条件判断,圈复杂度超标;现在辅助方法只有一个条件分支,主方法只是两次调用辅助方法,圈复杂度直接降到符合Rubocop 0.85.0的要求(≤6)。
  3. 代码可读性更高:方法名update_player_and_dealer_points清晰表达了功能,辅助方法calculate_points的职责也单一明确。

替换原有代码

现在你可以移除原来的convert_face_cards和add_integer_points方法,在需要更新点数的地方调用update_player_and_dealer_points(keep_score)即可。如果A的点数处理需要单独调整,只需要在这个方法执行后,再添加处理A的逻辑即可(比如遍历卡牌值中的"A",根据当前点数调整加1还是11)。

内容的提问来源于stack exchange,提问作者Weston

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:52:46