Игра в угадывание чисел для начинающих

Sep 01 2020

Я начал учиться программировать, и в качестве первой программы, которую я написал сам, я хотел придумать игру по угадыванию чисел - вот что у меня получилось.

В основном я ищу обзор своей Guessфункции, но у меня есть несколько конкретных вопросов:

  1. Имеет ли смысл использовать переменную цикла в качестве параметра функции?
  2. В настоящее время я определяю некоторые переменные (например tries) вне моей функции - это идиоматический способ сделать это?
import random
tries = [1]
def Guess(playing):
    number = random.randint(1,100)
    print(number)
    print("We are going to play high and low, the avabile numbers are from 1 to 100 included.")
    while playing == True:
        user_input = input("What is your number? ")
        if int(user_input) == number:
            print("You have won!")
            playing = False
        elif int(user_input) < number:
            print("You need to give a higher number")
            tries.append(1)
        elif int(user_input) > number:
            print("You need to give an lower number")
            tries.append(1)
        else:
            print("You have put an wrong number")
            playing = False
    print("It took you " + str(sum(tries)) + " turns to guess")
    still = input("Do you want to play again?")
    if still == "yes" or still == "YES" or still == "y" or still == "si":
        Guess(playing=True)
    else:
        playing=False

Guess(playing=True)

Ответы

8 IEatBagels Sep 01 2020 at 21:02

В целом вы хорошо поработали со своим кодом, есть пара вещей, на которые я обращаю внимание:

  • Вы не платите за пробелы! Я имею в виду, что важно дать вашему коду возможность дышать. Используйте несколько пустых строк, это будет чудо для ваших глаз при работе с большими фрагментами кода.
  • Почему triesмассив? На мой взгляд, triesэто должно быть количество попыток, поэтому это должно быть число!
  • Обратите внимание, что у вас есть условия. ==, <, > and... ?Скажем, я прошу вас дать мне число, которое не равно, не меньше или не больше 3. Есть ли возможный вариант? Вместо этого вы должны убедиться, что игрок ввел число! Прямо сейчас, если бы я ответил: «Я не знаю своих чисел, я всего лишь ребенок» на «Мы будем играть по высоким и низким, допустимые числа от 1 до 100 включительно», ваша программа выйдет из строя. ! Вы должны изучить try/catchблоки, чтобы решить эту проблему, это может стать для вас следующим уроком!
  • Скажем, мне нужно три попытки для моего первого прохождения, затем я запускаю новую игру (используя «да» при появлении запроса), и я могу добиться успеха с первой попытки, ваш код скажет мне, что мне нужно четыре попытки для успеха. Вы можете узнать, почему и как это исправить?
  • Вы можете упростить свой цикл, используя breakключевое слово, это тоже то, что вам следует искать (пока мы на нем, попытайтесь понять использование break, returnи continue. Эти три ключевых слова очень полезны, хотя вы, вероятно, уже знаете о них return).
  • Что, если я специализируюсь на английском и не могу терпеть грамматические ошибки (это, очевидно, не мой случай), и я пишу «Да» вместо «да» или «ДА», когда меня спрашивают, хочу ли я играть снова? Что вы можете сделать, так это сравнить уменьшенную (или расширенную ) версию ввода с тем, что вы хотите проверить (например still.lower() == "yes").
1 ChristianDean Sep 02 2020 at 08:55

Вот несколько улучшений, которые, я думаю, вы могли бы сделать (IEatBabels коснулся многих из них, но я хотел бы расширить некоторые области и добавить свою формулировку):

  • Почему triesсписок? Было бы проще и разумнее просто позволить tries = 0начать, а затем увеличивать try ( tries += 1) каждый раз, когда пользователь вводит неправильное число.
  • Поскольку в вашей программе нет других функций, я бы даже не стал беспокоиться о создании Guessфункции. Просто напишите код прямо в программе.
  • Вы , возможно, только что отладки программы, но вы показываете пользователю номер они должны угадать, написав print(number)в Guess!
  • Что произойдет, если пользователь решит проявить дерзость и произнести какую-то тарабарщину (то есть что-то, что не является числом)? Ваша программа вызовет исключение, когда попытается преобразовать ввод в число. Что вам нужно сделать, так это обернуть код под вашим циклом в try/exceptблок. Таким образом, всякий раз, когда пользователь вводит тарабарщину, вы можете предложить ему ввести действительное число.
  • Я не уверен, почему у вас elseблок после ваших if/elifзаявлений? Если пользовательский ввод не равен числу, не меньше числа и не больше числа, что еще это может быть? Ничего! Так что здесь действительно нет необходимости в elseзаявлении. Возможно, вы пытались использовать elseоператор в тех случаях, когда пользовательский ввод был недействительным. Однако это не совсем сработает. Если это то, что вы пытались сделать, см. Мой последний пункт.
  • Преобразуйте пользовательский ввод в целое число один раз и сохраните его в переменной. Это экономит время и выглядит чище, чем преобразование пользовательского ввода каждый раз, когда вы хотите его протестировать.
  • Я не уверен, почему вы здесь используете рекурсию? Рекурсия является отличным инструментом, но часто whileили forпетли работать гораздо лучше. Думаю, ваша программа - один из таких случаев. Просто используйте два цикла - один цикл для запроса пользователя, хотят ли они снова сыграть, и один цикл для самой игры.
  • Я заметил, что вы использовали флаги, чтобы вырваться из наших петель. Это прекрасный метод. Но я бы предпочел здесь просто использовать break. break- это инструкция, которая сообщает Python немедленно выйти из цикла, в котором он в данный момент находится. Он имеет тот же эффект, что и установка флагов на Trueи / или False.
  • Вы неплохо справились с этим в своей программе, но всегда старайтесь использовать описательные имена переменных и писать понятный, явный код. Это делает ваш код чистым и самодокументируемым, а также позволяет вернуться к нему через несколько месяцев и быстро понять, что он делает и как работает.

Вот как я бы переписал вашу программу с учетом приведенных выше предложений и некоторых улучшений форматирования, логики и именования (также IEatBagels отлично зарекомендовал себя в отношении пробелов. Убедитесь, что вы приняли это близко к сердцу!):

import random


print("We are going to play high and low, the avabile numbers are from 1 to 100 included.")

tries = 0
while True:
    number_to_guess = random.randint(1, 100)
    while True:
        try:
            user_input = input("What is your number? ")
            guess = int(user_input)
        except ValueError:
            print("That's not a valid number! Try again.")
        else:
            if guess == number_to_guess:
                print("You have won!")
                break
            elif int(user_input) < number_to_guess:
                print("You need to give a higher number")
                tries += 1
            elif int(user_input) > number_to_guess:
                print("You need to give a lower number")
                tries += 1

    print("It took you " + str(tries) + " turns to guess")
    still = input("Do you want to play again?")

    if not (still == "yes" or still == "YES" or still == "y" or still == "si"):
        break