提示:本文内容来源于UCB CS61A课程,详情请点击CS 61A: Structure and Interpretation of Computer Programs
文章目录
前言
本文收录在文章CS61A 课程 Project1 The Game of Hog
提示:以下是本篇文章正文内容,下面代码除课程提供外均为本人自主完成,仅供参考
阶段1:模拟器
Problem 0
完成这一部分需要阅读说明和dice.py
中的代码
from random import randint
def make_fair_dice(sides):
"""Return a die that returns 1 to SIDES with equal chance."""
assert type(sides) == int and sides >= 1, 'Illegal value for sides'
def dice():
return randint(1,sides)
return dice
four_sided = make_fair_dice(4)
six_sided = make_fair_dice(6)
def make_test_dice(*outcomes):
"""
Return a die that cycles deterministically through OUTCOMES.
This function uses Python syntax/techniques not yet covered in this course.
The best way to understand it is by reading the documentation and examples.
"""
assert len(outcomes) > 0, 'You must supply outcomes to make_test_dice'
for o in outcomes:
assert type(o) == int and o >= 1, 'Outcome is not a positive integer'
index = len(outcomes) - 1
def dice():
nonlocal index
index = (index + 1) % len(outcomes)
return outcomes[index]
return dice
函数make_fair_dice在传入一个参数sides(骰子的面数)后返回一个sides面骰子,每次投掷等可能生成1-sides之间任意一个数字
函数make_test_dice传入一个整数序列,按顺序循环输出序列中的数字(大致功能为此,依据后续内容,发现该函数用来避免随机性以对其他函数的实现进行测试)
>>> dice = make_test_dice(1, 2, 3)
>>> dice()
1
>>> dice()
2
>>> dice()
3
>>> dice()
1
>>> dice()
2
课程组提供了一个脚本,用于检测学生是否理解了dice.py内函数的作用
$ python3 ok -q 00 -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 0 > Suite 1 > Case 1
(cases remaining: 2)
>>> from hog import *
>>> test_dice = make_test_dice(4, 1, 2)
>>> test_dice()
? 4
-- OK! --
>>> test_dice() # Second call
? 1
-- OK! --
>>> test_dice() # Third call
? 2
-- OK! --
>>> test_dice() # Fourth call
? 4
-- OK! --
---------------------------------------------------------------------
Question 0 > Suite 2 > Case 1
(cases remaining: 1)
Q: Which of the following is the correct way to "roll" a fair, six-sided die?
Choose the number of the correct choice:
0) six_sided()
1) make_fair_dice(6)
2) make_test_dice(6)
3) six_sided
? 0
-- OK! --
---------------------------------------------------------------------
OK! All cases for Question 0 unlocked.
关于nonlocal关键字
因为变量index是在函数dice之外make_test_dice之内定义的,因此要修改index的值,需要nonlocal关键字,需要注意的是,make_test_dice返回的函数dice一直持有其父环境(即定义dice函数的环境),因此会记录每一次修改后index的值,从而保证循环依次输出元组*outcomes的中的整数
Problem 01
该环节需要实现hog.py
文件中的roll_dice
函数
该函数需要两个参数:
- 一个正数
num_rolls
,表示该玩家本轮要投掷多少个骰子 - 一个函数
dice
,表示投掷何种骰子
该函数的返回值该轮中获得的分数,分数只能是1或者每次投掷结果的和(根据Pig Out规则)
该课程还对函数的实现作出以下要求:
- 调用dice()可以获得一次投掷的结果,你需要在roll_dice的函数体中确切调用dice()函数num_rolls次
即是投掷结果是1可能会触发Pig Out规则,但仍然需要将所有num_rolls次数投掷完,因为在现实中投掷骰子是一次行将num_rolls全部掷出的,在函数实现中需要正确地模拟这种情况
- 在函数中不能尝试实现Feral Hogs规则,因为本函数无法知晓前一次投掷结果(该参数没有传入),该功能会在别处实现
课程为确保学生完全理解函数需求,提供了一个检测脚本用于学生自查(只有通过这类检测,脚本的代码检测功能才能正常使用)(挺贴心的)
$ python3 ok -q 01 -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 1 > Suite 1 > Case 1
(cases remaining: 59)
>>> from hog import *
>>> roll_dice(2, make_test_dice(4, 6, 1))
? 10
-- OK! --
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 2
(cases remaining: 58)
>>> from hog import *
>>> roll_dice(3, make_test_dice(4, 6, 1))
? 1
-- OK! --
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 3
(cases remaining: 57)
>>> from hog import *
>>> roll_dice(4, make_test_dice(2, 2, 3))
? 9
-- OK! --
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 4
(cases remaining: 56)
>>> from hog import *
>>> roll_dice(4, make_test_dice(1, 2, 3))
? 1
-- OK! --
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 5
(cases remaining: 55)
>>> from hog import *
>>> counted_dice = make_test_dice(4, 1, 2, 6)
>>> roll_dice(3, counted_dice)
? 1
-- OK! --
>>> # Make sure you call dice exactly num_rolls times!
>>> # If you call it fewer or more than that, it won't be at the right spot in the cycle for the next roll
>>> # Note that a return statement in a for loop ends the loop
>>> roll_dice(1, counted_dice)
? 6
-- OK! --
---------------------------------------------------------------------
Question 1 > Suite 1 > Case 6
(cases remaining: 54)
>>> from hog import *
>>> roll_dice(9, make_test_dice(6))
? 54
-- OK! --
>>> roll_dice(7, make_test_dice(2, 2, 2, 2, 2, 2, 1))
? 1
-- OK! --
---------------------------------------------------------------------
OK! All cases for Question 1 unlocked.
下面就可以开始实现掷骰子函数了
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
"*** YOUR CODE HERE ***"
score, i = 0, 1
pig_out = False
while i <= num_rolls:
this_roll = dice()
score += this_roll
if this_roll == 1:
pig_out = True
i += 1
return 1 if pig_out else score
# END PROBLEM 1
由于要将投掷过程模拟出来,所以没有在投掷骰子的循环过程中将得分更改为1,而是选择了设立一个pig_out
的flag,当某个骰子(某一侧投掷)的结果为1时,将该flag设为True,然后用这个flag的真值来确定要返回的是1还是score
上述实现的最后一行与以下等效
if pig_out == True:
return 1
else:
return score
能通过自动打分脚本的测评
$ python3 ok -q 01
=====================================================================
Assignment: Project 1: Hog
OK, version v1.18.1
=====================================================================
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running tests
-