7
\$\begingroup\$

I'm new to programming and I'm trying to teach myself Python through some online books.

One of the exercises has me making a Rock Paper Scissors game. The one I have written works well enough I think, but I was wondering if there were more efficient ways of writing the code, perhaps something shorter.

I'm using Python 3.4.3 IDLE GUI.

 import random
#variables
done = False
comp = random.randrange(1,4)
#start
print("Lets play rock, paper, scissors! Choose numbers 1-3 only please.")
print()
#begin loop
while not(done):
#computer vs input
 guess = int(input("1. Rock 2. Paper 3. Scissors "))
 if comp == 1 and guess == 3:
 print("Rock beats scissors, too bad!")
 elif comp == 2 and guess == 1:
 print("Paper beats rock, tough luck!")
 elif comp == 3 and guess == 2:
 print("Scissors me timbers! Scissors cuts paper! You lose.")
 elif guess == 1 and comp == 3:
 print("Rock beats scissors, you beat me!")
 elif guess == 2 and comp == 1:
 print("You win! Paper beats rock.")
 elif guess == 3 and comp == 2:
 print("Scissor cuts paper, you win!")
 else:
 print("It's a draw!")
#continue 
 stop = input("Do you want to quit? ")
 if stop.lower() == "y" or stop.lower() == "yes":
 done = True
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Oct 3, 2015 at 6:22
\$\endgroup\$
0

2 Answers 2

7
\$\begingroup\$

Looping

Rather than setting a done flag and looping while not(done): (note: this would usually be written as simply while not done:), you could use a formulation more like:

while True:
 # do things
 if loop_should_end:
 break

This removes the need for the flag and makes the loop easier to follow.

Logic

At present, comp is set outside the loop, so the computer will always guess the same thing. This makes it rather too easy to win - you should move comp = random.randint(1, 4) (note whitespace) inside the loop.

Comparisons

The most obvious tweak is that the canonical replacement for lots of elifs in Python is a dictionary. In this case, you could look up a tuple (comp, guess) and print the result:

RESULTS = {
 (1, 3): "Rock beats scissors, too bad!",
 (2, 1): "Paper beats rock, tough luck!",
 ...
}

then access this inside the loop as easily as:

print(RESULTS.get((comp, guess), "It's a draw!"))

You could also simplify:

stop = input("Do you want to quit? ")
if stop.lower() == "y" or stop.lower() == "yes":

to:

if input("Do you want to quit? ").lower() in {"y", "yes"}:

Validation

You currently have no input validation, so the program could crash with a ValueError if the user types 'scissors' instead of 3. See e.g. "Asking the user for input until they give a valid response" for guidance on this.

Structure

Finally, it is bad practice to have all of your code running at the top level of the script - it makes it much more difficult to re-use later. Instead, I would do something like:

import random
RESULTS = {...} # possible outcomes
def get_int_input(...):
 """Take valid integer input from user."""
 ...
def game_loop(...):
 """Main game loop."""
 ...
if __name__ == '__main__':
 game_loop()

This will work exactly the same if you run the script directly (see "What does if __name__ == "__main__": do?") but allows you to use e.g. from wherever import get_input_int elsewhere, simplifying reuse and encouraging modular design.

answered Oct 3, 2015 at 8:44
\$\endgroup\$
2
  • \$\begingroup\$ Why use a set for in {"y", "yes"} and not a tuple? \$\endgroup\$ Commented Oct 5, 2015 at 13:37
  • 1
    \$\begingroup\$ @SuperBiasedMan membership testing on a set is O(1), vs. O(n) on a tuple - I doubt it makes any difference with two items, but it's good practice \$\endgroup\$ Commented Oct 5, 2015 at 13:42
2
\$\begingroup\$

If you want to add an extra empty line to the print output, use the newline character \n, so instead of

print("Lets play rock, paper, scissors! Choose numbers 1-3 only please.")
print()

use this

print("Lets play rock, paper, scissors! Choose numbers 1-3 only please.\n")

Also you don't need most of those comments. Anyone who can read your code at all can tell what's a variable and where the loop starts. Use comments to explain the context of more abstract reasons for things. If it was unclear, you could comment

# comp will randomly pick the computer's move

The other time to use comments is when code is complicated to parse or hard to read and understand what it's actually doing, like if it you had an algorithm for determining the computer's move. That wouldn't be as clear without a comment.

answered Oct 5, 2015 at 13:46
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.