Orange
Orange

Reputation: 1

Is there a better way to pick a winner for rock paper scissors?

Learning python casually, and decided to give rock paper scissors a go as a quick project. Went pretty smooth, but I got really caught up in the process of trying to shorten the code you use to compare the results.

def check_results(ai, self):
    if ai == self:
        return 'tralf'
    if self == 'rock':
        if ai == 'paper':
            return False
        else:
            return True
    if self == 'scissors':
        if ai == 'rock':
            return False
        else:
            return True
    if self == 'paper':
        if ai == 'scissors':
            return False
        else:
            return True

ai and self, as you can probably guess, are the computers pick and the players pick just being passed in.

Something about having to hard code this was very very unsatisfying to me, and I spent about 20 minutes sort of refusing to do it, and just trying out random stuff to see if I could shorten it.

The one thing I tried was to involve something where you get the index of both players choice from a list, and use that to compare them by running it through a separate list. Couldn't get it to work, or at least couldn't get it to work in a way that was better than just hard coding it, so I gave up and did it the boring way. Any help would be appreciated.

Upvotes: 0

Views: 214

Answers (3)

martiangoblin
martiangoblin

Reputation: 109

My solution to my son’s school assignment. Had a couple of extra requirements: You must declare the winner, and you must use a descriptive verb to state the outcome of the contest.

all_wins = {
    ("rock", "scissors"): "crushes",
    ("paper", "rock"): "covers",
    ("scissors", "paper"): "cuts"
}

def result_string(player_a, player_b):
    if player_a == player_b:
        return f"Both did {player_a}. They tied."
    elif (player_a, player_b) in all_wins:
        verb = all_wins[(player_a, player_b)]
        return f"{player_a} {verb} {player_b}! player A wins."
    else:
        verb = all_wins[(player_b, player_a)]
        return f"{player_b} {verb} {player_a}! player B wins."

Test:

choices = ["rock", "paper", "scissors"]
for aaa in choices:
    for bbb in choices:
        print(result_string(aaa, bbb))

Gives:

Both did rock. They tied.
paper covers rock! player B wins.
rock crushes scissors! player A wins.
paper covers rock! player A wins.
Both did paper. They tied.
scissors cuts paper! player B wins.
rock crushes scissors! player B wins.
scissors cuts paper! player A wins.
Both did scissors. They tied.

Upvotes: 0

rdas
rdas

Reputation: 21285

Here's a solution using python 3.10's match-case (pattern-matching):

def check_results(ai, self):
    if ai == self:
        return 'tralf'
    match (ai, self):
        case ('scissor', 'paper') | ('paper', 'rock') | ('rock', 'scissor'):  # cases where you lose
            return False
        case ('scissor', 'rock') | ('paper', 'scissor') | ('rock', 'paper'):  # cases where you win
            return True


print(check_results('rock', 'rock'))
print(check_results('rock', 'paper'))
print(check_results('paper', 'rock'))
print(check_results('rock', 'scissor'))

Result:

tralf
True
False
False

Upvotes: 0

Paul M.
Paul M.

Reputation: 10809

At the cost of readability and error-checking, something like this maybe:

def did_player_win(player_choice, computer_choice):
    choices = ['scissors', 'paper', 'rock']
    # The order in which the strings appear in the list is important.
    # scissors beats paper
    # paper beats rock
    # rock beats scissors (wraps around)

    return choices[(choices.index(player_choice) + 1) % len(choices)] == computer_choice

player_choice = 'paper'
computer_choice = 'rock'
print(did_player_win(player_choice, computer_choice))

That doesn't make for great source code though. There's no shame in being verbose (future self will thank you:)

def did_player_win(player_choice, computer_choice):
    choices = {
        'rock': 'scissors',
        'paper': 'rock',
        'scissors': 'paper'
    }

    return choices[player_choice] == computer_choice

Upvotes: 1

Related Questions