口袋妖怪战斗计划中的偶尔无限循环

时间:2014-10-13 18:26:29

标签: ruby infinite-loop

这仅在程序运行时~15%的时间内发生。我通过“计数器”变量将“回合”的数量限制为10来停止无限终端循环。如果没有计数器停止循环,它会将攻击伤害降低为负指数值(ex 1.80e-80)并停止从生命值中减去。

pokemon = ['Bulbasaur', 'Charizard', 'Squirtle']


player_one_selection = rand(3)
player_two_selection = rand(3)

puts player_one_selection
counter = 0
until player_one_selection != player_two_selection
    counter += 1
    player_two_selection = rand(3)
    print "#{counter} "
end

puts player_two_selection

player_one_pkmn = pokemon[player_one_selection]
player_two_pkmn = pokemon[player_two_selection]


puts player_one_pkmn
puts player_two_pkmn

p1_dm = 1
p2_dm = 1

if player_one_pkmn == 'Bulbasaur' && player_two_pkmn == 'Charizard'
    p1_dm = 0.9
    p2_dm = 1.1
end
if player_one_pkmn == 'Squirtle' && player_two_pkmn == 'Charizard'
    p1_dm = 1.1
    p2_dm = 0.9
end
if player_one_pkmn == 'Bulbasaur' && player_two_pkmn == 'Squirtle'
    p1_dm = 1.1
    p2_dm = 0.9
end
if player_one_pkmn == 'Squirtle' && player_two_pkmn == 'Bulbasaur'
    p1_dm = 0.9
    p2_dm = 1.1
end
if player_one_pkmn == 'Charizard' && player_two_pkmn == 'Squirtle'
    p1_dm = 0.9
    p2_dm = 1.1
end
if player_one_pkmn == 'Charizard' && player_two_pkmn == 'Bulbasaur'
    p1_dm = 1.1
    p2_dm = 0.9
end

jugador_uno = {
    "pokemon"           => player_one_pkmn,
    "pokemon-type"      => "",
    "pokemon-health"    => 100,
    "damage-modifier"   => p1_dm,
    "pokemon-lvl"       => rand(5)+5,
    "current-attack" => ["",0]
}
jugador_dos = {
    "pokemon"           => player_two_pkmn,
    "pokemon-type"      => "",
    "pokemon-health"    => 100,
    "damage-modifier"   => p2_dm,
    "pokemon-lvl"       => rand(5)+5,
    "current-attack" => ["",0]
}

puts jugador_uno
puts jugador_dos

puts "\nReady to Battle! \n"

attacks = [
    ['tackle', 20], ['leer', 5], ['bite', 35], ['special-attack', 50]
]
counter = 0
# until jugador_uno['pokemon-health'] <= 0 || jugador_dos['pokemon-health'] <= 0
loop do
    jugador_uno['current-attack'] = attacks[rand(4)]
    jugador_dos['current-attack'] = attacks[rand(4)]

    jugador_uno['current-attack'][1] = jugador_uno['current-attack'][1] * jugador_uno['pokemon-lvl'] / 10 * jugador_uno['damage-modifier']
    jugador_dos['current-attack'][1] = jugador_dos['current-attack'][1] * jugador_dos['pokemon-lvl'] / 10 * jugador_dos['damage-modifier']

    puts "Lvl. #{jugador_uno['pokemon-lvl']} #{jugador_uno['pokemon']} attack: #{jugador_uno['current-attack'][0].capitalize} did #{jugador_uno['current-attack'][1]} damage."
    puts "Lvl. #{jugador_dos['pokemon-lvl']} #{jugador_dos['pokemon']} attack: #{jugador_dos['current-attack'][0].capitalize} did #{jugador_dos['current-attack'][1]} damage.\n"

    jugador_dos['pokemon-health'] -= jugador_uno['current-attack'][1]
    jugador_uno['pokemon-health'] -= jugador_dos['current-attack'][1]

    puts "\n#{jugador_uno['pokemon']} health: #{jugador_uno['pokemon-health']}"
    puts "#{jugador_dos['pokemon']} health: #{jugador_dos['pokemon-health']}\n"

    counter += 1

    break if jugador_uno['pokemon-health'] <= 0 || jugador_dos['pokemon-health'] <= 0 || counter > 10
end

在无限循环中卡住的终端输出

Seths-MacBook-Air:learn-ruby$ ruby pokemon_game.rb 
2
0
Squirtle
Bulbasaur
{"pokemon"=>"Squirtle", "pokemon-type"=>"", "pokemon-health"=>100, "damage-modifier"=>0.9, "pokemon-lvl"=>6, "current-attack"=>["", 0]}
{"pokemon"=>"Bulbasaur", "pokemon-type"=>"", "pokemon-health"=>100, "damage-modifier"=>1.1, "pokemon-lvl"=>6, "current-attack"=>["", 0]}

Ready to Battle! 
Lvl. 6 Squirtle attack: Bite did 18.900000000000002 damage.
Lvl. 6 Bulbasaur attack: Tackle did 13.200000000000001 damage.

Squirtle health: 86.8
Bulbasaur health: 81.1
Lvl. 6 Squirtle attack: Special-attack did 27.0 damage.
Lvl. 6 Bulbasaur attack: Leer did 3.3000000000000003 damage.

Squirtle health: 83.5
Bulbasaur health: 54.099999999999994
Lvl. 6 Squirtle attack: Bite did 10.206 damage.
Lvl. 6 Bulbasaur attack: Leer did 2.178 damage.

Squirtle health: 81.322
Bulbasaur health: 43.89399999999999
Lvl. 6 Squirtle attack: Bite did 5.51124 damage.
Lvl. 6 Bulbasaur attack: Leer did 1.43748 damage.

Squirtle health: 79.88452000000001
Bulbasaur health: 38.38275999999999
Lvl. 6 Squirtle attack: Special-attack did 14.58 damage.
Lvl. 6 Bulbasaur attack: Bite did 3.6374184 damage.

Squirtle health: 76.24710160000001
Bulbasaur health: 23.802759999999992
Lvl. 6 Squirtle attack: Tackle did 7.128 damage.
Lvl. 6 Bulbasaur attack: Leer did 0.9487368000000003 damage.

Squirtle health: 75.2983648
Bulbasaur health: 16.674759999999992
Lvl. 6 Squirtle attack: Bite did 1.29637591776 damage.
Lvl. 6 Bulbasaur attack: Bite did 1.29637591776 damage.

Squirtle health: 74.00198888224
Bulbasaur health: 15.378384082239991
Lvl. 6 Squirtle attack: Leer did 0.5123178720000002 damage.
Lvl. 6 Bulbasaur attack: Tackle did 4.70448 damage.

Squirtle health: 69.29750888224
Bulbasaur health: 14.86606621023999
Lvl. 6 Squirtle attack: Bite did 0.7000429955904002 damage.
Lvl. 6 Bulbasaur attack: Leer did 0.3381297955200002 damage.

Squirtle health: 68.95937908671999
Bulbasaur health: 14.166023214649591
Lvl. 6 Squirtle attack: Bite did 0.37802321761881613 damage.
Lvl. 6 Bulbasaur attack: Leer did 0.22316566504320015 damage.

Squirtle health: 68.7362134216768
Bulbasaur health: 13.787999997030775
Lvl. 6 Squirtle attack: Bite did 0.1347274747593461 damage.
Lvl. 6 Bulbasaur attack: Bite did 0.1347274747593461 damage.

Squirtle health: 68.60148594691745
Bulbasaur health: 13.653272522271429

1 个答案:

答案 0 :(得分:2)

假设你的问题是&#34;为什么这个程序无限循环?&#34;,那么答案是在某些情况下攻击数组中的值:

attacks = [
    ['tackle', 20], ['leer', 5], ['bite', 35], ['special-attack', 50]
]

逐渐减少到0.

您可以通过修改上述代码来打印出攻击中的值:

loop do
  puts "attack choices: #{attacks}"

  jugador_uno['current-attack'] = attacks[rand(4)]
  jugador_dos['current-attack'] = attacks[rand(4)]

  jugador_uno['current-attack'][1] = jugador_uno['current-attack'][1] * jugador_uno['pokemon-lvl'] / 10 * jugador_uno['damage-modifier']
  jugador_dos['current-attack'][1] = jugador_dos['current-attack'][1] * jugador_dos['pokemon-lvl'] / 10 * jugador_dos['damage-modifier']

  # ...
end

您会发现,在第一次迭代中,攻击包含['tackle', 20], ['leer', 5], ['bite', 35], ['special-attack', 50]的初始值,但后续迭代将使用更新的值替换它们。

例如,

attack choices: [["tackle", 20], ["leer", 5], ["bite", 35], ["special-attack", 50]]
attack choices: [["tackle", 20], ["leer", 5], ["bite", 10.395000000000001], ["special-attack", 50]]
attack choices: [["tackle", 20], ["leer", 2.7], ["bite", 1.6980232500000005], ["special-attack", 50]]

# bunch of iterations later

attack choices: [["tackle", 5.219269710359129e-11], ["leer", 2.46107539497387e-11], ["bite", 2.5860511581722106e-16], ["special-attack", 9.938279578366043e-12]]

这些值将在以下两行代码中替换:

jugador_uno['current-attack'][1] = jugador_uno['current-attack'][1] * jugador_uno['pokemon-lvl'] / 10 * jugador_uno['damage-modifier']
jugador_dos['current-attack'][1] = jugador_dos['current-attack'][1] * jugador_dos['pokemon-lvl'] / 10 * jugador_dos['damage-modifier']

jugador_uno['damage-modifier']jugador_dos['damage-modifier']小于1(例如,0.9)时,您会遇到问题。