[CS61A] Lecture 4. Higher-Order Functions & Project 1: The Game of Hog

Lecture

Lecture 4. Higher-Order Functions

本节课介绍了高阶函数的概念与用法,主要包含如下内容:

  1. 从斐波那契数列说起,定义fib函数并使用迭代法解答。
  2. 面积公式,介绍正方形、五边形以及圆形的面积公式,它们的共同点是面积公式都可以变为:半径x半径x面积系数 的形式,因此将函数抽象成一个通用函数。
  3. 求和公式,西格玛求和公式可以通过一个包含序列长度n和元素计算函数term的方式表达,就此引入高阶函数的概念。
  4. 局部函数:在非全局作用域中定义的函数,例如make_adder函数接受一个整数n,返回用来+n的函数adder。
  5. 高阶函数:将函数作为参数或返回值的函数。
  6. 匿名函数:lambda函数,没有绑定名称的函数。
  7. return关键词:表示函数的结束,函数有两种返回的方法,一种是当满足条件时返回,另一个是判断所有不满足的条件后返回。
  8. 控制语句if、else,控制表达式and、or、x if a else b。

Q&A:lambda函数

Project 1: The Game of Hog

Phase 1: Rules of the Game

该项目要求充分运用python中控制与高阶函数相关的知识,实现一个hog游戏。

Problem 0 (0 pt)

要求在dice.py文件中实现一个公平的骰子。实际上是个判断题,判断多个骰子函数中哪个才是真正公平的骰子,答案是a) six_sided()。

执行测试用例:

$ python3 ok -q 00 -u
Question 0 > Suite 1 > Case 1
? 4
? 1
? 2
? 4
---------------------------------------------------------------------
Question 0 > Suite 2 > Case 1
? 0

Problem 1 (2 pt)

要求在hog.py中实现roll_dice函数。

roll_dice函数:

def roll_dice(num_rolls, dice=six_sided):
"""Simulate rolling the DICE exactly NUM_ROLLS > 0 times. Return the sum of
the outcomes unless any of the outcomes is 1. In that case, return 1. num_rolls: The number of dice rolls that will be made.
dice: A function that simulates a single dice roll outcome.
"""
# These assert statements ensure that num_rolls is a positive integer.
assert type(num_rolls) == int, 'num_rolls must be an integer.'
assert num_rolls > 0, 'Must roll at least once.'
# BEGIN PROBLEM 1
res = [dice() for _ in range(num_rolls)]
return 1 if 1 in res else sum(res)
# END PROBLEM 1

执行测试用例:

$ python3 ok -q 01 -u
Question 1 > Suite 1 > Case 1
? 10
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 2
? 1
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 3
? 1
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 5
? 1
? 6
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 6
? 54
$ python3 ok -q 01
Test summary
59 test cases passed! No cases failed.

Problem 2 (4 pt)

要求实现oink_points函数。

oink_points函数:

def oink_points(player_score, opponent_score):
"""Return the points scored by player due to Oink Points. player_score: The total score of the current player.
opponent_score: The total score of the other player.
"""
ones = opponent_score%10
tens = opponent_score//10%10
return max(2*tens-ones, 1)

执行测试用例:

$ python3 ok -q 02 -u
Question 2 > Suite 1 > Case 1
? 1
---------------------------------------------------------------------
Question 2 > Suite 1 > Case 2
? 12
---------------------------------------------------------------------
Question 2 > Suite 1 > Case 3
? 1
$ python3 ok -q 02
Test summary
34 test cases passed! No cases failed.

Problem 3 (2 pt)

要求实现take_turn函数。

take_turn函数:

def take_turn(num_rolls, player_score, opponent_score, dice=six_sided, goal=GOAL_SCORE):
"""Simulate a turn rolling NUM_ROLLS dice,
which may be 0 in the case of a player using Oink Points.
Return the points scored for the turn by the current player. num_rolls: The number of dice rolls that will be made.
player_score: The total score of the current player.
opponent_score: The total score of the opponent.
dice: A function that simulates a single dice roll outcome.
goal: The goal score of the game.
"""
# Leave these assert statements here; they help check for errors.
assert type(num_rolls) == int, 'num_rolls must be an integer.'
assert num_rolls >= 0, 'Cannot roll a negative number of dice in take_turn.'
assert num_rolls <= 10, 'Cannot roll more than 10 dice.'
assert max(player_score, opponent_score) < goal, 'The game should be over.'
# BEGIN PROBLEM 3
if num_rolls==0:
return oink_points(player_score, opponent_score)
return roll_dice(num_rolls, dice)
# END PROBLEM 3

执行测试用例:

$ python3 ok -q 03 -u
Question 3 > Suite 1 > Case 1
? 9
---------------------------------------------------------------------
Question 3 > Suite 1 > Case 2
? 1
---------------------------------------------------------------------
Question 3 > Suite 1 > Case 3
? 7
---------------------------------------------------------------------
Question 3 > Suite 1 > Case 4
? 1
$ python3 ok -q 03
Test summary
10 test cases passed! No cases failed.

Problem 4 (1 pt)

要求实现pigs_on_prime函数。

pigs_on_prime函数:

def pigs_on_prime(player_score, opponent_score):
"""Return the points scored by the current player due to Pigs on Prime. player_score: The total score of the current player.
opponent_score: The total score of the other player.
"""
# BEGIN PROBLEM 4
if not is_prime(player_score):
return 0
additional_score = 1
while not is_prime(player_score+additional_score):
additional_score+=1
return additional_score
# END PROBLEM 4

执行测试用例:

$ python3 ok -q 04 -u
Question 4 > Suite 1 > Case 1
? 0
---------------------------------------------------------------------
Question 4 > Suite 1 > Case 2
? 4
---------------------------------------------------------------------
Question 4 > Suite 1 > Case 3
? 0
---------------------------------------------------------------------
Question 4 > Suite 1 > Case 4
? 2
---------------------------------------------------------------------
Question 4 > Suite 1 > Case 5
? 2
$ python3 ok -q 04
Test summary
105 test cases passed! No cases failed.

Phase 2: Playing the Game

Problem 5 (5 pt)

要求实现play函数。

play函数:

def play(strategy0, strategy1, score0=0, score1=0, dice=six_sided,
goal=GOAL_SCORE, say=silence):
"""Simulate a game and return the final scores of both players, with Player
0's score first, and Player 1's score second. A strategy is a function that takes two total scores as arguments (the
current player's score, and the opponent's score), and returns a number of
dice that the current 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.
say: The commentary function to call every turn.
"""
who = 0 # Who is about to take a turn, 0 (first) or 1 (second)
leader = None # To be used in problem 7
# BEGIN PROBLEM 5
while score0 < goal and score1 < goal:
if who == 0:
score0 += take_turn(strategy0(score0, score1), score0, score1, dice, goal)
score0 += pigs_on_prime(score0, score1)
else:
score1 += take_turn(strategy1(score1, score0), score1, score0, dice, goal)
score1 += pigs_on_prime(score1, score0)
who = next_player(who)
# END PROBLEM 5
# (note that the indentation for the problem 7 prompt (***YOUR CODE HERE***) might be misleading)
# BEGIN PROBLEM 7
"*** YOUR CODE HERE ***"
# END PROBLEM 7
return score0, score1

执行测试用例:

$ python3 ok -q 05 -u
Question 5 > Suite 1 > Case 1
? 2
---------------------------------------------------------------------
Question 5 > Suite 1 > Case 2
? 1
---------------------------------------------------------------------
Question 5 > Suite 1 > Case 3
? 3
---------------------------------------------------------------------
Question 5 > Suite 2 > Case 1
? 106
? 10
---------------------------------------------------------------------
Question 5 > Suite 2 > Case 2
? 15
? 0
---------------------------------------------------------------------
Question 5 > Suite 3 > Case 1
? 87
? 108
$ python3 ok -q 05
Test summary
111 test cases passed! No cases failed.

Problem 6 (2 pt)

要求实现announce_lead_changes函数。

announce_lead_changes函数:

def announce_lead_changes(score0, score1, last_leader=None):
"""A commentary function that announces when the leader has changed. >>> leader, message = announce_lead_changes(5, 0)
>>> print(message)
Player 0 takes the lead by 5
>>> leader, message = announce_lead_changes(5, 12, leader)
>>> print(message)
Player 1 takes the lead by 7
>>> leader, message = announce_lead_changes(8, 12, leader)
>>> print(leader, message)
1 None
>>> leader, message = announce_lead_changes(8, 13, leader)
>>> leader, message = announce_lead_changes(15, 13, leader)
>>> print(message)
Player 0 takes the lead by 2
"""
# BEGIN PROBLEM 6
if score0 == score1:
leader = None
changes = 0
elif score0 < score1:
leader = 1
changes = score1-score0
else:
leader = 0
changes = score0-score1
return leader, f'Player {leader} takes the lead by {changes}' if leader != last_leader and leader != None else None
# END PROBLEM 6

执行测试用例:

$ python3 ok -q 06 -u
Question 6 > Suite 1 > Case 1
? 1
---------------------------------------------------------------------
Question 6 > Suite 1 > Case 2
? 0
---------------------------------------------------------------------
Question 6 > Suite 1 > Case 3
? 0
$ python3 ok -q 06
Test summary
4 test cases passed! No cases failed.

Problem 7 (2 pt)

要求更新play函数,

函数:

def play(strategy0, strategy1, score0=0, score1=0, dice=six_sided,
goal=GOAL_SCORE, say=silence):
"""Simulate a game and return the final scores of both players, with Player
0's score first, and Player 1's score second. A strategy is a function that takes two total scores as arguments (the
current player's score, and the opponent's score), and returns a number of
dice that the current 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.
say: The commentary function to call every turn.
"""
who = 0 # Who is about to take a turn, 0 (first) or 1 (second)
leader = None # To be used in problem 7
# BEGIN PROBLEM 5
while score0 < goal and score1 < goal:
if who == 0:
score0 += take_turn(strategy0(score0, score1), score0, score1, dice, goal)
score0 += pigs_on_prime(score0, score1)
else:
score1 += take_turn(strategy1(score1, score0), score1, score0, dice, goal)
score1 += pigs_on_prime(score1, score0)
who = next_player(who)
# END PROBLEM 5
# (note that the indentation for the problem 7 prompt (***YOUR CODE HERE***) might be misleading)
# BEGIN PROBLEM 7
leader, message = say(score0, score1, leader)
print(message) if message else 0
# END PROBLEM 7
return score0, score1

执行测试用例:

$ python3 ok -q 07 -u
Question 7 > Suite 1 > Case 1
? 0
---------------------------------------------------------------------
Question 7 > Suite 2 > Case 3
(line 1)? 5 0
(line 2)? 5 5
(line 3)? 8 5
---------------------------------------------------------------------
Question 7 > Suite 2 > Case 4
(line 1)? 1 7
(line 2)? 2 7
(line 3)? 3 12
(line 4)? 4 12
(line 5)? 5 19
---------------------------------------------------------------------
Question 7 > Suite 3 > Case 1
(line 1)? 4 0
(line 2)? 4 12
(line 3)? 7 12
(line 4)? 7 24
---------------------------------------------------------------------
Question 7 > Suite 3 > Case 2
(line 1)? 3
(line 2)? 10
(line 3)? 14
(line 4)? 19
---------------------------------------------------------------------
Question 7 > Suite 3 > Case 3
(line 1)? * 3
(line 2)? ** 0
(line 3)? * 3
(line 4)? ** 3
(line 5)? * 7
(line 6)? ** 3
$ python3 ok -q 07
Test summary
9 test cases passed! No cases failed.

Phase 3: Strategies of the Game

Problem 8 (2 pt)

实现make_averaged函数。

make_averaged函数:

def make_averaged(original_function, total_samples=1000):
"""Return a function that returns the average value of ORIGINAL_FUNCTION
called TOTAL_SAMPLES times. To implement this function, you will have to use *args syntax, a new Python
feature introduced in this project. See the project description. >>> dice = make_test_dice(4, 2, 5, 1)
>>> averaged_dice = make_averaged(roll_dice, 1000)
>>> averaged_dice(1, dice)
3.0
"""
# BEGIN PROBLEM 8
def inner(*args):
return sum([original_function(*args) for _ in range(total_samples)])/total_samples
return inner
# END PROBLEM 8

执行测试用例:

$ python3 ok -q 08 -u
Question 8 > Suite 1 > Case 1
? 3
---------------------------------------------------------------------
Question 8 > Suite 1 > Case 2
? 0
---------------------------------------------------------------------
Question 8 > Suite 2 > Case 1
? 3.75
---------------------------------------------------------------------
Question 8 > Suite 2 > Case 2
? 6.0
$ python3 ok -q 08
Test summary
7 test cases passed! No cases failed.

Problem 9 (2 pt)

实现max_scoring_num_rolls函数。

max_scoring_num_rolls函数:

def max_scoring_num_rolls(dice=six_sided, total_samples=1000):
"""Return the number of dice (1 to 10) that gives the highest average turn score
by calling roll_dice with the provided DICE a total of TOTAL_SAMPLES times.
Assume that the dice always return positive outcomes. >>> dice = make_test_dice(1, 6)
>>> max_scoring_num_rolls(dice)
1
"""
# BEGIN PROBLEM 9
new_roll_dice = make_averaged(roll_dice, total_samples)
return max([(new_roll_dice(i, dice), i) for i in range(1, 11)], key=lambda x: x[0])[1]
# END PROBLEM 9

执行测试用例:

$ python3 ok -q 09 -u
Question 9 > Suite 1 > Case 1
? 2
---------------------------------------------------------------------
Question 9 > Suite 2 > Case 1
? 10
---------------------------------------------------------------------
Question 9 > Suite 3 > Case 1
? 10
---------------------------------------------------------------------
Question 9 > Suite 3 > Case 2
? 1
---------------------------------------------------------------------
Question 9 > Suite 3 > Case 3
? 1
$ python3 ok -q 09
Test summary
10 test cases passed! No cases failed.

Problem 10 (1 pt)

要求实现oink_points_strategy函数。

oink_points_strategy函数:

def oink_points_strategy(score, opponent_score, threshold=8, num_rolls=6):
"""This strategy returns 0 dice if that gives at least THRESHOLD points, and
returns NUM_ROLLS otherwise.
"""
# BEGIN PROBLEM 10
return 0 if oink_points(score, opponent_score) >= threshold else num_rolls
# END PROBLEM 10

执行测试用例:

$ python3 ok -q 10 -u
Question 10 > Suite 1 > Case 1
? 0
---------------------------------------------------------------------
Question 10 > Suite 1 > Case 2
? 5
---------------------------------------------------------------------
Question 10 > Suite 1 > Case 3
? 0
---------------------------------------------------------------------
Question 10 > Suite 1 > Case 4
? 4
---------------------------------------------------------------------
Question 10 > Suite 1 > Case 5
? 0
$ python3 ok -q 10
Test summary
106 test cases passed! No cases failed.

Problem 11 (1 pt)

要求实现pigs_on_prime_strategy函数。

pigs_on_prime_strategy函数:

def pigs_on_prime_strategy(score, opponent_score, threshold=8, num_rolls=6):
"""This strategy returns 0 dice when this would result in Pigs on Prime taking
effect. It also returns 0 dice if it gives at least THRESHOLD points.
Otherwise, it returns NUM_ROLLS.
"""
# BEGIN PROBLEM 11
additional = oink_points(score, opponent_score)
return 0 if pigs_on_prime(score+additional, opponent_score) != 0 or additional >= threshold else num_rolls
# END PROBLEM 11

执行测试用例:

$ python3 ok -q 11 -u
Question 11 > Suite 1 > Case 1
? 0
---------------------------------------------------------------------
Question 11 > Suite 1 > Case 2
? 6
---------------------------------------------------------------------
Question 11 > Suite 1 > Case 3
? 0
---------------------------------------------------------------------
Question 11 > Suite 1 > Case 4
? 6
$ python3 ok -q 11
Test summary
105 test cases passed! No cases failed.

Optional: Problem 12 (0 pt)

要求实现final_strategy函数,该题为开放题,思考怎样结合oink_points或pigs_on_prime策略,让玩家赢的概率才能够更大。

参考资料

CS61A Project 1: The Game of Hog:https://cs61a.org/proj/hog/

cs61a公开课视频:https://www.bilibili.com/video/BV1s3411G7yM

[CS61A] Lecture 4. Higher-Order Functions & Project 1: The Game of Hog的更多相关文章

  1. [CS61A] Lecture 5&6&7. Environments & Design & Functions Examples & Homework 2: Higher Order Functions

    [CS61A] Lecture 5&6&7. Environments & Design & Functions Examples & Homework 2: ...

  2. 46 Simple Python Exercises-Higher order functions and list comprehensions

    26. Using the higher order function reduce(), write a function max_in_list() that takes a list of nu ...

  3. [CS61A] Lecture 1&2&3. Introduction&Functions&Control

    [CS61A] Lecture 1&2&3. Introduction&Functions&Control 前言 CS61A是加州大学伯克利分校一门计算机专业课程,用于 ...

  4. [React] Higher Order Components (replaces Mixins)

    Higher order components will allow you to apply behaviors to multiple React components. So the idea ...

  5. [React] Implement a Higher Order Component with Render Props

    When making a reusable component, you'll find that people often like to have the API they're most fa ...

  6. [Redux] Understand Redux Higher Order Reducers

    Higher Order Reducers are simple reducer factories, that take a reducer as an argument and return a ...

  7. [React Intl] Use a react-intl Higher Order Component to format messages

    In some cases, you might need to pass a string from your intl messages.js file as a prop to a compon ...

  8. [React] Cleanly Map Over A Stateless Functional Component with a Higher Order Component

    In this lesson we'll create a Higher Order Component (HOC) that takes care of the key property that ...

  9. [RxJS] Flatten a higher order observable with concatAll in RxJS

    Besides switch and mergeAll, RxJS also provides concatAll as a flattening operator. In this lesson w ...

随机推荐

  1. 【java】学习路径45-多线程-线程生命周期

    线程分为五大状态:新建.就绪.运行.阻塞.死亡. New,Runnable,Running,Blocked,Terminated. 新建状态(New: 创建好一个系统对象,在调用start()之前,线 ...

  2. Windows如何创存储虚拟机并制作存储虚拟化LUN的映射

    创建虚拟机 只能设置为8G,不能多也不能少 选择仅主机模式 选择使用现有磁盘 浏览选择自己的vmdk文件 选择保存现有格式 点击完成 点击编辑虚拟机设置 添加一个40G的硬盘 修改为40G并选择存储为 ...

  3. 【PMP学习笔记】第5章 项目范围管理

    一.规范管理的内涵 项目范围管理:包括确保项目做且只做所需的全部工作,以成功完成项目的各个过程. 项目范围:为交付具有规定特性与功能的产品.服务或成果而必须完成的工作. 预测型:开始时定义可交付成果, ...

  4. 全局索引与分区索引对于SQL性能影响的比较

    KingbaseES 提供了对于分区表 global index 的支持.global index 不仅提供了对于唯一索引功能的改进(无需包含分区键),而且在性能上相比非global index (l ...

  5. ProxySQL(11):链式规则( flagIN 和 flagOUT )

    文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9350631.html 理解链式规则 在mysql_query_rules表中,有两个特殊字段"fl ...

  6. centos7使用yum方式安装node_exporter

    官网下载地址:https://prometheus.io/download/ 选择对应的系统版本 官网提供的是压缩包,点击旁边的github地址 github页面显示的有yum安装和docker安装, ...

  7. Elasticsearch集群规模和容量规划的底层逻辑

    转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484628&idx=1&sn=666e416ae ...

  8. js基础知识--BOM

    之前说过,在js的 运行环境为浏览器时,js就主要有三部分组成: ECMAScript核心语法.BOM.DOM.今天就和大家详细说一下BOM的一些基础知识. BOM BOM通常被称为浏览器对象模型,主 ...

  9. 十分钟速成DevOps实践

    摘要:以华为云软件开发平台DevCloud为例,十分钟简单体验下DevOps应用上云实践--H5经典小游戏上云. 本文分享自华为云社区<<DevOps实践秘籍>十分钟速成DevOps ...

  10. SQL日期查询语句

    --查询当天(1: select * from ShopOrder where datediff(day,ordTime,getdate()-1)=0 --查询当天(2:select * from i ...