-1

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
trincot
  • 317,000
  • 35
  • 244
  • 286
  • I believe you misunderstood your problem. You've created a function for only A, but it's a game with A against B. So you should create a function for diceRow, and after loop over the number of interactions, with each row belonging to one player, and checking the scores. After all the trials, then calculate the fraction of games that A won. – Luan Naufal Dec 08 '18 at 12:05
  • Thanks a mill! How do I create a function knowing if the throw is A or B's? – user10551611 Dec 08 '18 at 12:07
  • you should create variables for score for A and score for B, so add a `for` loop, for instance, for each play. Run this `diceRow` twice for each play, one assigning the result to player A and another to player B, and checking the results, if any won because the dice result was 6. Is it clear? – Luan Naufal Dec 08 '18 at 12:12
  • Okay, so if A throws first, how do I check if the throw is A's, can I use something like if numThrows %2 != 0? As all of As throws are odd – user10551611 Dec 08 '18 at 12:25
  • Just make it simpler, @user10551611, just create two variables: `aThrow` and `bThrow` – Luan Naufal Dec 08 '18 at 12:34
  • I've edited it, but it's still not coming out correct.. It seems to only be taking in the number of trials – user10551611 Dec 08 '18 at 14:42
  • You seem to decide randomly who has the first turn, but the task states that it should always be "A" taking the first turn. – trincot Dec 08 '18 at 15:13

2 Answers2

0

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)
Luan Naufal
  • 1,346
  • 9
  • 15
0

You really only need to count wins for player A. Since you play 10000 games per trial, if you know the number of games that A won, you know the other games must have been won by B, and A+B=10000.

You seem to decide randomly who has the first turn, but the task states that it should always be player A taking the first turn.

You can use a boolean isPlayerA to know whose turn it is. Start with isPlayerA = True and then toggle it with isPlayerA = not isPlayerA.

Here is how you could code it:

import random

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

def winFraction(): # Perform one trial of 10000 games and return fraction of wins for A
    winsA = 0 # only count wins for A
    for numTrow in range(10000):
        isPlayerA = True # Player A always takes the first turn
        throw = rollDie()
        while throw != 6: # While the game is not over yet:
            isPlayerA = not isPlayerA # Switch to the other player
            throw = rollDie()
        if isPlayerA:
            winsA += 1 # Only count the wins for player A
    return winsA/10000.0 # This is the fraction: we know the number of played games

def sim():
    for trial in range(10): # Perform 10 trials
        print(winFraction()) # Print the result of the trial

sim() # Start the simulation
trincot
  • 317,000
  • 35
  • 244
  • 286