Python Forum
Roshambo with only 1 if switch
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Roshambo with only 1 if switch
#10
(Jan-25-2019, 09:30 AM)perfringo Wrote: Instead of verbose dictionary one can combine Python indices and % with some math.

We order elements so that next beats previous:

>>> choices = ['Rock', 'Paper', 'Scissors']
The problem is, that 'previous' to 'Rock' should be 'Scissors' which is actually last in list. Winning combinations using indices are:

0 -> 2 (Rock beat Scissors)
1 -> 0 (Paper beat Rock)
2 -> 1 (Scissors beat Paper)

As length of choices is 3 then we can use Python % to do something like that:

0 -> 2 ---> (0 - 2) % 3 -> (2 - 0) % 3 ---> 1 -> 2 ---> 1 beats 2
1 -> 0 ---> (1 - 0) % 3 -> (0 - 1) % 3 ---> 1 -> 2 ---> 1 beats 2
2 -> 1 ---> (2 - 1) % 3 -> (1 - 2) % 3 ---> 1 -> 2 ---> 1 beats 2

This means that winning side (i.e 'previous') returns 1 and loosing side (i.e 'next') returns 2. You can test it to hold true with the opposite as well (loosing combinations are 2 -> 0, 0 -> 1 and 1 -> 2)

% with negative numbers:

>>> (0 - 2) % 3
1
>>> (0 - 1) % 3
2
>>> (1 - 2) % 3
2
So we can do something like (no data validation applied, just to show how to use previous principle to determine winner):

>>> choices = ['Rock', 'Paper', 'Scissors'] 
>>> user_choice = # get user choice and return corresponding index in choices
>>> computer_choice = random.choice(range(3))  # or random.choice(len(choices))
>>> if user_choice == computer_choice:
...     # draw
>>> elif (user_choice - computer_choice) % 3 < (computer_choice - user_choice) % 3:
...     # user wins
... else:
...     # computer wins

import random

moves = {"Rock": 0, "Paper": 1, "Scissors": 2}
results = {-1: "Lose", 0: "Draw", 1: "Win"}
score = 0
while True:
    print("\nPaper, Rock, Scissors, or Quit")
    user_choice = input("Please enter your choice: ").title()
    if user_choice == "Quit":
        break
    computer_choice = random.choice(list(moves))
    try:
        if user_choice != computer_choice:
            if moves[user_choice]%3 > moves[computer_choice]%3:
                result = 1
            else:
                result = -1
        else:
            result = 0
        score += result
        print(f"User choice: {user_choice}, Computer choice: {computer_choice}, You {results[result]}, Score: {score}")
    except KeyError:
        print("Invalid Entry")
input(f"Final score: {score}")
Here is the application of all of the suggestions. I have to say that unless there is a tremendous speed gain or space savings that the mod(3) solution sacrifices readability. I'm going to try a different approach but I don't think I'm a fan of it.
Reply


Messages In This Thread
Roshambo with only 1 if switch - by Clunk_Head - Jan-24-2019, 10:28 PM
RE: Roshambo with only 1 if switch - by ichabod801 - Jan-24-2019, 11:55 PM
RE: Roshambo with only 1 if switch - by Clunk_Head - Jan-25-2019, 12:02 AM
RE: Roshambo with only 1 if switch - by buran - Jan-25-2019, 08:20 AM
RE: Roshambo with only 1 if switch - by Clunk_Head - Jan-26-2019, 06:16 PM
RE: Roshambo with only 1 if switch - by perfringo - Jan-25-2019, 09:30 AM
RE: Roshambo with only 1 if switch - by Clunk_Head - Jan-27-2019, 03:19 AM
RE: Roshambo with only 1 if switch - by buran - Jan-25-2019, 09:37 AM
RE: Roshambo with only 1 if switch - by perfringo - Jan-25-2019, 11:48 AM
RE: Roshambo with only 1 if switch - by buran - Jan-26-2019, 06:56 PM
RE: Roshambo with only 1 if switch - by perfringo - Jan-27-2019, 09:02 AM
RE: Roshambo with only 1 if switch - by Clunk_Head - Jan-27-2019, 10:19 PM
RE: Roshambo with only 1 if switch - by perfringo - Jan-28-2019, 08:59 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  switch to python3 Skaperen 0 2,195 Jul-03-2018, 12:55 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020