Search code examples
pythonpython-3.xmontecarlodicestochastic

Dice Game Simulation


I have this question for an assignment:

Your friend has devised a game with two players. The two players, called A and B, take turns rolling an ordinary six-sided die, with A being the first to roll.

The first player who rolls a six wins the game. You and your friend do not agree about what the probability of A winning the game is, and you therefore decide to simulate the game with a computer.

Thus: write a Python program that performs 10 trials, each consisting of 10000 games, and for each trial prints the fraction of the games won by player A.

This is the code I've gotten so far, it's just returning a number in and around 1667 every time. I'm mainly wondering how to differentiate between A or B winning the game.

Any help would be appreciated!

EDITED CODE

import random

def rollDie():
    return random.choice([1,2,3,4,5,6])

def roll_first():
    if random.choice([0,1]) == 0:
        return 'A'
    else:
        return 'B'   

def rollSim():
    while True:
        turn = roll_first()
        numTrials = 10
        numThrows = 10000
        totalThrows = numTrials*numThrows
        game_on = True
        winsA = 0
        winsB = 0
        while game_on:
            for n in range(numTrials):
                games = 0
                for i in range(numThrows):
                    throw = rollDie()
                    if turn == 'A':
                        if throw == 6:
                            winsA += 1
                            games += 1
                            break
                        else:
                            turn = 'B'
                    else:
                        if throw == 6:
                            winsB += 1
                            games += 1
                            break
                        else:
                            turn = 'A'
            return winsA/totalThrows

Solution

  • The best way to achieve a clean code would be to separate in functions each one of the tasks in hand, meaning:
    1. Run a play -> For each dice rolling
    2. Run a game -> Alternation of plays between A and B, until the first one gets a 6 on the dice (here considering that if A gets a 6, B doesn't even need to play, as A won)
    3. Run a trial -> Consisting of a specific number of plays
    4. Run the main program -> Consisting of playing all the number of trials required

    So, below, is one of the possible solutions (here you see that my play function already returns the result, meaning if the player won or not):

    import random
    
    def play():
        won = True
        keepPlaying = False
        rollDice = random.choice([1,2,3,4,5,6])
        if rollDice == 6: 
            return won
        return keepPlaying
    
    def run_game(winsA, winsB):
        while True:
            playA = play()
            playB = play()
            if playA:
                winsA += 1
                return winsA, winsB
            elif playB:
                winsB += 1
                return winsA, winsB
    
    def run_trial(numGames):
        winsA = 0
        winsB = 0
        for i in range(numGames):
            wins = run_game(winsA, winsB)
            winsA = wins[0]
            winsB = wins[1]
        print("winsA:", winsA, "| winsB:", winsB, "| Fraction of A wins:",  "{} %".format(winsA / ( winsA + winsB ) * 100))
    
    numTrials = 10
    numGames = 10000
    
    for i in range(numTrials):
        run_trial(numGames)