#ruby
#ruby
Вопрос:
Я создал функцию для запуска моделирования боя. У него есть случайный элемент, поэтому хотелось бы запустить его 100 раз, чтобы проверить результаты.
Я узнал, что ruby не может иметь функции внутри функций.
$p1_skill = 10
$p1_health = 10
$p2_skill = 10
$p2_health = 10
def hp_check
if $p2_health >= 1 amp;amp; $p1_health == 0
return "p2_wins"
elsif $p1_health >= 1 amp;amp; $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 здоровья.
Навыки и hp игроков будут меняться на протяжении всей игры, это для задания проекта.
Мне нравится это, чтобы создавать коэффициенты для шансов на победу при балансировке проблем.
Комментарии:
1. Не могли бы вы немного уточнить, в чем ваш вопрос? Чего вы хотите достичь? В чем ваша проблема? Вы хотите запустить эту функцию несколько раз, и вы не видите, как ее достичь? Или у вас есть ошибка в вашей функции?
2. Извините, первый пост. Приведенный выше код работает, если вы его запустите. Он сообщит, выиграет ли игрок 1 или 2. 50% каждый, потому что статистика в настоящее время одинакова. Я хотел бы иметь возможность запускать это x раз и отображать, какой% выиграл каждый игрок. Возможно, каждый раз, когда выполняется вышеупомянутое, оно добавляется к счетчику побед, но я уже пробовал это. Основная проблема заключается в том, что я не могу объединить два описанных выше метода в методе перегиба. Подведены итоги. Я хочу иметь возможность запускать это 100 раз, затем я получаю вывод, в котором говорится, что игрок один выиграл 60 раз, игрок 2 выиграл 40 раз. * числа, используемые для примера.
Ответ №1:
У меня есть несколько предложений относительно вашей реализации. Обратите внимание, что, поскольку это домашнее задание, я предоставляю ответ по частям, а не просто даю вам целую программу. В произвольном порядке…
- Не используйте глобальные переменные. Я подозреваю, что это основное препятствие, с которым вы сталкиваетесь, пытаясь выполнить несколько запусков вашей модели. Состояние модели должно содержаться в методах модели, и начальное состояние может быть передано ему в качестве аргументов. Пример:
def battle(p1_skill, p1_health, p2_skill, p2_health)
- Если ваш инструктор не поручил вам использовать рекурсию, простая структура цикла будет служить вам намного лучше. Нет необходимости проверять, кто выиграл, пока один или другой игрок не опустится до нуля (или ниже). Также нет необходимости в
else
рекурсивном вызовеbattle
to , цикл перейдет к следующему раунду боя, если оба игрока все еще находятся в процессе, даже если ни один из игроков не получил удар.
while p1_health > 0 amp;amp; p2_health > 0
# roll the dice and update health
end
# check who won and return that answer
hp_check
на самом деле это не нужно, когда вы теряете рекурсивные вызовы, это становится однострочным, если вы выполняете проверку после выхода из цикла. Кроме того, было бы более полезно возвращать только победителя, чтобы тот, кто получит это возвращаемое значение, мог решить, хотят ли они его распечатать, использовать для обновления подсчета, и то, и другое, или что-то еще. После выхода из цикла, описанного выше:
# determine which player won, since somebody's health dropped to 0 or less
p1_health > 0 ? 1 : 2
- Когда вы увеличиваете или уменьшаете количество, не выполняйте проверку на равенство.
p1_health <= 0
намного безопаснее, чемp1_health == 0
, потому что когда-нибудь вы или кто-то другой начнете с нечетного числа, уменьшив его на 2 или уменьшив на какую-то другую (случайную?) Величину.
- Равномерное генерирование числа от 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"
Если вы замените константу 10 в вызове на battle
, получая пользовательский ввод или перебирая диапазоны, вы можете исследовать богатый набор других сценариев.