2014-10-13 2 views
0

Это происходит только в 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 
+0

Хотя это не отвечает на ваш вопрос, более простой способ получить разные случайные выборки для двух игроков - использовать [Array # sample] (http://www.ruby-doc.org/core-2.1.3 /Array.html#method-i-sample): '[0,1,2] .sample (2)'. –

+0

Пожалуйста, уменьшите код до минимума, необходимого для демонстрации проблемы. –

ответ

2

Предполагая, что ваш вопрос «Почему эта программа бесконечно зацикливание?», То ответ, что в некоторых случаях значения в вашем массиве атаки:

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), а затем вы столкнетесь с проблемами.

+0

Спасибо, я не думал об перезагрузке значений, чтобы они не уменьшались, но я чувствую, что это придет позже, когда я не буду делать простые игры Pokemon lol. @hjing, я не могу проголосовать за вас, потому что у меня недостаточно репутации, и я не знаю, как отметить это как ответ, но вы определенно дали отличный ответ, спасибо большое! – Seth

Смежные вопросы