falconed
falconed

Reputation: 39

Rock, paper, scissors game does not loop as intended

I'm new to python (and coding for that matter) and am going through a rock, paper, scissors exercise. After the second game my code below does not ask me if I want to play another, instead it automatically calls the game function. Does anyone know where I could be going wrong?

import sys

print("Welcome to rock, paper, scissors!")

player_a = input("Player A input one of the following; rock, paper or scissors: ")
player_b = input("Player B input one of the following; rock, paper or scissors: ")

def game(p1, p2):
    if p1 == p2:
        print("It is a draw!")
    elif p1 == "rock" and p2 == "scissors":
        print("Player A wins!")
    elif p1 == "rock" and p2 == "paper":
        print("Player B wins!")
    elif p1 == "paper" and p2 == "rock":
        print("Player A wins!")
    elif p1 == "paper" and p2 == "scissors":
        print("Player B wins!")
    elif p1 == "scissors" and p2 == "rock":
        print("Player A wins!")
    elif p1 == "scissors" and p2 == "paper":
        print("Player B wins!")

game(player_a, player_b)

playAgain = input("Would you like to play again? (Insert Y or N): ")

while playAgain == "Y":
    player_a = input("Player A input one of the following; rock, paper or scissors: ")
    player_b = input("Player B input one of the following; rock, paper or scissors: ")
    game(player_a, player_b)
else:
    print("Thanks for playing!")
    sys.exit()

Upvotes: 2

Views: 317

Answers (3)

John Coleman
John Coleman

Reputation: 51998

A couple of points on your code:

1) I for one can almost never spell "scissors" correctly. It might make the game more playable if the main function is just expecting 'r', 'p', or 's', so why not just pass the first letters of the inputs to game()? Something like:

player_a = input("Player A input one of the following; rock, paper or scissors: ")
payer_a = player_a.strip().lower()[0]

and similarly for player_b.

2) I always visualize rock-paper-scissors as a loop:

    R
  /  \
 S -- P

Every possibility is defeated by the item which is in the clockwise direction, and whether or not player_2 is in the clockwise direction from player_1 can be determined via modular arithmetic:

def game(p1,p2):
    if p1 == p2:
        print("It is a draw!")
    else:
        i = "rps".index(p1)
        if "rps"[(i+1)%3] == p2:
            print("Player B wins!")
        else:
            print("Player A wins!")

This way you avoid the proliferation of cases. Furthermore, this sort of thing scales more easily if you want to expand the game to "rock-paper-scissors-Spock-lizard" of Big Bang (the show, not the origin of the universe) fame. Modular arithmetic on indices is the way to go (though "rock-paper-scissors-Spock-lizard" requires a bit more than simple direction).

Upvotes: 2

PM 2Ring
PM 2Ring

Reputation: 55479

You just need to ask the "play again?" question inside your loop.

An important principle of coding is DRY: Don't Repeat Yourself. By a tiny bit of reorganization we can get rid of some repetition in your code.

In the code below we pretend that at the start of the program the user has already answered "Y" to the "play again?" question.

print("Welcome to rock, paper, scissors!")

def game(p1, p2):
    if p1 == p2:
        print("It is a draw!")
    elif p1 == "rock" and p2 == "scissors":
        print("Player A wins!")
    elif p1 == "rock" and p2 == "paper":
        print("Player B wins!")
    elif p1 == "paper" and p2 == "rock":
        print("Player A wins!")
    elif p1 == "paper" and p2 == "scissors":
        print("Player B wins!")
    elif p1 == "scissors" and p2 == "rock":
        print("Player A wins!")
    elif p1 == "scissors" and p2 == "paper":
        print("Player B wins!")

playAgain = "Y"
while playAgain == "Y":
    player_a = input("Player A input one of the following; rock, paper or scissors: ")
    player_b = input("Player B input one of the following; rock, paper or scissors: ")
    game(player_a, player_b)
    playAgain = input("Would you like to play again? (Insert Y or N): ")
else:
    print("Thanks for playing!")

Note that there's no need to call sys.exit(), we can just let the program terminate naturally.


We can also condense the game function considerably. If it's not a draw, and A doesn't win, then B must win. So we don't need to do all those B tests. And we can combine the A tests into a single test, using the or operator.

def game(p1, p2):
    if p1 == p2:
        print("It is a draw!")
    elif ((p1 == "rock" and p2 == "scissors") 
        or (p1 == "paper" and p2 == "rock")
        or (p1 == "scissors" and p2 == "paper")):
        print("Player A wins!")
    else:
        print("Player B wins!")

A more advanced (and slightly more Pythonic) way to do the test is to use tuples:

def game(p1, p2):
    if p1 == p2:
        print("It is a draw!")
    elif (p1, p2) in (("rock", "scissors"), ("paper", "rock"), ("scissors", "paper")):
        print("Player A wins!")
    else:
        print("Player B wins!")

Upvotes: 5

Ben
Ben

Reputation: 1291

Or

while True:
    if input("Would you like to play again? (Insert Y or N): ") == "Y":
        player_a()
        player_b()
    else:
        print('thanks for playing')
        break

Upvotes: 1

Related Questions