其实这个项目不难,只是把,对于英语不好的我来说,这个翻译太绕口了,我好多都不知道题目意思是什么。只能在GitHub上找了一些答案,对着答案看题目,也是醉了;
1. 游戏规则
这个游戏就是你和对手轮流摇色子,获取色子点数总和,然后比较你和对手的色子总数大小,色子最多选择10个;但是里面有两个特殊情况。
- Sow Sad: 当回合只要出现点数为1的情况的时候,该轮得分为1;
- Pig Tail : 对手得分十位数和各位数的差值的绝对值,然后加上1 作为该轮分数;
- Square Swine : 当该轮选手总分数为完美平方的时候,就是开根号能开出正整数,就返回该正整数加1的平方
2.code
1.Problem 1 实现色子点数之和;
Rule
roll_dice这个方法返回的结果就是色子的点数之和,当色子出现1的时候,那么就会出发Sow Sad,则本轮返回结果为1,否则返回总数;
第一个是色子的个数,第二个是函数,通过这个函数,获取色子的点数;
实现很简单,就是遍历求和;如果触发了1点的条件,则将has_one这个值设置为True,然后返回值通过if条件返回即可。
但是因为本来是学Java的,所以Java返回值不存在函数的现象,所以Python这种返回值是一种很灵活的方式;
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 ***"
# END PROBLEM 1
sum = 0
has_one = False
for i in range(num_rolls):
m = dice()
if (m == 1):
has_one = True
continue
sum += m
return sum if not has_one else 1
2.Problem 2 实现Pig Tail
Rule:
实现Pig Tail,这翻译软件翻译成猪尾巴。。也是醉了。
tail_points 函数接收对手分数,这个分数需要返回的是个位数和十位数。
实现就按照这个实现就行,但是要求是不要假设小于100,所以需要坐一个判断
def tail_points(opponent_score):
"""Return the points scored by rolling 0 dice according to Pig Tail.
opponent_score: The total score of the other player.
"""
# BEGIN PROBLEM 2
"*** YOUR CODE HERE ***"
# END PROBLEM 2
return 1 if opponent_score <= 0 \
else abs(opponent_score % 10 - (opponent_score // 10) % 10) * 2 + 1
3. Problem 3 返回回合点数 take_turn
Rule:
返回分数总和
take_turn 接收三个参数,num_rolls代表次数,opponent_score 是对手分数 dice 代表执行函数
这个实现不难,就是如果当摇色子次数为0的时候,返回tail_points 函数的结果,否则返回摇色子的个数
def take_turn(num_rolls, opponent_score, dice=six_sided):
"""Return the points scored on a turn rolling NUM_ROLLS dice when the
opponent has OPPONENT_SCORE points.
num_rolls: The number of dice rolls that will be made.
opponent_score: The total score of the other player.
dice: A function that simulates a single dice roll outcome.
"""
# 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.'
# BEGIN PROBLEM 3
"*** YOUR CODE HERE ***"
# END PROBLEM 3
# 这题的意思就是如果当num_rolls 为0的时候,就是不需要掷色子,
if num_rolls == 0:
return tail_points(opponent_score)
else:
return roll_dice(num_rolls, dice)
4. Problem 4 square_update 完美平方数
Rule
Square Swine 解释过了,实现即可
square_update 函数,接收四个参数, num_rolls 返回摇色子的个数,player_score当前分数,opponent_score对手分数,dice是获取点数的函数
实现不难,第一步是判断你是否为完美平方,如果是则返回Square Swine,如果不是则返回当前点数和分数的总和;
def square_update(num_rolls, player_score, opponent_score, dice=six_sided):
"""Return the total score of a player who starts their turn with
PLAYER_SCORE and then rolls NUM_ROLLS DICE, *including* Square Swine.
"""
score = player_score + take_turn(num_rolls, opponent_score, dice)
if perfect_square(score): # Implement perfect_square
return next_perfect_square(score) # Implement next_perfect_square
else:
return score
5.Problem 5 play 模拟游戏
rule:
模拟游戏,直到分数达到目标分数;
play函数接收六个参数,strategy0 代表0号玩家执行的策略,策略说白了就是该玩家通过什么方法得到结果
score0 代表0号玩家当前回合得到的分数,strategy1 score1 就是1号玩家的策略和得分,dice是获取点数的函数,goal 代表目标值,他是一个阈值。达到这个跳出循环;
实现就是轮流获取分数,然后判断是否达到目标分数,如果没有达到目标分数,则再轮询,直至大于等于goal为止;
def play(strategy0, strategy1, update,
score0=0, score1=0, dice=six_sided, goal=GOAL):
"""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, square_update) simulates a game in
which both players always choose to roll 5 dice on every turn and the Square
Swine rule is in effect.
A strategy function, such as always_roll_5, takes the current player's
score and their opponent's score and returns the number of dice the current
player chooses to roll.
An update function, such as square_update or simple_update, takes the number
of dice to roll, the current player's score, the opponent's score, and the
dice function used to simulate rolling dice. It returns the updated score
of the current player after they take their turn.
strategy0: The strategy for player0.
strategy1: The strategy for player1.
update: The update function (used for both players).
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
"*** YOUR CODE HERE ***"
# END PROBLEM 5
score = 0
while True:
if score0 >= goal or score1 >= goal:
break
if who == 0:
score = strategy0(score0, score1)
score0 = update(score, score0, score1, dice)
else:
score = strategy1(score1, score0)
score1 = update(score, score1, score0, dice)
who = 1 - who
return score0, score1
此时,第一阶段目标完成;
6.always_roll 返回固定色子个数
Rule :这个目标我个人就是觉得将always_roll_5 == always_roll(5) 。说第二节点,就是通过固定色子获得得分;因为两个人摇的色子点数应该是一致的;
always_roll 的参数代表摇多少色子
这个就是定义一个嵌套函数,返回嵌套函数名称就行;
def always_roll(n):
"""Return a player strategy that always rolls N dice.
A player 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.
>>> strategy = always_roll(3)
>>> strategy(0, 0)
3
>>> strategy(99, 99)
3
"""
assert n >= 0 and n <= 10
# BEGIN PROBLEM 6
"*** YOUR CODE HERE ***"
# END PROBLEM 6
def strategy_roll(x, y):
return n
return strategy_roll
7.Problem 7 掷出相同色子的概率
Rule :
固定数量色子,摇出相同点数;我们通过轮训,判断当前值和上一个值是否一致即可;
strategy 代表当前执行的策略, goal 是目标分数,跳出循环的阈值
MD这个一想到我就气,我想的是,当函数签名一致的时候,获得的函数方法也是一致的。所以我直接调用always_roll() 返回函数,然后和strategy比较,但是这么想唯一的缺陷就是需要参数n,我的参数没办法穿,而后来看了答案就是遍历,获取每一个值,然后对比得出结果。。。。囧
def is_always_roll(strategy, goal=GOAL):
"""Return whether strategy always chooses the same number of dice to roll.
>>> is_always_roll(always_roll_5)
True
>>> is_always_roll(always_roll(3))
True
>>> is_always_roll(catch_up)
False
"""
# BEGIN PROBLEM 7
"*** YOUR CODE HERE ***"
# END PROBLEM 7
x, y = 0, 0
def get_score(x, y):
return strategy(x, y)
while x < goal:
while y < goal:
score0 = get_score(x, y)
y += 1
score1 = get_score(x, y)
if score0 != score1:
return False
x += 1
y = 0
return True
8. Problem 8 make_averaged 返回调用函数次数之后的平均值
Rule
make_averaged 的目标就是获取总和的平均值,这个不要考虑太多,就是只需要考虑最终的值大小就行;
实现是通过定义一个函数,这个函数接收任意多参数,然后返回平均数,我们调用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.
>>> dice = make_test_dice(4, 2, 5, 1)
>>> averaged_dice = make_averaged(roll_dice, 40)
>>> averaged_dice(1, dice) # The avg of 10 4's, 10 2's, 10 5's, and 10 1's
3.0
"""
# BEGIN PROBLEM 8
"*** YOUR CODE HERE ***"
# END PROBLEM 8
def getScore(*args):
roll_total, roll_num = 0, total_samples
while roll_num:
roll_total += original_function(*args)
roll_num -= 1
return roll_total / total_samples
return getScore
9.Problem 9 max_scoring_num_rolls 获取最大平均得分;
Rule :
就是返回最大均分,当第一次和第二次得到相同结果的时候,则返回第一次,首先出现的次数;
dice 代表获取结果的策略, total_samples 代表执行的次数
其实就是通过make_averaged 函数,通过roll_dice函数和次数,获取均分。
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
"*** YOUR CODE HERE ***"
# END PROBLEM 9
ret, max_score = 0, 0
for i in range(1, 11):
averaged_dice = make_averaged(roll_dice, total_samples)
score = averaged_dice(i, dice)
if score > max_score:
ret, max_score = i, score
return ret
10 Problem 10 0的攻城略地
Rule 当掷色子次数为0的时候,当大于阈值点的时候,返回0 否则返回默认摇色子数目
def tail_strategy(score, opponent_score, threshold=12, num_rolls=6):
"""This strategy returns 0 dice if Pig Tail gives at least THRESHOLD
points, and returns NUM_ROLLS otherwise. Ignore score and Square Swine.
"""
# BEGIN PROBLEM 10
roll_points = 0
if score:
roll_points = tail_points(opponent_score)
return 0 if roll_points >= threshold else num_rolls
return num_rolls # Remove this line once implemented.
# END PROBLEM 10
11.Problem 11 结合 Pig Tail Square Swine
Rule ,这个就是如果结合Pig Tail Square Swine 给出掷色子数量;
def square_strategy(score, opponent_score, threshold=12, num_rolls=6):
"""This strategy returns 0 dice when your score would increase by at least threshold."""
# BEGIN PROBLEM 11
gain = square_update(0, score, opponent_score)
if gain - score >= threshold:
return 0
return num_rolls # Remove this line once implemented.
# END PROBLEM 11
最后附上通过截图
3.写在最后
与其说这个Pro硬,不如说自己基本功不扎实,好多地方看不明白,导致错的多。有了答案再去看题目,发现奥,原来是这个意思。