2
votes

So, I'm making this game in python. The thing is, in scissors, paper and rock there can be different combinations like .. Rock and paper, Rock and scissors, and so on. So how would I make this without doing heaps of elif statements.

import random
random_choice = ["Scissors", "Paper", "Rock"][random.randint(0, 2)]

player_input = raw_input("What's your choice (Scissors, Paper, or Rock)")
if player_input not in ["Scissors", "Paper", "Rock"]:
      print("Not valid choice")
      raw_input()
      exit()

if player_input == random_choice:
      print("You both choose %s" % random_choice)
elif player_input == "Rock" and random_choice == "Scissors":
      print("You picked Rock and the bot picked Scissors, you win!")
      raw_input()
#And so on making heaps of elif's for all the combinations there can be.

So how do we make this game without having to do so many elif statements or type less code. Surely there has to be a better programming sequence for dealing with these types of things?

2
if "Scissors" or "Paper" or "Rock" not in player_input won't do what you expect it to. - Tim
Your first guard against rogue user input will immediately return 'Scissors', you probably want player_input not in ['Scissors', ...]. I'd also wrap it in a loop so when the user keeps giving you garbage input you keep asking for what you want (right now, if the if was correct) you only ask twice. - Nick T
I keep seeing this question over and over on SO. I have answered it in the past but only to find the question deleted but now wonder if it is straight out of a programming assignment - Spade
No, I just want to know how big companies would deal with these things when they have a lot of combinations in a game. - user3818650
@user3818650 They would often convert the inputs to numbers - and work out the winning input based on numbers - or they would use a table or similar data structure to help work out the combinations. I doubt they would hand code every possible combination and ever possible test. - Tony Suffolk 66

2 Answers

2
votes

If you want to avoid the elif tree, you may use a set to store all the winning combinations:

import random

# random.choice is a convenient method
possible_choices = ["Scissors", "Paper", "Rock"]
random_choice = random.choice(possible_choices)

# set notation, valid since Python 2.7+ and 3.1+ (thanks Nick T)
winning = {("Scissors", "Paper"), ("Paper", "Rock"), ("Rock", "Scissors")}

player_input = raw_input("What's your choice (Scissors, Paper, or Rock)")
if player_input not in possible_choices:
      print("Not valid choice.")
      raw_input()

if player_input == random_choice:
      print("You both choose %s" % random_choice)
elif (player_input, random_choice) in winning:
      print("You picked %s and the bot picked %s, you win!" % (player_input, random_choice))
else:
      print("You picked %s and the bot picked %s, you lose!" % (player_input, random_choice))

raw_input()
1
votes

How about doing a map of possible results:

a_beats_b = {('Scissors', 'Paper'): True,
             ('Scissors', 'Rock'):  False,
             ...

(Note that keys must be tuples). And then do a lookup with like this:

player_wins = a_beats_b[(player_input, random_choice)]

You'll need to handle the case of the same choices (as you already do).