项目简介:为骰子游戏Hog开发一个模拟器和多种策略,需要同时使用控制语句和高阶函数(Lecture1-4)
Phase 1: Simulator
按照Hint Video里给的Pseudocode转成代码(注释部分包含Pseudocode)
"""CS 61A Presents The Game of Hog."""
from dice import six_sided, four_sided, make_test_dice
from ucb import main, trace, interact
GOAL_SCORE = 100 # The goal of Hog is to score 100 points.
FIRST_101_DIGITS_OF_PI = 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
######################
# Phase 1: Simulator #
######################
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 ***"
"""
while <cond>:
save dice into temporary variable
if roll 1:
raise flag
update total
if flag raised:
return 1
else:
return total
"""
total = 0
flag = False
while num_rolls:
a = dice()
if a == 1:
flag = True
total += a
num_rolls -= 1
if flag:
return 1
else:
return total
# END PROBLEM 1
def free_bacon(score):
"""Return the points scored from rolling 0 dice (Free Bacon).
score: The opponent's current score.
"""
assert score < 100, 'The game should be over.'
pi = FIRST_101_DIGITS_OF_PI
# Trim pi to only (score + 1) digit(s)
# BEGIN PROBLEM 2
'''
while <some cond>:
update pi by floor-dividing by 10 each time
'''
k=0
while k<=99-score:
pi=pi//10
k+=1
# END PROBLEM 2
return pi % 10 + 3
def take_turn(num_rolls, opponent_score, dice=six_sided):
"""Simulate a turn rolling NUM_ROLLS dice, which may be 0 (Free Bacon).
Return the points scored for the turn by the current player.
num_rolls: The number of dice rolls that will be made.
opponent_score: The total score of the opponent.
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.'
assert opponent_score < 100, 'The game should be over.'
# BEGIN PROBLEM 3
'''
if zero dice:
free_bacon
else:
roll_dice
'''
if num_rolls==0:
return free_bacon(opponent_score)
else:
return roll_dice(num_rolls, dice)
# END PROBLEM 3
def extra_turn(player_score, opponent_score):
"""Return whether the player gets an extra turn."""
return (pig_pass(player_score, opponent_score) or
swine_align(player_score, opponent_score))
def swine_align(player_score, opponent_score):
"""Return whether the player gets an extra turn due to Swine Align.
player_score: The total score of the current player.
opponent_score: The total score of the other player.
>>> swine_align(30, 45) # The GCD is 15.
True
>>> swine_align(35, 45) # The GCD is 5.
False
"""
# BEGIN PROBLEM 4a
"*** YOUR CODE HERE ***"
add_gcd=1
while add_gcd<=player_score:
if player_score%add_gcd==0 and opponent_score%add_gcd==0:
final_gcd=add_gcd
add_gcd+=1
while final_gcd>=10 and player_score >0 and opponent_score > 0:
return True
else:
return False
# END PROBLEM 4a
def pig_pass(player_score, opponent_score):
"""Return whether the player gets an extra turn due to Pig Pass.
player_score: The total score of the current player.
opponent_score: The total score of the other player.
>>> pig_pass(9, 12)
False
>>> pig_pass(10, 12)
True
>>> pig_pass(11, 12)
True
>>> pig_pass(12, 12)
False
>>> pig_pass(13, 12)
False
"""
# BEGIN PROBLEM 4b
'''
while <some cond>:
return True
else:
return False
'''
while opponent_score-player_score>0 and opponent_score-player_score<3:
return True
else:
return False
# END PROBLEM 4b
def other(who):
"""Return the other player, for a player WHO numbered 0 or 1.
>>> other(0)
1
>>> other(1)
0
"""
return 1 - who
def silence(score0, score1):
"""Announce nothing (see Phase 2)."""
return silence
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 at the end of the first turn.
"""
who = 0 # Who is about to take a turn, 0 (first) or 1 (second)
# BEGIN PROBLEM 5
"*** YOUR CODE HERE ***"
'''
who=other(who)
player0_num_dice=strategy0(score0,score1)
bool_extra_turn=extra_turn(player_score, opponent_score)
score_gain=take_turn(num_dice,<score>,dice)
while <some cond>:
depending on which turn:
get num dice to roll
update score
check if extra turn
if no extra turn:
swap player
'''
# END PROBLEM 5
while score0<goal and score1<goal:
if who==0:
roll_dice0=strategy0(score0,score1)
score0=score0+take_turn(roll_dice0,score1,dice)
say=say(score0,score1)
if extra_turn(score0,score1) is False:
who=other(who)
else:
roll_dice1=strategy1(score1,score0)
score1=score1+take_turn(roll_dice1,score0,dice)
say=say(score0,score1)
if extra_turn(score1,score0) is False:
who=other(who)
# (note that the indentation for the problem 6 prompt (***YOUR CODE HERE***) might be misleading)
# BEGIN PROBLEM 6
# END PROBLEM 6
return score0, score1