多次运行功能并跟踪战斗模拟结果

时间:2019-04-14 11:34:52

标签: ruby

我已经创建了运行模拟战斗的功能。它有一个随机元素,因此想运行100次以检查结果。

我了解到ruby不能在函数内部具有函数。

$p1_skill = 10
$p1_health = 10

$p2_skill = 10
$p2_health = 10

def hp_check
  if $p2_health >= 1 && $p1_health == 0
    return "p2_wins"
  elsif $p1_health >= 1 && $p2_health == 0
     return "p1_wins"
  else 
    battle
  end
end

def battle
  p1_fight = $p1_skill + rand(2..12)
  p2_fight = $p2_skill + rand(2..12)
  if p1_fight > p2_fight
    $p2_health -= 2
    hp_check
  elsif p2_fight > p1_fight
    $p1_health -= 2
    hp_check
  else
    battle
   end
end

battle

现在,这准确地产生了赢家。它掷出两个骰子,并将其添加到玩家技能中。如果其比其他玩家高,则该另一玩家失去2点生命。 玩家的技能和生命值将在整个游戏中发生变化,这是为项目分配的。 我喜欢这样为平衡问题赢得胜利的机会。

1 个答案:

答案 0 :(得分:0)

关于您的实施情况,我有几点建议。请注意,由于这是一项家庭作业,因此我将分步提供答案,而不仅仅是为您提供整个程序。没有特别的顺序...

  1. 不要使用全局变量。我怀疑这是您尝试实现模型的多次运行时遇到的主要障碍。模型状态应包含在模型方法中,并且初始状态可以作为参数传递给它。示例:

def battle(p1_skill, p1_health, p2_skill, p2_health)


  1. 除非您的讲师要求您使用递归,否则简单的循环结构将为您提供更好的服务。直到一个玩家或另一个玩家降至零(或更低)之前,无需检查谁赢了。也不需要else递归调用battle,即使双方都没有命中,循环也会循环到下一轮战斗,即使双方都没有命中。

while p1_health > 0 && p2_health > 0
  # roll the dice and update health
end
# check who won and return that answer


    确实不需要
  1. hp_check,当您丢失递归调用时,如果您在退出循环后执行检查,它将变成单线。同样,只退还获胜者会更有用,因此,获得退还价值的人可以决定是否要打印退还价值,使用退还价值来更新理货,两者还是全部。突破以上概述的循环后:

# determine which player won, since somebody's health dropped to 0 or less
p1_health > 0 ? 1 : 2


  1. 在增加或减少数量时,请勿进行相等性测试。 p1_health <= 0p1_health == 0安全得多,因为有一天,您或其他人将以一个奇数开始,同时递减2,或者递减其他(随机数)。


  1. 统一生成2到12之间的数字 不是 与将两个6边骰子相加相同。两个骰子可能有36种结果。 36个中只有一个产生2,只有一个产生12,而在另一极端,有六种方法得到7的总和。我创建了一个小骰子掷骰方法,该方法将骰子数作为参数:


def roll_dice(n)
  n.times.inject(0) { |total| total + rand(1..6) }
end

例如,确定玩家1的战斗得分将变为p1_fight = p1_skill + roll_dice(2)

进行了这些更改之后,统计数据非常简单:

n = 10000
number_of_p1_wins = 0
n.times { number_of_p1_wins += 1 if battle(10, 10, 10, 10) == 1 }
proportion = number_of_p1_wins.to_f / n
puts "p1 won #{"%5.2f" % (100.0 * proportion)}% of the time"

如果通过获取用户输入或遍历范围来替换对battle的调用中的常数10,则可以探索其他多种情况。