【问题标题】:Dice Game Simulation骰子游戏模拟
【发布时间】:2019-05-09 23:16:46
【问题描述】:

我有一个作业问题:

你的朋友设计了一个有两个玩家的游戏。两位选手, 叫 A 和 B,轮流掷一个普通的六面骰子,A 是 第一个滚动。

第一个掷出 6 的玩家赢得游戏。 你和你的朋友不同意 A 获胜的概率 游戏是,因此您决定使用 电脑。

因此:编写一个执行 10 次试验的 Python 程序,每个试验包括 10000 场比赛,并且每次试验都会打印获胜的比赛的分数 玩家A。

这是我目前得到的代码,它每次只返回一个 1667 左右的数字。我主要想知道如何区分A或B赢得比赛。

任何帮助将不胜感激!

编辑代码

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

【问题讨论】:

  • 我相信你误解了你的问题。您只为 A 创建了一个函数,但它是 A 对 B 的游戏。所以您应该为 diceRow 创建一个函数,然后循环交互次数,每一行属于一个玩家,并检查分数。在所有的试验之后,然后计算 A 赢得比赛的分数。
  • 感谢磨坊!如何创建一个知道抛出是 A 还是 B 的函数?
  • 您应该为 A 的得分和 B 的得分创建变量,例如,为每个播放添加一个 for 循环。每次游戏运行此diceRow 两次,一次将结果分配给玩家 A,另一次分配给玩家 B,并检查结果是否因骰子结果为 6 而获胜。清楚吗?
  • 好的,所以如果 A 先抛出,我如何检查抛出是否是 A,我可以使用 if numThrows %2 != 0 之类的东西吗?因为所有的 As throw 都是奇怪的
  • 简单一点,@user10551611,只需创建两个变量:aThrowbThrow

标签: python python-3.x montecarlo dice stochastic


【解决方案1】:

实现干净代码的最佳方法是将functions 中的每个任务分开,意思是:
1. 运行游戏 -> 每次掷骰子
2. 运行游戏 -> A 和 B 之间交替进行游戏,直到第一个在骰子上得到 6(这里考虑到如果 A 得到 6,B 甚至不需要玩,因为 A 赢了)
3. 运行试验 -> 由特定数量的播放组成
4. 运行主程序 -> 包括播放所有需要的次数

所以,下面是可能的解决方案之一(在这里你看到我的play 函数已经返回了结果,这意味着玩家是否赢了):

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)

【讨论】:

    【解决方案2】:

    您实际上只需要计算玩家 A 的获胜次数。由于您每次尝试玩 10000 场比赛,如果您知道 A 赢得了多少场比赛,您就知道其他比赛一定是 B 赢得的,并且 A+B= 10000。

    你似乎随机决定谁先轮,但任务规定应该始终是玩家 A 第一轮。

    您可以使用布尔值isPlayerA 知道轮到谁了。从isPlayerA = True 开始,然后用isPlayerA = not isPlayerA 切换它。

    你可以这样编码:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-19
      • 2014-03-16
      • 2016-02-07
      • 2013-03-07
      • 2018-10-19
      • 1970-01-01
      • 2012-02-29
      • 2015-09-28
      相关资源
      最近更新 更多