Игра в кости»
Итак, только что запустил python неделю назад, поэтому я ищу отзывы / критику о том, что я могу сделать, чтобы улучшить свой код. Я написал небольшую игру в кости для пользователя / компьютера. Любая обратная связь приветствуется!
def dice(n: int) -> tuple:
"""
Simple function to roll 'n' number of dices.
Returns numbers of each roll and a total.
:param n: number of dices to roll
:return: dices_numbers, total
"""
numbers = []
total = 0
for dices in range(n):
number = random.randint(1, 6)
numbers.append(number)
total += number
dices_numbers = ", ".join(map(str, numbers))
return dices_numbers, total
def dice_check(user_total: int = 0, pc_total: int = 0) -> None:
"""
Function to check whether user or pc won dice roll.
:param user_total: user's total roll
:param pc_total: pc's total roll
:return: None
"""
if user_total > pc_total:
print("Congratulations! You won")
elif user_total < pc_total:
print("Sorry, BOT wins!")
else:
print("Tie!")
number_of_dices = ""
user_roll = ""
pc_roll = ""
while True:
number_of_dices = int(input("How many dices would you like to roll?"
" (0 to quit) >"))
if number_of_dices == 0:
break
else:
user_roll = dice(number_of_dices)
pc_roll = dice(number_of_dices)
print(f"You: Roll: {user_roll[0]}, a total of: {user_roll[1]}")
print(f"BOT: Roll: {pc_roll[0]}, a total of: {pc_roll[1]}")
dice_check(user_roll[1], pc_roll[1])
2 ответа
Вы на правильном пути, помещая большую часть своего кода внутрь функций. Я призываю вас пройти полную дистанцию и сделать это своей стандартной привычкой. В приведенном ниже коде это делается путем создания main()
функция.
Python имеет встроенный sum()
функция, так что ваш dice()
и dice_check()
функции, вероятно, выполняют больше работы, чем им нужно. Это не имеет большого значения. Иногда, когда вы учитесь, делаете то, что трудный путь может быть познавательным. В любом случае отредактированный код ниже проиллюстрирует, как sum()
может упростить ситуацию.
В dice()
при желании функцию можно существенно сократить, используя понимание кортежей. Вы также можете рассмотреть возможность упрощения всего последующего кода, объединив бросок игральных костей и их сумму в небольшой объект. В этом примере что-то очень простое, например namedtuple
может быть хорошим выбором. Обратите внимание, как это изменение упрощает возвращаемый тип dice()
а также очищает код, который должен использовать возвращаемое значение. Также обратите внимание, что это решение имеет непредвиденное преимущество, так как позволяет нам напрямую сравнивать user
и
pc
игра в кости для определения победителя. Это работает, потому что total
атрибут помещается первым в namedtuple
.
У вас уже есть хорошее предложение добавить некоторую проверку пользовательского ввода. Перенеся коллекцию пользовательского ввода в отдельную функцию, вы можете сохранить
main()
сосредоточены на общей оркестровке программы. Общее правило — не допускать подробных вычислений в сценарии. main()
. Эту функцию почти всегда труднее всего тестировать в более сложных программах, поэтому вы должны иметь привычку делать ее алгоритмически простой. Это мышление стоит за
get_result()
функция: пусть какой-нибудь другой фрагмент кода определит победителя и справится с грязной задачей по сборке любого сообщения, которое должно быть напечатано.
Для краткости в этом примере я отбросил большую часть печати (вы должны улучшить по мере необходимости) и строки документации (неплохо сохранить их в реальной программе).
import random
import sys
from collections import namedtuple
Roll = namedtuple('Roll', 'total roll')
def main(args):
while True:
# Get N of dice from user or quit.
n = get_user_input()
if not n:
break
# Roll dice.
user = dice(n)
pc = dice(n)
# Report.
msg = get_result(user, pc)
print(msg)
def get_user_input() -> int:
while True:
prompt="How many dice would you like to roll? "
reply = input(prompt).strip()
try:
return int(reply) if reply else 0
except (ValueError, TypeError):
pass
def dice(n: int) -> Roll:
roll = tuple(random.randint(1, 6) for _ in range(n))
return Roll(sum(roll), roll)
def get_result(user, pc) -> str:
winner = (
'You' if user > pc else
'Bot' if pc > user else
'Tie'
)
return f'Winner: {winner} {user} {pc}'
if __name__ == '__main__':
main(sys.argv[1:])
Я тоже новичок, но мне нравится создавать исключение всякий раз, когда я пытаюсь преобразовать ввод пользователя в целое число. Что-то вроде этого-
while True:
try:
number_of_dices = int(input("How many dices would you like to roll?"
" (0 to quit) >"))
except ValueError:
print("Please enter a number.")