Snarre
Snarre

Reputation: 597

Simulate several rounds of rock, paper and scissors

I am trying to implement a function that takes an integer n and simulates n rounds of Rock, Paper, Scissors between players Player 1 and Player 2. The player who wins the most rounds wins the n-round game, with ties possible. The function should print the result of the game as shown.

    >>> simul(1)
    Player 1
    >>> simul(1)
    Tie
    >>>simul(100)
    Player 2

I think I need to approach this in a modular fashion. In other words, I need to combine at least 2 functions, my problem is that I can't seem to figure out how to do that. How can I activate the result from an embedded function when calling the simul() function?

So I have created a function that simulates the game Rock, Paper, Scissors by execution the function rps(p1, p2). The code is the following:

    def rps(p1,p2):
        #tie
        if (p1==p2):
            return 0
        # player 1 wins    
        elif p1+p2 in ['PR','RS','SP']:
            return -1
        else:
            return 1
        # player 2 wins

This is where I'm a bit stuck. I need to activate this function when executing the simul() function—how can I do that? What I have so far is the following:

    def rps(p1,p2):
    #tie
        if (p1==p2):
            return 0
    # player 1 wins    
        elif p1+p2 in ['PR','RS','SP']:
            return -1
        else:
            return 1
    # player 2 wins

    def choose_rps():
        import random
        random.choice('RPS')

    def simul(n):
        p1_wins, p2_wins = 0, 0
        for i in range(n):
            p1 = choose_rps()
            p2 = choose_rps()
            result = rps(p1, p2)
            if result == -1:
                p1_wins += 1
            elif result == 1:
                p2_wins += 1
            if p1_wins > p2_wins:
                return 'Player 1'
            elif p1_wins == p2_wins:
                return 'Tie'
            else:
                return 'Player 2'

Upvotes: 1

Views: 2699

Answers (2)

dansalmo
dansalmo

Reputation: 11696

Here is an equivalent function without the RPS narrative:

import random

def simul(n):
    score = sum([random.choice([-1, 0, 1]) for i in xrange(n)])
    winner_idx = 0 if score > 0 \
            else 1 if score < 0 \
            else 2
    print ['Player 1', 'Player 2', 'Tie'][winner_idx]

Here is one that follows the story and is expanded to Rock, Paper, Scissors, Lizard, Spock:

import random

def rand_RPSLK():
    while True:
        yield random.choice('PSKLR')

def simul(n):
    p1 = rand_RPSLK()
    p2 = rand_RPSLK()
    choice = lambda px: 'PSKLR'.index(next(px))
    score = sum([[0,1,-1,1,-1][choice(p1)-choice(p2)] for i in xrange(n)])
    winner_idx = 0 if score > 0 \
            else 1 if score < 0 \
            else 2
    print ['Player 1', 'Player 2', 'Tie'][winner_idx]

Upvotes: 0

abarnert
abarnert

Reputation: 365875

To "activate" a function, you just call it. For example:

def simul(n):
    score = 0
    for i in range(n):
        p1 = choose_rps()
        p2 = choose_rps()
        result = rps(p1, p2)
        score += result
    if score < 0:
        print('Player 1')
    elif score == 0:
        print('Tie')
    else:
        print('Player 2')

Of course you need to write the choose_rps function (which randomly chooses and returns one of R, P, or S)—but, as you can see, you just call it the same way as the rps function.


To put it all together into a script:

def rps(p1, p2):
    # ... your code here

def choose_rps():
    # implement this here

def simul(n):
    # code from above

And then you'll probably want something to drive it, such as this:

if __name__ == '__main__':
    import sys
    n = int(sys.argv[1]) if len(sys.argv) > 1 else 5
    simul(n)

… or…

while True:
    n = int(input('How many trials?')) # raw_input for Python 2.x
    simul(n)

If you want, you can simplify this further. For example, you can turn the whole loop into a sum call with a generator expression:

def simul(n):
    score = sum(rps(choose_rps(), choose_rps()) for _ in range(n))

Upvotes: 5

Related Questions