dude12310
dude12310

Reputation: 3

Python - How do I make Rock Paper Scissors run multiple rounds?

Edit: Thank you for all the help!

So I'm in a beginner class, don't have much experience and I've ran into this problem: I'm trying to make the game repeat five times and what I want to happen is

Player inputs choice

Game spits out result

Move onto round 2

Ask for choice again

Game spits out result... etc

What actually ends up happening though is

Player inputs choice

Game spits out result

Move onto round 2

Program asks for choice (I think)

The if/elif is completely disregarded after round 1 as in whatever I input spits no result

Can hit enter five times before program ends

My challenge here is doing this while trying to be as concise as possible because I can do it but the resulting program would be really long and really ugly.

Anyway, to ask a specific question, is it even possible to reuse the same variable five times like this? And why is the if/else completely ignored after round 1?

import random

cpu_choice = ["rock","paper","scissors","dynamite"]

for i in range(5):

    choice = input().lower().strip("!.?")
    cpu_choice = random.choice(cpu_choice)

    if "rock" in choice:
        if cpu_choice == "rock":
            print("It's a tie!")
        elif cpu_choice == "scissors":
            print("Dang, I lost!")
        elif cpu_choice == "paper" or cpu_choice == "dynamite":
            print("Haha! I won!")

    elif "paper" in choice:
        if cpu_choice == "rock":
            print("Dang, I lost!")
        elif cpu_choice == "paper":
            print("It's a tie!")
        elif cpu_choice == "scissors" or cpu_choice == "dynamite":
            print("Haha! I won!")

    elif "scissors" in choice:
        if cpu_choice == "rock":
            print("Haha! I won!")
        elif cpu_choice == "scissors":
            print("It's a tie!")
        elif cpu_choice == "paper" or cpu_choice == "dynamite":
            print("Dang, I lost!")

    elif "dynamite" in choice:
        if cpu_choice == "scissors":
            print("Dang, I lost!")
        elif cpu_choice == "dynamite":
            print("It's a tie!")
        elif cpu_choice == "paper" or cpu_choice == "rock":
            print("Haha! I won!")
    else:
        print("Please use rock, paper, scissors, or dynamite!")
    
    ```

Upvotes: 0

Views: 1436

Answers (6)

CryptoFool
CryptoFool

Reputation: 23119

I initially posted an answer. A few minutes later, there were 4 answers, all saying the same thing. I thought about deleting my answer or just leaving it, but I figured it would be better to offer something more to the asker and the community by providing an enhanced answer.

As the other answers point out, your problem is that you are using the cpu_choice variable for two purposes, and that breaks the logic of your program. You can get more details from the other answers.

One thing you'll learn as you become a better programmer is to recognize when you've got repetition that can be eliminated. We call this the DRY, or "Don't Repeat Yourself" principle. This is an obvious characteristic of your code...there are four blocks of code that are nearly identical, with the only difference being the particular values of some string constants.

In a case like this, you'll learn that you want to parameterize the duplicated code so that you only need one copy of that code. This doesn't only save you time and space on your screen, but it also leads to code that is easier to maintain. If you want to change the logic for how you deal with comparing the values that the user typed in with the computer's choice, you have to make the change in four places. If you had reduced your code down to a single block, you would only then have to make one change.

Here's a version of your code that acts on the DRY principle to reduce the four code blocks down to one. It has a few other enhancements as well. It prompts the user so that they know what to enter. It will play as many rounds as the user wants, and user can quit the game by pressing Return without entering any letters:

import random

# Valid choices, each with a list of what that choice can beat
choices = {"rock":["scissors"],"paper":["rock"],"scissors":["paper" "dynamite"],"dynamite":["scissors"]}

while True:

    print("rock, paper, scissors or dynamite? >", end="")
    user_choice = input().lower().strip("!.?")
    cpu_choice = random.choice(list(choices.keys()))

    if not user_choice:
        # End the program on an empty input
        break
    elif user_choice not in choices:
        # Complain about an invalid choice
        print("That's not a valid input value!")
    else:
        # Show what the computer picked
        print("I picked " + cpu_choice)

        # Do the appropriate thing based on the two choices
        if user_choice == cpu_choice:
            # The two choices were the same
            print("It's a tie!")
        elif cpu_choice in choices[user_choice]:
            # The computer's choice is not in the list of things that the user's choice beats
            print("Haha! I won!")
        else:
            # The computer's choice is in the list of things that the user's choice beats
            # beats, so it must have won
            print("Dang, I lost!")

Here's what a sample run looks like:

rock, paper, scissors or dynamite? >rock
I picked paper
Dang, I lost!
rock, paper, scissors or dynamite? >rock
I picked scissors
Haha! I won!
rock, paper, scissors or dynamite? >paper
I picked paper
It's a tie!
rock, paper, scissors or dynamite? >blah
That's not a valid input value!
rock, paper, scissors or dynamite? >rock
I picked dynamite
Dang, I lost!
rock, paper, scissors or dynamite? >

I hope this helps you by teaching you about the DRY principle!

Upvotes: 1

pakpe
pakpe

Reputation: 5479

You are right. Writing a whole bunch of if/elif statements makes for very ugly code. There is a much more efficient way of designing this game by taking advantage of the circular hierarchy of the moves. If you assign a value to each move as in {'r':0, 'p':1, 'd':2, 's': 3}, you realize that player1 wins if and only if the difference between player1 and player2's score is 1 or 2 or -3. You can use this fact to markedly simplify the code. The following code runs 5 times:

import random

player_dic = {'r':0, 'p':1, 'd':2, 's': 3}
for i in range(5):
    player_letter = input('Enter r or p or d or s: ')
    player_number = player_dic[player_letter]
    computer_choice = random.choice(list(player_dic.items()))

    difference = (computer_choice[1] - player_number)
    print(f'Player: {player_letter}, Computer: {computer_choice[0]}')
    if difference == 0:
        print("It's a tie!")
    elif difference in [1,2,-3]:
        print('Computer wins!')
    else:
        print('Player wins')

Upvotes: 0

Minh-Long Luu
Minh-Long Luu

Reputation: 2731

This two lines of code is contradict:

cpu_choice = ["rock","paper","scissors","dynamite"]

cpu_choice = random.choice(cpu_choice)

When it is the first run, it uses the list, and assign it as a choice from it, take "rock" for example. But the second time, it uses "rock" as choices, not the list you declared earlier. Just change the variable a bit and you are good to go:

Full working code:

import random

choices = ["rock","paper","scissors","dynamite"]

for i in range(5):

    choice = input("Your input: ").lower().strip("!.?")
    cpu_choice = random.choice(choices)

    if "rock" in choice:
        if cpu_choice == "rock":
            print("It's a tie!")
        elif cpu_choice == "scissors":
            print("Dang, I lost!")
        elif cpu_choice == "paper" or cpu_choice == "dynamite":
            print("Haha! I won!")

    elif "paper" in choice:
        if cpu_choice == "rock":
            print("Dang, I lost!")
        elif cpu_choice == "paper":
            print("It's a tie!")
        elif cpu_choice == "scissors" or cpu_choice == "dynamite":
            print("Haha! I won!")

    elif "scissors" in choice:
        if cpu_choice == "rock":
            print("Haha! I won!")
        elif cpu_choice == "scissors":
            print("It's a tie!")
        elif cpu_choice == "paper" or cpu_choice == "dynamite":
            print("Dang, I lost!")

    elif "dynamite" in choice:
        if cpu_choice == "scissors":
            print("Dang, I lost!")
        elif cpu_choice == "dynamite":
            print("It's a tie!")
        elif cpu_choice == "paper" or cpu_choice == "rock":
            print("Haha! I won!")
    else:
        print("Please use rock, paper, scissors, or dynamite!")

Upvotes: 0

Prakash Dahal
Prakash Dahal

Reputation: 4875

Replace cpu_choice to cpu_ch

import random
cpu_ch = ["rock","paper","scissors","dynamite"]

for i in range(5):

    choice = input().lower().strip("!.?")
    cpu_choice = random.choice(cpu_ch)

    if choice == "rock":
        if cpu_choice == "rock":
            print("It's a tie!")
        elif cpu_choice == "scissors":
            print("Dang, I lost!")
        elif cpu_choice == "paper" or cpu_choice == "dynamite":
            print("Haha! I won!")

    elif choice == "paper":
        if cpu_choice == "rock":
            print("Dang, I lost!")
        elif cpu_choice == "paper":
            print("It's a tie!")
        elif cpu_choice == "scissors" or cpu_choice == "dynamite":
            print("Haha! I won!")

    elif choice == '"scissors':
        if cpu_choice == "rock":
            print("Haha! I won!")
        elif cpu_choice == "scissors":
            print("It's a tie!")
        elif cpu_choice == "paper" or cpu_choice == "dynamite":
            print("Dang, I lost!")

    elif choice == "dynamite":
        if cpu_choice == "scissors":
            print("Dang, I lost!")
        elif cpu_choice == "dynamite":
            print("It's a tie!")
        elif cpu_choice == "paper" or cpu_choice == "rock":
            print("Haha! I won!")
    else:
        print("Please use rock, paper, scissors, or dynamite!")

Upvotes: 0

ScienceSnake
ScienceSnake

Reputation: 617

You're using cpu_choice for two different things. The first time, its a list of potential choices that the cpu has. But then you redefine it to be the outcome that the cpu has actually chosen. This means (say the cpu picked rock in the first iteration) that in the second one you have '''cpu_choice = random.choice("rock")''', and because python treats strings as lists, it will output "r" "o" "c" or "k". You don't get an error message for that, because you have no else statement in your inner if statements.

Just rename your second line to potential_choices and it will be fine.

Upvotes: 0

Toby Maguire
Toby Maguire

Reputation: 154

The problem with your code is this line: cpu_choice = random.choice(cpu_choice).you choose an object from the list , then you save it in the cpu_choice itself.

In other words after the first round you dont have access to the cpu_choice itself,because you overwrited it last round. the trick is simple; change variable name:

import random

cpu_choice2 = ["rock","paper","scissors","dynamite"]

for i in range(5):

    choice = input().lower().strip("!.?")
    cpu_choice = random.choice(cpu_choice2)

    if "rock" in choice:
        if cpu_choice == "rock":
            print("It's a tie!")
        elif cpu_choice == "scissors":
            print("Dang, I lost!")
        elif cpu_choice == "paper" or cpu_choice == "dynamite":
            print("Haha! I won!")

I just added a 2 to your cpu_list name.

Upvotes: 0

Related Questions