CS61A 课程项目 Hog, Phase2: Commontary

提示:本文内容来源于UCB CS61A课程,详情请点击CS 61A: Structure and Interpretation of Computer Programs


前言

本文收录在文章CS61A 课程 Project1 The Game of Hog


提示:以下是本篇文章正文内容,下面代码除课程提供外均为本人自主完成,仅供参考

Phase2 Commentary

本阶段需要完成一个函数,该函数会在每位玩家每轮结束后对其作出注释,如

"22 points! That's the biggest gain yet for Player 1."

一个注释函数需要两个参数,玩家0的当前分数和玩家1的当前分数

其作用是打印分数中的任意一个或者两个,也可以打印其父环境中其他信息

由于分数的不同,每一轮的注释函数会有所差异,所以一个注释函数会返回下一轮将要调用的注释函数(注释函数的唯一副作用为打印信息)

课程提供了一个注释函数的样例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

除上述两个函数之外,还提供了一个函数both,该函数的两个参数f,g均为注释函数,该函数的返回值为一个新的注释函数,被返回的函数又会返回另一个注释函数,该函数按顺序依次调用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, 6)
    Player 0 now has 10 and Player 1 now has 6
    >>> h3 = h2(6, 17)
    Player 0 now has 6 and Player 1 now has 17
    Player 1 takes the lead by 11    
    NOTE: the following game is not possible under the rules, it's just
    an example for the sake of the doctest
    """
    def say(score0, score1):
        return both(f(score0, score1), g(score0, score1))
    return say

关于嵌套含数的调用请参照1.2.5 Evaluating Nested Expressions的内容

Problem 06

本节要求更新play函数的内容,使得注释函数可以在每轮游戏中被调用,而注释函数得返回值同时是下一轮游戏得注释函数

课程提供了提问脚本用于确保学生完全理解函数的要求

$ python3 ok -q 06 -u --local
=====================================================================
Assignment: Project 1: Hog
OK, version v1.18.1
=====================================================================

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

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

---------------------------------------------------------------------
Question 6 > Suite 1 > Case 1
(cases remaining: 7)

Q: What does a commentary function return?
Choose the number of the correct choice:
0) An integer representing the score.
1) None.
2) Another commentary function.
? 2
-- OK! --

---------------------------------------------------------------------
Question 6 > Suite 2 > Case 1
(cases remaining: 6)

>>> from hog import play, always_roll
>>> from dice import make_test_dice
>>> #
>>> def echo(s0, s1):
...     print(s0, s1)
...     return echo
>>> s0, s1 = play(always_roll(1), always_roll(1), dice=make_test_dice(3), goal=5, say=echo)
(line 1)? 3 0
(line 2)? 3 3
(line 3)? 9 3
-- OK! --

---------------------------------------------------------------------
Question 6 > Suite 2 > Case 2
(cases remaining: 5)

>>> from hog import play, always_roll
>>> from dice import make_test_dice
>>> #
>>> def count(n):
...     def say(s0, s1):
...         print(n, s0)
...         return count(n + 1)
...     return say
>>> s0, s1 = play(always_roll(1), always_roll(1), dice=make_test_dice(3), goal=10, say=count(1))
(line 1)? 1 3
(line 2)? 2 3
(line 3)? 3 9
(line 4)? 4 9
(line 5)? 5 15
-- OK! --

---------------------------------------------------------------------
Question 6 > Suite 2 > Case 3
(cases remaining: 4)

>>> from hog import play, always_roll
>>> from dice import make_test_dice
>>> #
>>> def echo(s0, s1):
...     print(s0, s1)
...     return echo
>>> strat0 = lambda score, opponent: 1 - opponent // 10
>>> strat1 = always_roll(3)
>>> s0, s1 = play(strat0, strat1, dice=make_test_dice(4, 2, 6), goal=15, say=echo)
(line 1)? 4 0
(line 2)? 4 12
(line 3)? 12 13
(line 4)? 12 25
-- OK! --

---------------------------------------------------------------------
Question 6 > Suite 2 > Case 4
(cases remaining: 3)

>>> from hog import play, always_roll
>>> from dice import make_test_dice
>>> #
>>> # Ensure that say is properly updated within the body of play.
>>> def total(s0, s1):
...     print(s0 + s1)
...     return echo
>>> def echo(s0, s1):
...     print(s0, s1)
...     return total
>>> s0, s1 = play(always_roll(1), always_roll(1), dice=make_test_dice(2, 3), goal=15, say=echo)
(line 1)? 2 0
(line 2)? 5
(line 3)? 4 3
(line 4)? 13
(line 5)? 6 9
(line 6)? 21
-- OK! --

---------------------------------------------------------------------
Question 6 > Suite 3 > Case 1
(cases remaining: 2)

>>> from hog import play, always_roll, both, announce_lead_changes, say_scores
>>> from dice import make_test_dice
>>> #
>>> def echo_0(s0, s1):
...     print('*', s0)
...     return echo_0
>>> def echo_1(s0, s1):
...     print('**', s1)
...     return echo_1
>>> s0, s1 = play(always_roll(1), always_roll(1), dice=make_test_dice(2), goal=3, say=both(echo_0, echo_1))
(line 1)? * 2
(line 2)? ** 0
(line 3)? * 2
(line 4)? ** 2
(line 5)? * 4
(line 6)? ** 2
-- OK! --

---------------------------------------------------------------------
Question 6 > Suite 3 > Case 2
(cases remaining: 1)

-- Already unlocked --

---------------------------------------------------------------------
OK! All cases for Question 6 unlocked.

函数得实现只需要在if和else得语句块末尾分别添加以下表达式即可

say = say(score0, score1)

可以通过脚本得检测

$ python3 ok -q 06 --local
=====================================================================
Assignment: Project 1: Hog
OK, version v1.18.1
=====================================================================

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running tests

---------------------------------------------------------------------
Test summary
    7 test cases passed! No cases failed.

Problem 07

该部分要求实现announce_highest函数,该函数为一个返回值为注释函数得高阶函数
该注释函数只有在某个特定玩家在某一轮游戏中获得比以往更多的分数时才会打印信息

例如,announce_highest(1) 及其返回值完全忽略玩家0,只打印有关玩家1的信息。

要计算得分,必须目标玩家将上一回合的得分与本回合的得分进行比较(目标玩家由参数who指定)

除此之外,该函数须跟踪玩家到目前为止的最高得分

课程提供提问脚本以确保学生完全理解函数的需求

$ python3 ok -q 07 -u
=====================================================================
Assignment: Project 1: Hog
OK, version v1.18.1
=====================================================================

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

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

---------------------------------------------------------------------
Question 7 > Suite 1 > Case 1
(cases remaining: 5)

Q: What does announce_highest return?
Choose the number of the correct choice:
0) A string containing the largest point increase for the
   current player.
1) The current largest point increase between both
   players.
2) A commentary function that prints information about the
   biggest point increase for the current player.
? 2
-- OK! --

---------------------------------------------------------------------
Question 7 > Suite 1 > Case 2
(cases remaining: 4)

Q: When does the commentary function returned by announce_highest
print something out?
Choose the number of the correct choice:
0) After each turn.
1) When the current player, given by the parameter `who`,
   earns the biggest point increase yet between both
   players in the game.
2) When the current player, given by the parameter `who`,
   earns their biggest point increase yet in the game.
? 2
-- OK! --

---------------------------------------------------------------------
Question 7 > Suite 1 > Case 3
(cases remaining: 3)

Q: What does the parameter last_score represent?
Choose the number of the correct choice:
0) The current player's score before this turn.
1) The opponent's score before this turn.
2) The last highest gain for the current player.
? 0
-- OK! --

---------------------------------------------------------------------
OK! All cases for Question 7 unlocked.

函数的实现如下:

def announce_highest(who, last_score=0, running_high=0):
    """Return a commentary function that announces when WHO's score
    increases by more than ever before in the game.

    NOTE: the following game is not possible under the rules, it's just
    an example for the sake of the doctest

    >>> f0 = announce_highest(1) # Only announce Player 1 score gains
    >>> f1 = f0(12, 0)
    >>> f2 = f1(12, 11)
    11 point(s)! That's the biggest gain yet for Player 1
    >>> f3 = f2(20, 11)
    >>> f4 = f3(13, 20)
    >>> f5 = f4(20, 35)
    15 point(s)! That's the biggest gain yet for Player 1
    >>> f6 = f5(20, 47) # Player 1 gets 12 points; not enough for a new high
    >>> f7 = f6(21, 47)
    >>> f8 = f7(21, 77)
    30 point(s)! That's the biggest gain yet for Player 1
    >>> f9 = f8(77, 22) # Swap!
    >>> f10 = f9(33, 77) # Swap!
    55 point(s)! That's the biggest gain yet for Player 1
    """
    assert who == 0 or who == 1, 'The who argument should indicate a player.'
    # BEGIN PROBLEM 7
    "*** YOUR CODE HERE ***"
    def track_highest(score0, score1, highest=running_high):
        if who == 0:
            this_score = score0
        else:
            this_score = score1
        gain = this_score - last_score
        if gain > highest:
            print(gain, "point(s)! That's the biggest gain yet for Player", who)
            highest = gain
        return announce_highest(who, this_score, highest)
    return track_highest
    # END PROBLEM 7

该函数的实现满足评分脚本要求

$ python3 ok -q 07 --local
=====================================================================
Assignment: Project 1: Hog
OK, version v1.18.1
=====================================================================

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running tests

---------------------------------------------------------------------
Test summary
    5 test cases passed! No cases failed.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值