Problem 5 (500pts)
实现play函数,该函数模拟完整的Hog游戏。
玩家轮流掷骰子,直到其中一名玩家的得分达到goal,函数将返回两名玩家的最终得分。
为了确定每轮掷多少个骰子,每个玩家使用其各自的战略(玩家0使用strategy0,玩家1使用strategy1)。
战略是一个函数,给定玩家的得分和对手的得分,返回当前玩家在该轮将掷的骰子数。
一个示例战略是always_roll_5,它在play函数的下方。
如果任何玩家在回合结束时达到目标得分,即在应用所有适用规则后,游戏结束。
重要:
为了用户界面正常工作,每个回合只能调用一次战略函数。 只在轮到玩家0时调用
strategy0,只在轮到玩家1时调用strategy1。提示:
- 您应该调用已经实现的函数。
- 如果
who是当前玩家,则下一个玩家是1 - who。
在编写任何代码之前,请解锁测试以验证您对问题的理解。
python ok -q 05 -u
解锁完成后,开始实现您的解决方案。您可以使用以下命令检查正确性:
python ok -q 05
完成后,您将能够玩该游戏的图形版本。我们提供了一个名为hog_gui.py的文件,您可以从终端运行:
python hog_gui.py
您可以通过在终端中输入Ctrl + C退出图形界面。
图形界面依赖于您的实现,因此如果您的代码有任何错误,它们将在图形界面中体现出来。这意味着您也可以将图形界面用作调试工具;不过,最好先运行测试。
恭喜!您已完成该项目的第一阶段!
Solutions
def play(strategy0, strategy1, score0=0, score1=0, dice=six_sided, goal=GOAL_SCORE):
"""Simulate a game and return the final scores of both players, with Player
0's score first, and Player 1's score second.
E.g., play(always_roll_5, always_roll_5) simulates a game in which both
players always choose to roll 5.
A strategy function, such as always_roll_5, takes the current player's
score and the opponent's score, and returns the number of dice that the
corresponding player will roll this turn.
strategy0: The strategy function for Player 0, who plays first.
strategy1: The strategy function for Player 1, who plays second.
score0: Starting score for Player 0
score1: Starting score for Player 1
dice: A function of zero arguments that simulates a dice roll.
goal: The game ends and someone wins when this score is reached.
"""
who = 0 # Who is about to take a turn, 0 (first) or 1 (second)
# BEGIN PROBLEM 5
nxt = 1 - who
strs = [strategy0, strategy1]
scos = [score0, score1]
playing = True
while playing:
dice_cnt = strs[who](scos[who], scos[nxt])
scos[who] += take_turn(dice_cnt, scos[nxt], dice)
if scos[who] >= goal:
playing = False
if swine_swap(scos[who]):
scos[who], scos[nxt] = scos[nxt], scos[who]
who, nxt = nxt, who
score0, score1 = scos
# END PROBLEM 5
return score0, score1
one-liner:
def play(strategy0, strategy1, score0=0, score1=0, dice=six_sided, goal=GOAL_SCORE):
return (score0, score1) if max(score0, score1) >= goal else ((lambda x, y: y, x)(play(
strategy1, strategy0,
*((lambda x, y: (x, y) if swine_swap(x) else (y, x))(score0 + take_turn(strategy0(score0, score1)), score1)),
dice, goal
)))