2025, Nov 01 20:46
Как ограничить ресурсы Hope и Fear до 6 в Python
Показываем, как в Python ограничить Hope и Fear максимумом 6 при бросках d12: два способа (проверка и min), защита от отрицаний при расходе, чистый игровой цикл
Когда вы автоматизируете броски кубиков для настольной механики, которая отслеживает два ресурса, может показаться, что переменную можно просто «поставить потолок». Однако в Python нет встроенного способа напрямую задать жёсткий максимум для переменной. Если вы накапливаете Надежду (Hope) и Страх (Fear) до 6 на основе двух бросков d12, ограничение нужно реализовать явно в коде.
Постановка задачи
Бросаются два d12. Если кубик Hope превосходит кубик Fear, значение Hope увеличивается на 1. Если выигрывает кубик Fear, на 1 прибавляется Fear. Ни один ресурс не может превышать 6. Ниже — минимальный фрагмент, который инкрементирует без какого‑либо ограничения и позволяет значению выйти за пределы:
if user_cmd == 'r':
pos_d12 = int(random.randint(1, 12))
neg_d12 = int(random.randint(1, 12))
sum_roll = int(pos_d12) + int(neg_d12)
print('You rolled {} with ...'.format(sum_roll))
if pos_d12 > neg_d12:
print('... hope')
hope_pool += 1
В чем причина проблемы
Python не накладывает верхнюю границу на обычные целые числа. Это означает, что увеличения будут продолжаться столько, сколько велит ваш код. Чтобы обеспечить максимум, нужно проверять текущее значение перед увеличением или явно «зажимать» результат до предела.
Также нет необходимости приводить результаты randint к int: функция уже возвращает целое. Как указано в документации:
Возвращает случайное целое N, такое что a <= N <= b. Псевдоним для randrange(a, b+1).
Два надежных способа ограничить ресурс
Первый способ — защищённый инкремент: прибавляйте 1 только когда текущее значение строго меньше потолка:
if pos_d12 > neg_d12:
if hope_pool < 6:
hope_pool = hope_pool + 1
Второй способ — всегда пытаться прибавить 1, а затем зажимать результат через min, чтобы он никогда не превышал 6:
if pos_d12 > neg_d12:
hope_pool = min(hope_pool + 1, 6)
Если hope_pool уже равен 6, выражение min(6 + 1, 6) даёт 6, так что значение остаётся на верхней границе.
Итоговый фрагмент, где оба ресурса ограничены
В следующем рефакторинге к Hope и Fear применён защищённый инкремент, а лишние приведения к int у randint и при суммировании удалены:
if user_cmd == 'r':
pos_d12 = random.randint(1, 12)
neg_d12 = random.randint(1, 12)
sum_roll = pos_d12 + neg_d12
print('You rolled {} with ...'.format(sum_roll))
if pos_d12 > neg_d12:
print('... hope')
if hope_pool < 6:
hope_pool = hope_pool + 1
if pos_d12 < neg_d12:
print('... fear')
if fear_pool < 6:
fear_pool = fear_pool + 1
if pos_d12 == neg_d12:
print('Doubles! An extreme event')
print('%s Hope, %s Fear' % (hope_pool, fear_pool))
Если вам ближе стиль с зажимом, замените защищённые инкременты на min в обеих ветках, оставив остальное без изменений:
if pos_d12 > neg_d12:
print('... hope')
hope_pool = min(hope_pool + 1, 6)
if pos_d12 < neg_d12:
print('... fear')
fear_pool = min(fear_pool + 1, 6)
Как не допустить отрицательных значений при расходе ресурса
Когда ресурс тратится, убедитесь, что он не уходит ниже нуля. Достаточно простой проверки доступности:
if user_cmd == 'h':
if hope_pool > 0:
hope_pool = hope_pool - 1
print('%s Hope, %s Fear' % (hope_pool, fear_pool))
else:
print('No hope available')
Почему это важно
Явные ограничения держат состояние игры согласованным и предсказуемым. Они предотвращают тихие переполнения, делают крайние случаи (например, уже достигнутый максимум) однозначными и не позволяют счётчикам уходить в недопустимые диапазоны. Такая предсказуемость критична для чистого игрового цикла.
Вывод
В Python нельзя «задать максимум переменной». Его обеспечивают логикой. Для увеличений либо защищайте операцию сравнением, либо зажимайте результат функцией min. Для уменьшений проверяйте, что есть что тратить. Результаты randint оставляйте как есть — это уже целые числа — и ваш дайс-роллер будет работать именно так, как задумано, не превышая лимит ресурса.
Статья основана на вопросе на StackOverflow от Nienke и ответе StandingDuck.