Невозможно проверить ввод данных пользователем в игре - PullRequest
0 голосов
/ 29 мая 2020

Я создаю игру «камень, ножницы, бумага». Я хочу, чтобы он был лучшим из 3 совпадений и имел возможность проверять вводимые пользователем данные. У меня постоянно возникают проблемы с вводом данных пользователем. Я пробовал несколько вариантов, но, похоже, не могу понять. Я знаю, что мой код, вероятно, беспорядочный, поэтому мы будем очень признательны за любые комментарии о том, как его очистить. Большое спасибо за ваше время.

import random
import sys
import time

print("Hello and welcome to the Rock, Paper, Scissors tournament.\n"
      "The tournament will be the best of 3 wins.\n"
      "It will be you against our highly intelligent computer opponent.\n"
      "Good luck!")


# Create a function for the game
def play_game():
    user_count = 0
    comp_count = 0
    tie_game = 0

    while comp_count < 2 and user_count < 2:
        user_choice = (int(input("-------------------------------------------"
                             "\nEnter choice by typing 1 2 or 3: \n 1. Rock \n 2. paper \n 3. scissor \n"
                             "-------------------------------------------\n")))
        if user_choice == 1:
            user_choice_name = 'Rock'
        elif user_choice == 2:
            user_choice_name = 'Paper'
        elif user_choice == 3:
            user_choice_name = 'Scissor'
        else:
            print("Please pick a valid number")


        print(f"\nYou have chosen: {user_choice_name}")
        print("\nNow it's the computer's turn to pick......")
        time.sleep(3)

        comp_choice = random.randint(1, 3)

        if comp_choice == 1:
            comp_choice_name = 'Rock'
        elif comp_choice == 2:
            comp_choice_name = 'Paper'
        else:
            comp_choice_name = 'Scissor'

        print(f"\nComputer has chosen: {comp_choice_name}\n")

        if user_choice == 1 and comp_choice == 2:
            comp_count += 1
            print("Computer wins this round with Paper! "
                  f"\n Computer: {comp_count}"
                  f"\n You: {user_count} \n\n")

        elif user_choice == 1 and comp_choice == 3:
            user_count += 1
            print("You win this round with Rock!"
                  f"\n Computer: {comp_count}"
                  f"\n You: {user_count} \n\n")

        elif user_choice == 2 and comp_choice == 1:
            user_count += 1
            print("You win this round with Paper!"
                  f"\n Computer: {comp_count}"
                  f"\n You: {user_count} \n\n")

        elif user_choice == 2 and comp_choice == 3:
            comp_count += 1
            print("Computer wins this round with Scissor!"
                  f"\n Computer: {comp_count}"
                  f"\n You: {user_count} \n\n")

        elif user_choice == 3 and comp_choice == 2:
            user_count += 1
            print("You win this round with Scissor!"
                  f"\n Computer: {comp_count}"
                  f"\n You: {user_count} \n\n")

        elif user_choice == 3 and comp_choice == 1:
            user_count += 1
            print("Computer wins this round with Rock!"
                  f"\n Computer: {comp_count}"
                  f"\n You: {user_count} \n\n")

        else:
            if user_choice == comp_choice:
                tie_game += 1
            print(f"This round was a tie! Both choosing {user_choice_name}, try again!"
                  f"\n Computer: {comp_count}"
                  f"\n You: {user_count} \n\n")
    else:
        print(f'The game is now over with a score of: \n You:{user_count} \n to \n Computer:{comp_count}')
        again = str(input("Do you want to play again, type 'yes' or 'no' \n"))
        if again.lower() == "no":
            print('Thank you for playing!')
            sys.exit()
        else:
            play_game()


play_game()

1 Ответ

0 голосов
/ 29 мая 2020

Так как у меня было несколько минут, чтобы убить чашечкой кофе, вот перезапись вашей программы с кучей улучшений, проверка, о которой вы спрашивали, и несколько советов по стилю кодирования:

import random
import time

print("Hello and welcome to the Rock, Paper, Scissors tournament.\n"
      "The tournament will be the best of 3 wins.\n"
      "It will be you against our highly intelligent computer opponent.\n"
      "Good luck!")

# to avoid repeating these values over and over and changing numbers in to string,
# just defining them here. Name in capitals because it's global (generally bad)
# an even nicer solution would be to write a Game() class and put everything in
# there, but it would be a bit more advanced
RSP_OPTIONS = {
    1: 'Rock',
    2: 'Scissor',
    3: 'Paper'
}


def get_user_choice():
    # keep asking until a valid value is returned
    while True:
        # this is a bit fancy, but let's say you want to reuse the game for similar games
        # with different options from rock, scissor, paper, you'd want this code to still work

        # get a list of string versions of the numbers
        numbers = list(map(str, RSP_OPTIONS.keys()))
        # join them together like you presented them: 1, 2 or 3
        options = ', '.join(numbers[:-1]) + ' or ' + numbers[-1] + ':\n'
        # add the descriptions
        options = options + ''.join(f'{n}: {name}\n' for n, name in RSP_OPTIONS.items())
        try:
          user_choice = (int(input("-------------------------------------------\n"
                                   f"Enter choice by typing {options}"
                                   "-------------------------------------------\n")))
        except ValueError:
            # any invalid option
            user_choice = -1
        # check if it's one of the valid options
        if user_choice in RSP_OPTIONS:
            return user_choice
        else:
            # it makes sense to generate a new line where you want it, instead of having
            # to put new line characters at the start of other strings
            print("Please pick a valid number\n")


def beats(choice1, choice2):
    # choice1 beats choice2 if it's one greater, except when choice2 == 3 and choice1 == 1
    # but to make it even nicer and have it work for other similar games, you could say
    # "except when choice1 == the max choice and choice2 == the min choice"
    return (choice2 - choice1 == 1 or
            (choice1 == max(RSP_OPTIONS.keys()) and choice2 == min(RSP_OPTIONS.keys())))


# Create a function for the game
def play_game():
    user_count = 0
    comp_count = 0
    tie_game = 0

    # this is what you really want, best out of three, ties not counted?
    while comp_count + user_count < 3:
        user_choice = get_user_choice()

        print(f"You have chosen: {RSP_OPTIONS[user_choice]}\n")
        print("Now it's the computer's turn to pick......\n")
        # this wait is not very nice, the user might try to hit enter or something
        # you could consider printing the countdown, or telling the user to please wait
        # even then, it's kind of silly to pretend the computer has to work hard here
        time.sleep(3)

        # this choice is always valid, so no problem
        comp_choice = random.randint(1, 3)
        # note that you don't need the name, you can just look it up whenever in RSP_OPTIONS
        print(f"\nComputer has chosen: {RSP_OPTIONS[comp_choice]}\n")

        # getting rid of some repetition, note how the code really reads like what is intended
        if beats(comp_choice, user_choice):
            comp_count += 1
            # nice to also say what really beat them
            print(f"Computer wins this round with {RSP_OPTIONS[comp_choice]} over {RSP_OPTIONS[user_choice]}!\n")
        elif beats(user_choice, comp_choice):
            user_count += 1
            print(f"You win this round with {RSP_OPTIONS[user_choice]} over {RSP_OPTIONS[comp_choice]}!\n")
        else:
            # you can only get here on a tie
            tie_game += 1
            print(f"This round was a tie! Both choosing {RSP_OPTIONS[user_choice]}, try again!\n")
        # you always print this, so just do it after the options:
        print(f"Computer: {comp_count}\n"
              f"You: {user_count}\n\n")
    else:
        print(f'The game is now over with a score of:\n You:{user_count}\n to\n Computer:{comp_count}\n')
        again = str(input("Do you want to play again, type 'yes' or 'no' \n"))
        # let's quit on anything starting with n
        if again.lower()[0] == "n":
            print('Thank you for playing!\n')
            # instead of exiting hard, maybe just return, telling the caller we don't want to play again
            return False
        else:
            # you were calling play_game again, but that causes the game to get more and more calls
            # on top of each other, ultimately reaching an error state
            # by returning first and then calling again, you avoid that problem
            return True


# the function returns whether it should play again
while play_game():
    pass
# once it leaves the loop, the game stops automatically here, no more code

Однако есть еще много возможностей для улучшения; попробуйте реализовать более продвинутые формы RSP или сделать компьютер более умным, чем просто случайное воспроизведение, но пусть он использует какую-нибудь стратегию, возможно, с небольшой примесью случайности.

И с точки зрения кода, попробуйте отделение игры от того, как она представлена ​​на экране; что, если вы решили сделать это в Интернете, а не на консоли или в графическом окне? Вы также можете подумать о том, чтобы поместить весь код в красивый класс, избавившись от глобальных переменных и позволяя создавать больше копий игры по мере необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...