5-sided die
知道了!我将使用我的高阶函数来扔出更大的骰子。

重新下载文件之前: 请运行python3 ok --submit备份您的工作,以防在重新下载文件的过程中您的工作可能会被覆盖。如果是这样,您可以访问 okpy 以查看您的项目备份并在那里引用您的代码以恢复您目前的工作。

重要的分数更新: 项目的分数已更新,以更准确地反映问题权重,包括项目组成的分数。见组织小节。

如果您在周日(9/5)之前下载了项目 zip 文件,运行python3 ok --score命令会不准确。无需重新下载项目文件,因为这不会影响您的分数。但是,如果您想在运行--score时查看自己的更改,可以重新下载项目文件并从压缩包覆盖tests/文件夹。您可能需要重新解锁测试用例。

重要的 GUI 更新: 如果您在星期五 (9/3)之前下载了项目 zip 文件,则应从当前网站重新下载 GUI 文件。您可以通过从网站重新下载 zip 文件并覆盖 gui 文件:hog_gui.pygui_files文件夹。完成此操作后,gui 应该能与您的项目实现适配。谢谢你的耐心!

介绍

重要的提交说明:对于满分来说:

  • 9月7日星期二之前完成第一阶段的提交(值 1 分)。
  • 9月10日星期五之前完成所有阶段的提交。

尽管第 1 阶段仅在项目其余部分前几天到期,但您不应推迟完成第 1 阶段。我们建议尽快开始完成第 1 阶段。

尝试按顺序解决问题,因为一些后来的问题将取决于早期问题的实现,在运行ok测试时也是如此。

整个项目可以和一个搭档一起完成。

9月9日星期四之前提交整个项目可以获得 1 个奖励分 。

在这个项目中,您将为骰子游戏 Hog 开发一个模拟器和多种策略。您将需要同时使用控制语句和高阶函数,如在线教科书Composing Programs 的第 1.2 至 1.6 节所述。

以往学生在没有仔细阅读问题描述的情况下尝试实现这些功能时,经常会遇到问题。😱在开始编码之前仔细阅读每个描述。

规则

在 Hog 中,两名玩家轮流交替尝试成为第一个以至少总分 100 结束回合的玩家。在每一回合,当前玩家选择一定数量的骰子进行投掷,最多 10 个。玩家在该回合的分数是骰子结果的总和。然而,掷太多骰子的玩家有以下风险:

  • Sow Sad。如果任何骰子结果为 1,则当前玩家在该回合的得分为1

    • 示例 1:当前玩家掷 7 个骰子,其中 5 个为 1。他们在该轮得1分。

    • 示例 2:当前玩家掷 4 个骰子,所有骰子都是 3。由于 Sow Sad 没有发生,他们在该轮得12分。

在正常的 Hog 游戏中,这些就是所有规则。但为了给游戏增添趣味,我们将包含一些特殊规则:

  • Picky Piggy。选择掷零个骰子的玩家得分为 1/7 的十进制展开式 (0.14285714…) 的第n位数字,其中n是对手的得分。作为特例,如果n为 0,则玩家得 7 分。

    • 示例 1:当前玩家掷零个骰子,对手的分数为3。1/7 的十进制展开式的第3位是2:0.14[2]85714285714285,当前玩家将获得2分。

    • 示例 2:当前玩家掷零个骰子,对手的分数为14。1/7 的十进制展开式的第14位数字是4:,0.1428571428571[4]285,因此当前玩家将获得4分。

    • 示例 3:当前玩家掷零个骰子,对手得分为 0。当前玩家将获得7分。

  • Hog Pile。在当前回合得分加到玩家的分数后,如果玩家的分数相同,则当前玩家的分数加倍。

    • 示例:
    • 两个玩家都从 0 开始。 (0, 0)
    • 玩家 0 掷 2 个骰子并获得5分。(5, 0)
    • 玩家 1 掷 1 个骰子并获得5分。玩家 1 的得分翻倍。(5, 10)
    • 玩家 0 掷 2 个骰子并获得6分。(11, 10)
    • 玩家 1 掷 8 个骰子并获得1分。玩家 1 的得分翻倍。(11, 22)

完成品

您可以在hog.cs61a.org上试用在线 Hog GUI,这使用了项目工作人员的解决方案 。当您完成这个项目时,您将会自己实现游戏的重要部分。

下载启动文件

首先,下载所有项目代码 zip 存档。以下是解压缩后您将在存档中看到的所有文件的列表。对于该项目,您只需修改hog.py.

  • hog.py: Hog 的初始实现
  • dice.py: 掷骰子函数
  • hog_gui.py:用于 Hog 的图形用户界面 (GUI)(已更新)
  • ucb.py: CS 61A 的工具函数
  • ok: CS 61A 自动评分器
  • tests: ok使用的测试目录
  • gui_files: web GUI 使用的各种东西的目录
  • calc.py:可用于大致测试最终策略的文件(进行中)

您可能还会注意到上面列出的文件之外的一些文件—这些文件是使自动分级器和部分 GUI 工作所必需的。请不要修改除hog.py之外的文件.

组织

该项目总共 25 分。22 分给正确性,2 分给作业结构,在检查日期之前提交阶段 1 也能得 1 分。

重要的分数更新: 项目的分数已更新,以更准确地反映问题权重,包括项目组成的分数。

如果您在周日(9/5)之前下载了项目 zip 文件,运行python3 ok --score命令会不准确。无需重新下载项目文件,因为这不会影响您的分数。但是,如果您想在运行--score时查看自己的更改,可以重新下载项目文件并从压缩包覆盖tests/文件夹。您可能需要重新解锁测试用例。

您将上交以下文件:

  • hog.py

您无需修改或上交任何其他文件即可完成项目。要提交项目,请运行以下命令:

python3 ok --submit

您将能够在Ok 仪表板上查看您的提交。

对于我们要求您完成的函数,我们可能会提供一些初始代码。如果您不想使用该代码,请随意删除它并从头开始。您还可以根据需要添加新的函数定义。

但是,请不要修改任何其他函数。这样做可能会导致您的代码无法通过我们自动评分器的测试。此外,请不要更改任何函数签名(名称、参数顺序或参数数量)。

在整个项目中,您应该一直测试代码的正确性。经常测试是一种很好的做法,这样可以很容易地隔离任何问题。但是,您不应过于频繁地进行测试,以便让自己有时间思考问题。

我们提供了一个叫ok自动评分器来帮助你测试你的代码并跟踪你的进度。第一次运行自动评分器时,系统会要求您使用 Web 浏览器使用登录 Ok 帐户。请按这样做。每次运行ok,它都会在我们的服务器上备份您的工作和进度。

ok的主要目的是测试您的实现。

我们建议您在完成每个问题后提交。只有您最后一次提交的才会被评分。如果您遇到提交问题,我们有您代码的更多备份也很有用。如果您忘记提交,您的最后一次备份将自动转为提交。

如果您不希望我们记录您工作的备份或进度的信息,您可以运行

python3 ok --local

使用此选项,不会将任何信息发送到我们的课程服务器。如果你想以交互方式测试你的代码,你可以插入适当的问题编号(例如01)运行以下命令:

 python3 ok -q [question number] -i 

这将运行该问题的测试,直到第一次失败为止,然后让您有机会以交互的方式测试您编写的函数。

您还可以通过在 OK 中输入以下内容使用调试打印功能

 print("DEBUG:", x)

这将在您的终端中产生一个输出,而不会由于额外的输出导致 OK 测试失败。

图形用户界面

图形用户界面(简称为 GUI)提供给您了。目前,它不起作用,因为您尚未实现游戏逻辑。一旦你完成了play函数,你就可以玩一个完全互动版的 Hog!

注意:GUI 已更新。有关说明请参阅页面顶部的公告。

完成后,您可以从终端运行 GUI:

python3 hog_gui.py

阶段一:模拟器

在第一阶段,您将为 Hog 游戏开发一个模拟器。

问题 0 (0 分)

dice.py文件使用非纯零参函数表示骰子。这些函数是非纯函数,因为它们每次被调用时可能有不同的返回值。dice.py的文档描述了项目中使用的两种不同类型的骰子:

  • 公平骰子:以相等的概率产生每种可能的结果。已经定义了两个公平的骰子,four_sidedsix_sided,它们由make_fair_dice函数生成。
  • 测试骰子:行为是确定的,它总是循环被传入的参数这个固定的序列。测试骰子由make_test_dice函数生成。

在编写任何代码之前,请通读dice.py文件并通过解锁以下测试来检查您的理解。

python3 ok -q 00 -u

这应该显示如下提示:

=====================================================================
Assignment: Project 1: Hog
Ok, version v1.18.2
=====================================================================

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unlocking tests

At each "? ", type what you would expect the output to be.
Type exit() to quit

---------------------------------------------------------------------
Question 0 > Suite 1 > Case 1
(cases remaining: 1)

>>> test_dice = make_test_dice(4, 1, 2)
>>> test_dice()
?

您应该输入您期望的输出。为此,您需要首先根据上面的描述弄清楚test_dice将要做什么。

您可以通过键入exit()退出解锁。

在 Windows 上键入 Ctrl-C 退出解释器会导致问题,因此请避免这样做。

通常,对于每个解锁测试,您可能会发现在尝试解锁测试之前通读为该问题提供的提纲很有帮助。

问题 1(2 分)

实现hog.py中的roll_dice函数。它需要两个参数:一个正整数num_rolls,给出要掷的骰子次数和一个 dice函数。它返回在一回合中掷该骰子对应次数所获得的分数:要不为结果的总和要不为 1 (Sow Sad)

  • Sow Sad。如果任何骰子结果为 1,则当前玩家在该回合的得分为1

    • 示例 1:当前玩家掷 7 个骰子,其中 5 个为 1。他们该轮得1分。

    • 示例 2:当前玩家掷 4 个骰子,所有骰子都是 3。由于 Sow Sad 没有发生,他们在该轮得12分。

要获得掷一次骰子的单次结果,请调用dice()。你应该在roll_dice函数体中调用dice()恰好num_rolls次。即使Sow Sad在投掷的过程中发生了,也要记住调用dice()刚好num_rolls次。通过这种方式,您可以正确模拟一起扔所有骰子。

理解问题

在编写任何代码之前,解锁测试以验证您对问题的理解。注意:在您解锁对应问题的测试用例之前,您将无法用ok测试您的代码

python3 ok -q 01 -u

编写代码并检查您的工作

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 01

调试技巧

如果测试没有通过,那就是调试的时候了。您可以直接使用 Python 观察函数的行为。首先,启动 Python 解释器并加载hog.py文件。

python3 -i hog.py

然后,您可以用任意数量的骰子调用您的roll_dice函数。该roll_dice函数对dice有一个默认参数值,即随机六面骰子函数。因此,以下调用roll_dice 模拟扔四个公平的六面骰子。

>>> roll_dice(4)

你会发现之前的表达式每次调用它可能会有不同的结果,因为它是模拟随机掷骰子。您还可以使用预先确定结果的测试骰子。例如,当你知道骰子会出现 3 和 4 时,掷两次应该得到总和 7。

>>> fixed_dice = make_test_dice(3, 4)
>>> roll_dice(2, fixed_dice)
7

在大多数系统上,您可以通过按向上箭头,然后按 enter 或 return 来再次计算相同的表达式。要求值更早的命令,请重复按向上箭头。

如果发现了一个问题,你需要更改hog.py文件,保存并退出 Python,再次启动 Python,然后开始计算表达式。即使在重新启动 Python 之后,按向上箭头也可以让您访问之前的表达式。

继续调试您的代码并运行ok测试,直到它们全部通过。对于此项目中的所有问题,您应该遵循相同的过程:理解问题、实施解决方案、测试和调试。

还有一个调试技巧:要在ok测试失败时自动启动交互式解释器,请使用-i标志. 例如,python3 ok -q 01 -i将运行问题 1 的测试,然后在测试失败时启动一个加载了hog.py的交互式解释器 。

问题 2(3 分)

实现picky_piggy,它获取对手的当前score并返回掷 0 个骰子获得的分数。

  • Picky Piggy。选择掷零个骰子的玩家得分为 1/7 的十进制展开式 (0.14285714…) 的第n位数字,其中n是对手的得分。作为特例,如果n为 0,则玩家得 7 分。

    • 示例 1:当前玩家掷零个骰子,对手的分数为3。1/7 的十进制展开式的第3位是2:0.14[2]85714285714285,当前玩家将获得2分。

    • 示例 2:当前玩家掷零个骰子,对手的分数为14。1/7 的十进制展开式的第14位数字是4:,0.1428571428571[4]285,因此当前玩家将获得4分。

    • 示例 3:当前玩家掷零个骰子,对手得分为 0。当前玩家将获得7分。

本题的目的是让您练习检索一个数的数字,因此记住以前的数字迭代作业中使用的技术可能会有所帮助。

但是,您的代码实现不应使用str、列表或包含方括号 [ ]。除了这个约束之外,您可以按照自己的意愿实现此功能。

注意: 请记住在实现函数后从函数中删除字符串"*** YOUR CODE HERE ***",以免出现非故意的str检查错误。

如果语法检查在文档字符串上未通过,请尝试将 Python 版本升级到 3.8 或 3.9。检查包含文档字符串似乎特定于 Python 3.7 版,因此更新 Python 版本应该可以解决该问题。

提示: 1/7的十进制展开是一个6位的重复数字”142857“。因此,第2位与第8位、第14位、第20位、第26位、第32位等相同。

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 02 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 02

您还可以通过在终端键入python3 -i hog.py然后使用各种输入调用picky_piggy来交互地测试。

问题 3(2 分)

实现take_turn函数,该函数返回掷num_rolls次给定骰子dice的得分。

你实现的take_turn在可能的情况下应该调用roll_dicepicky_piggy

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 03 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 03

👩🏽‍💻👨🏿‍💻 [结对编程?]() 请记住交替扮演驾驶员和导航员的角色。驾驶员控制键盘;导航员观看,询问并提出想法。

问题 4(1 分)

实现hog_pile,它接受当前玩家和对手的分数,并返回当前玩家因 Hog Pile 机制而获得的分数。如果 Hog Pile 不适用,当前玩家获得额外 0 分,也就是不增加分数。

  • Hog Pile。回合得分加到当前玩家的分数后,如果玩家的分数相同,则当前玩家的积分加倍。
    • 例子:
    • 两个玩家都从 0 开始。 (0, 0)
    • 玩家 0 掷 2 个骰子并获得5分。(5, 0)
    • 玩家 1 掷 1 个骰子并获得5分。玩家 1 的积分翻倍。(5, 10)
    • 玩家 0 掷 2 个骰子并获得6分。(11, 10)
    • 玩家 1 掷 8 个骰子并获得1分。玩家 1 的积分翻倍。(11, 22)

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 04 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 04

问题 5(4 分)

实现play函数,模拟一个完整的 Hog 游戏。玩家轮流掷骰子,直到其中一名玩家达到goal分数。一个回合被定义为掷一次骰子。

为了确定每回合掷多少骰子,每个玩家使用自己的策略(玩家 0 使用strategy0,玩家 1 使用strategy1)。策略指的是一个函数,给定一个玩家的得分和对手的得分,返回当前玩家将在该回合中投骰子的数量。暂时不要担心实现策略;你会在第 3 阶段才做。

重要: 您的实现应该只需要使用一个循环;你不需要多个循环。如果您的逻辑总体上是正确的,这可能不会影响通过测试用例,但这可能会影响您的项目的编码评分。这是关于项目编码的教学大纲部分。

此外,每个策略函数每回合只应调用一次。这意味着您只想在轮到玩家 0 时调用strategy0,在轮到玩家 1 时调用strategy1。否则,GUI 和某些ok测试可能会混淆。

如果玩家在他们的回合结束时达到目标分数,即在应用了所有适用的规则之后,游戏结束。play将返回两个玩家的最终总分,首先是玩家 0 的分数,然后是玩家 1 的分数。

提示

  • 您应该调用已经实现的函数。
  • 用四个参数(不要忘记在传入goal)调用take_turntake_turn每回合只能调用一次。
  • 调用hog_pile以确定当前玩家是否会因 Hog Pile 获得额外分数,如果是,获得多少分。
  • 您可以通过调用提供的函数next_player来获取下一个玩家的号码(0 或 1)。
  • 您现在可以忽略play函数的say参数。您将在项目的第 2 阶段使用它。
  • 对于解锁的测试,hog.always_roll指的是hog.py中定义的always_roll函数。

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 05 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 05

一旦完成后,您就能够玩游戏的图形版本了。我们提供了一个您可以从终端运行的hog_gui.py文件:

python3 hog_gui.py

注意:GUI 已更新。有关说明,请参阅页面顶部的公告。

GUI 依赖于您的实现,因此如果您的代码中有任何错误,它们将被反映在 GUI 中。这意味着您还可以将 GUI 用作调试工具;但是,最好先运行测试。

确保在检查截止日期之前提交您的作业:

python3 ok --submit

检查以确保您完成了第 1 阶段中的所有问题:

python3 ok --score

恭喜!您已完成此项目的第 1 阶段!

👩🏽‍💻👨🏿‍💻 结对编程? 这将是转换角色的好时机。转换角色确保你们都能从担任不同角色的学习经验中受益。

阶段二:评论

在第二阶段,您将实现评论函数,在每回合后打印有关游戏的评论,例如: "22 point(s)! That's a record gain for Player 1!"

评论函数接受两个参数,玩家 0 的当前分数和玩家 1 的当前分数。它可以根据当前分数或/和其父环境中的任何其他信息打印评论。由于根据游戏中的当前分数情况,评论可能会因回合而异,因此评论函数总是返回另一个在下一轮调用的评论函数。评论函数的唯一副作用应该是打印。

评论示例

hog.py里的say_scores函数是一个评论函数的例子,它简单地宣布两个玩家的分数。请注意,say_scores返回自身,这意味着每轮都会调用相同的评论函数。

def say_scores(score0, score1):
    """A commentary function that announces the score for each player."""
    print("Player 0 now has", score0, "and Player 1 now has", score1)
    return say_scores

函数announce_lead_changes是一个高阶函数的例子,它返回一个跟踪领先变化的评论函数。每回合将调用不同的评论函数。

def announce_lead_changes(last_leader=None):
    """Return a commentary function that announces lead changes.

    >>> f0 = announce_lead_changes()
    >>> f1 = f0(5, 0)
    Player 0 takes the lead by 5
    >>> f2 = f1(5, 12)
    Player 1 takes the lead by 7
    >>> f3 = f2(8, 12)
    >>> f4 = f3(8, 13)
    >>> f5 = f4(15, 13)
    Player 0 takes the lead by 2
    """
    def say(score0, score1):
        if score0 > score1:
            leader = 0
        elif score1 > score0:
            leader = 1
        else:
            leader = None
        if leader != None and leader != last_leader:
            print('Player', leader, 'takes the lead by', abs(score0 - score1))
        return announce_lead_changes(leader)
    return say

您还应该了解函数both,它接受两个评论函数(fg)并返回一个新的评论函数。这个返回的评论函数的返回值是使用both函数调用fg的结果,按照先fg的顺序,当然也是个评论函数。

def both(f, g):
    """Return a commentary function that says what f says, then what g says.

    >>> h0 = both(say_scores, announce_lead_changes())
    >>> h1 = h0(10, 0)
    Player 0 now has 10 and Player 1 now has 0
    Player 0 takes the lead by 10
    >>> h2 = h1(10, 8)
    Player 0 now has 10 and Player 1 now has 8
    >>> h3 = h2(10, 17)
    Player 0 now has 10 and Player 1 now has 17
    Player 1 takes the lead by 7
    """
    def say(score0, score1):
        return both(f(score0, score1), g(score0, score1))
    return say

问题 6(1 分)

更新您的play函数,以便在每轮结束时调用评论函数。调用评论函数的返回值为您提供了下一轮调用的评论函数。

例如,say(score0, score1)应该在第一回合结束时调用。它的返回值(另一个评论函数)应该在第二轮结束时调用。每个连续的回合,调用上一回合的评论函数返回的函数。

提示: 对于此问题的解锁测试,请记住,当使用多个参数调用print时,Python 会在每个参数之间放置一个空格。例如:

>>> print(9, 12)
9 12

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 06 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 06

问题 7(3 分)

实现announce_highest函数,它是一个返回评论函数的高阶函数。每当特定玩家在回合中获得比以往更多的积分时,此评论函数就会宣布。例如, announce_highest(1)完全忽略玩家 0,只打印玩家 1 的信息。(它的返回值也是如此;另一个仅关于玩家 1 的评论函数。)

要计算分数的增加,它必须将感兴趣的玩家(由who参数指定)的上一回合 的分数( last_score) 与本回合分数进行比较。此函数还必须跟踪目前为止玩家的最高得分,并赋给running_high.

announce_highest公布的方式是非常明确的,你的实现应与提供的文档测试匹配。当宣布积分增加时,不要担心单数与复数;对于这两种情况,您应该使用 “point(s)” 简单地处理。

提示:announce_lead_changes函数提供给您的是一个如何使用评论函数跟踪信息的示例。如果您遇到困难,请首先确保您了解announce_lead_changes工作原理。

提示: 如果出现local variable [var] reference before assignment错误:

发生这种情况是因为在 Python 中,通常不允许您修改父帧中定义的变量。[var]并没有被重新赋值,反而解释器认为您正在尝试在当前帧内定义一个新变量。我们将在以后的讲座中学习如何解决这个问题,但这不是这个问题所必需的。

要解决此问题,您有两个选择:

1)与其给[var]赋新值,不如创建一个新变量来保存该新值。在以后的计算中使用该新变量。

2)对于这个特定问题,完全不使用赋值语句来完全避免它。相反,将新值作为参数传递给对announce_highest的调用。

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 07 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 07

完成后,您将在 GUI 中看到评论:

python3 hog_gui.py

注意:GUI 已更新。有关说明,请参阅页面顶部的公告。

GUI 中的评论是通过将以下函数作为say参数传递给play来生成的 。

both(announce_highest(0), both(announce_highest(1), announce_lead_changes()))

做得好!您刚刚完成了项目的第 2 阶段!

👩🏽‍💻👨🏿‍💻 结对编程? 庆祝、休息并转换角色!

阶段三:策略

在阶段三,您将尝试各种方法改进始终掷固定数量骰子的基本策略。首先,您需要开发一些工具来评估策略。

问题 8(2 分)

实现make_averaged函数,它是一个以函数original_function为参数的高阶函数。

make_averaged的返回值是一个与original function有着相同数量参数的函数。当我们在参数上调用这个返回的函数时,它会返回在传入的参数上重复调用original_function的平均值 。

具体来说,这个函数应该调用original_function总共trials_count次并返回这些调用结果的平均值。

重要: 要实现此函数,您需要使用新的 Python 语法。我们想编写一个接受任意数量参数的函数,然后使用这些参数来调用另一个函数。下面是它的工作原理。

与其列出一个函数的形式参数,你不如使用*args,它代表所有传递给该函数的参数。然后我们可以通过将*args传递给另一个函数来用这些相同的参数调用该函数。例如:

>>> def printed(f):
...     def print_and_return(*args):
...         result = f(*args)
...         print('Result:', result)
...         return result
...     return print_and_return
>>> printed_pow = printed(pow)
>>> printed_pow(2, 8)
Result: 256
256
>>> printed_abs = printed(abs)
>>> printed_abs(-10)
Result: 10
10

在这里,我们可以通过 *args 语法传递任意数量的参数给 print_and_return。我们也可以在print_and_return 函数内部使用 *args 来使用相同的参数进行另一个函数调用。

仔细阅读make_averaged的文档字符串以了解它是如何工作的。

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 08 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 08

问题 9(2 分)

实现max_scoring_num_rolls函数,该函数运行一个实验来确定一个回合产生最大平均分数的掷骰子次数(从 1 到 10)。您的实现应该用到make_averagedroll_dice

如果两个掷骰子数的最大平均分数一样,则返回较低的掷骰子数。例如,如果 3 和 6 均达到最大平均分数,则返回 3。

您可能会发现在进行解锁测试之前阅读文档字符串和其中针对此问题的示例很有用。

重要:为了通过我们所有的测试,请确保您正在测试从 1 到 10 的次序掷骰子,而不是从 10 到 1。

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 09 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 09

运行实验:

要在随机骰子上运行此实验,请使用-r选项调用run_experiments

python3 hog.py -r

对于本项目的其余部分,您可以根据需要更改run_experiments的实现。该函数包括各种调用average_win_rate来评估不同的 Hog 策略,但大多数调用当前已被注释掉。您可以取消注释来试验策略,例如比较always_roll(8)always_roll(6)的胜率。

某些实验可能需要一分钟才能运行完。您可以随时减少调用make_averaged的试验次数以加快实验速度。

运行实验不会影响您项目的分数。

👩🏽‍💻👨🏿‍💻 结对编程? 如果您最近还没有,我们建议现在转换角色。快完成了!

问题 10(1 分)

策略可以利用 Picky Piggy 规则掷 0 个骰子,如果这是最优的话。实现picky_piggy_strategy函数,当掷 0 个骰子时至少获得cutoff分数时该函数返回 0,否则返回num_rolls

提示:您可以使用在问题 2 中定义的picky_piggy函数。

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 10 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 10

一旦你实现此策略后,请更改run_experiments来根据基准评估新策略。这个策略是对基准的改进吗?

问题 11(1 分)

策略也可以利用 Hog Pile 规则。如果可以触发此规则,则 Hog Pile 策略始终会掷 0 个骰子。在其他情况下,如果掷 0 个骰子至少能获得cutoff分,则它会掷 0 。否则,策略会选择掷num_rolls个骰子。

提示:你可以使用在问题 10 中定义的picky_piggy_strategy函数。

提示:请记住,hog_pile应在将来自 picky_piggy的得分添加到总分后进行检查。

在编写任何代码之前,解锁测试以验证您对问题的理解。

python3 ok -q 11 -u

完成解锁后,开始实现您的解答。您可以通过以下方式检查您的正确性:

python3 ok -q 11

一旦你实现此策略后,请更新run_experiments以根据基准来评估新策略。

可选:问题 12 (0 pt)

实施final_strategy,它结合了这些或任何其他想法,以实现对基准策略的高胜率。一些建议:

  • picky_piggy_strategy或者hog_pile_strategy是您可以开始使用的默认策略。
  • 如果您知道目标得分(默认为 100),那么得分超过目标就毫无意义。检查您是否可以通过掷 0、1 或 2 个骰子来获胜。如果您处于领先地位,您可能会决定减少冒险。
  • 仔细选择num_rollscutoff参数。
  • 采取最有可能赢得比赛的行为。

您可以通过运行ok来检查您的最终策略是否有效。

python3 ok -q 12

您还可以使用图形用户界面和您的最终策略对抗:

python3 hog_gui.py

注意:GUI 已更新。有关说明,请参阅页面顶部的公告。

GUI 将交替由您控制的玩家。

项目提交

此时,运行整个自动评分器以查看是否有任何未通过的测试:

python3 ok

您还可以检查项目每个部分的分数:

python3 ok --score

满意后,提交以完成项目。

python3 ok --submit

如果您有合作伙伴,请确保将他们添加到okpy上的项目提交部分 。

恭喜,您的第一个 CS 61A 项目已经结束! 如果您还没有,请放松并与朋友一起玩几场 Hog 游戏。

Hog 比赛

如果您有兴趣,您可以通过参加 Hog Contest 进一步完善 Hog,在那里您可以使用final_strategy与其他学生进行较量。获胜的策略将获得额外的学分,并将在未来的学期中得到认可!

要查看更多信息,请阅读比赛说明。或查看排行榜

最后修改日期: 2022年6月7日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。