花了3天完成这个project。之后就在看别人的代码,觉得自己写的还是有问题的
"""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 ***"
sum = 0
flag_Pig_Out = False
while num_rolls :
roll = dice()
if roll == 1 :
flag_Pig_Out = True
sum = sum + roll
num_rolls -= 1
if flag_Pig_Out == True :
sum = 1
return sum
"""
sum = 1 if flag_Pig_Out else sum
return sum
"""
# 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
"*** YOUR CODE HERE ***"
a = pow(10 , 100 - score)
pi = pi // a
# 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
"*** YOUR CODE HERE ***"
points_scored = 0
if num_rolls :
points_scored = roll_dice(num_rolls, dice)
else :
points_scored = free_bacon(opponent_score)
return points_scored
# 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 ***"
n_CD , n_GCD = 1 , 1
while n_CD <= min(player_score , opponent_score) :
if player_score % n_CD == 0 and opponent_score % n_CD == 0 :
n_GCD = n_CD
n_CD += 1
if n_GCD < 10:
return False
else :
return True
# n_GCD = 2
# flag = False
# if player_score == 0 or opponent_score == 0 :
# return False
# while n_GCD <= min(player_score , opponent_score) :
# if player_score % opponent_score == 0 or opponent_score % player_score == 0 :
# n_GCD = min(player_score , opponent_score)
# if n_GCD < 10:
# return False
# else :
# return True
# if player_score % n_GCD == 0 and opponent_score % n_GCD == 0 :
# if n_GCD < 10:
# return False
# else :
# return True
# n_GCD += 1
# 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
"*** YOUR CODE HERE ***"
if player_score < opponent_score :
if opponent_score - player_score < 3:
return True
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 ***"
while score0 < goal and score1 < goal :
if who == 0 :
num_rolls_0 = strategy0(score0 , score1)
score = take_turn(num_rolls_0, score1, dice)
score0 = score0 + score
say = say(score0, score1)
if score0 >= goal :
break
else :
while extra_turn(score0, score1) :
num_rolls_0 = strategy0(score0, score1)
score = take_turn(num_rolls_0, score1, dice)
score0 = score0 + score
say = say(score0, score1)
if not (score0 < goal):
return score0, score1
who = other(who)
if who == 1 :
num_rolls_1 = strategy1(score1 , score0)
score = take_turn(num_rolls_1, score0, dice)
score1 = score1 + score
say = say(score0, score1)
if not (score1 < goal):
break
while extra_turn(score1, score0) :
num_rolls_1 = strategy1(score1, score0)
score = take_turn(num_rolls_1, score0, dice)
score1 = score1 + score
say = say(score0, score1)
if not (score1 < goal):
return score0, score1
who = other(who)
"""
>>> #
>>> s0, s1 = play(always_roll(3), always_roll(3), dice=make_test_dice(1, 2, 3, 3), goal=8, say=both(say_scores, announce_lead_changes()))
Player 0 now has 1 and Player 1 now has 0
Player 0 takes the lead by 1
Player 0 now has 1 and Player 1 now has 1
Player 0 now has 2 and Player 1 now has 1
Player 0 takes the lead by 1
Player 0 now has 2 and Player 1 now has 9
Player 1 takes the lead by 7
"""
# END PROBLEM 5
# (note that the indentation for the problem 6 prompt (***YOUR CODE HERE***) might be misleading)
# BEGIN PROBLEM 6
"*** YOUR CODE HERE ***"
# END PROBLEM 6
return score0, score1
#######################
# Phase 2: Commentary #
#######################
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
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_lead_changes(leader)
return say
def both(f, g):
"""Return a commentary function that says what f says, then what g says.
NOTE: the following game is not possible under the rules, it's just
an example for the sake of the doctest
>>> 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, 8)
Player 0 now has 10 and Player 1 now has 8
>>> h3 = h2(10, 17)
Player 0 now has 10 and Player 1 now has 17
Player 1 takes the lead by 7
"""
def say(score0, score1):
return both(f(score0, score1), g(score0, score1))
return say
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, 9)
9 point(s)! The most yet for Player 1
>>> f3 = f2(20, 9)
>>> f4 = f3(20, 30)
21 point(s)! The most yet for Player 1
>>> f5 = f4(20, 47) # Player 1 gets 17 points; not enough for a new high
>>> f6 = f5(21, 47)
>>> f7 = f6(21, 77)
30 point(s)! The most yet for Player 1
"""
assert who == 0 or who == 1, 'The who argument should indicate a player.'
# BEGIN PROBLEM 7
"*** YOUR CODE HERE ***"
# the score from last turn (last_score)
# the highest gain for the player so far, which is store as running_high.
# Hint: The announce_lead_changes function provided to you is an example of how to keep track of information using commentary functions.
def say(scores0, scores1) :
# something
if who == 0 :
last_score_0 = last_score
running_high_0 = scores0 - last_score_0
running_high_0_max = running_high
if running_high_0_max < running_high_0 :
running_high_0_max = running_high_0
print(running_high_0_max,'point(s)! The most yet for Player 0')
last_score_0 = scores0
#something
return announce_highest(who, last_score_0, running_high_0_max)
elif who == 1:
last_score_1 = last_score
running_high_1 = scores1 - last_score_1
running_high_1_max = running_high
if running_high_1_max < running_high_1 :
running_high_1_max = running_high_1
print(running_high_1_max,'point(s)! The most yet for Player 1')
last_score_1 = scores1
return announce_highest(who, last_score_1, running_high_1_max)
#something
#return announce_highest(who, last_score, running_high)
return say
# END PROBLEM 7
#######################
# Phase 3: Strategies #
#######################
def always_roll(n):
"""Return a strategy that always rolls N dice.
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.
>>> strategy = always_roll(5)
>>> strategy(0, 0)
5
>>> strategy(99, 99)
5
"""
def strategy(score, opponent_score):
return n
return strategy
def make_averaged(original_function, trials_count=1000):
"""Return a function that returns the average value of ORIGINAL_FUNCTION
when called.
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(dice, 1000)
>>> averaged_dice()
3.0
"""
# BEGIN PROBLEM 8
"*** YOUR CODE HERE ***"
def new_fun(*arg):
sum = 0
count = trials_count
while count:
num = original_function(*arg)
sum = sum + num
count -= 1
average = sum / trials_count
return average
return new_fun
# END PROBLEM 8
def max_scoring_num_rolls(dice=six_sided, trials_count=1000):
"""Return the number of dice (1 to 10) that gives the highest average turn
score by calling roll_dice with the provided DICE over TRIALS_COUNT 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 ***"
"""
def roll_dice(num_rolls, dice=six_sided): return sum ,don't consider 0 dice rolls each turn
def make_averaged(original_function, trials_count=1000):Return a function that returns the average value of ORIGINAL_FUNCTION
when called.
If two numbers of rolls are tied for the maximum average score,
return the lower number. For example,
if both 3 and 6 achieve a maximum average score, return 3.
>>> dice = make_test_dice(4, 2, 5, 1)
>>> averaged_dice = make_averaged(dice, 1000)
>>> averaged_dice()
3.0
>>> dice = make_test_dice(3, 1, 5, 6)
>>> averaged_roll_dice = make_averaged(roll_dice, 5)
>>> averaged_roll_dice(2, dice)
5.0
>>> dice = make_test_dice(1, 2, 2, 2, 2, 2, 2, 2)
>>> max_scoring_num_rolls(dice, trials_count=1000)
4
>>> dice = make_test_dice(1, 2, 3, 4, 5) # dice sweeps from 1 through 5
>>> max_scoring_num_rolls(dice, trials_count=1000)
3
"""
"""
网上看到的:
max_roll = 0
num_of_dice = 10
max_number_of_dice = 0
while num_of_dice > 0:
current_rool = make_averaged(roll_dice, trials_count)(num_of_dice, dice)
if current_rool > max_roll:
max_roll = current_rool
max_number_of_dice = num_of_dice
num_of_dice -= 1
return max_number_of_dice
————————————————
版权声明:本文为CSDN博主「hiccgoal」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42103298/article/details/108855216
我觉得:要是3,6都返回同一个average的话,应该返回的是3,但是这个返回6
自己写一下:
"""
max_average = 0 #最大的平均数
current_average = 0 #当前求的平均数
loop_num_roll = 1 #循环的色子数,从1,开始找最大平均值,
max_average_of_min_num_rolls = 0
while loop_num_roll < 11:
current_average = make_averaged(roll_dice,trials_count)(loop_num_roll,dice)
if current_average > max_average :
max_average = current_average
max_average_of_min_num_rolls = loop_num_roll
loop_num_roll += 1
return max_average_of_min_num_rolls
# """
# if now num_rolls = 1
# averages[11] = 0
# n = 1
max_average_num_rolls = 0
temp = make_averaged(roll_dice, trials_count)
# while not (n > 11):
# averages[n] = temp(1, dice)
average_1 = temp(1, dice)
average_2 = temp(2, dice)
average_3 = temp(3, dice)
average_4 = temp(4, dice)
average_5 = temp(5, dice)
average_6 = temp(6, dice)
average_7 = temp(7, dice)
average_8 = temp(8, dice)
average_9 = temp(9, dice)
average_10 = temp(10, dice)
# 从1到10 10个average 找到最大的 average 返回对应的 num_rolls
# temp = make_averaged(roll_dice, trials_count)
# average_1 = 0
# average_2 = 0
# average_3 = 0
# average_4 = 0
# average_5 = 0
# average_6 = 0
# average_7 = 0
# average_8 = 0
# average_9 = 0
# average_10 = 0
max_average = max(average_1,average_2,average_3,average_4,average_5,average_6,average_7,average_8,average_9,average_10)
if average_1 == max_average :
max_average_num_rolls = 1
elif average_2 == max_average :
max_average_num_rolls = 2
elif average_3 == max_average :
max_average_num_rolls = 3
elif average_4 == max_average :
max_average_num_rolls = 4
elif average_5 == max_average :
max_average_num_rolls = 5
elif average_6 == max_average :
max_average_num_rolls = 6
elif average_7 == max_average :
max_average_num_rolls = 7
elif average_8 == max_average :
max_average_num_rolls = 8
elif average_9 == max_average :
max_average_num_rolls = 9
elif average_10 == max_average :
max_average_num_rolls = 10
return max_average_num_rolls #能达到最大平均数的最小色子数
# END PROBLEM 9
def winner(strategy0, strategy1):
"""Return 0 if strategy0 wins against strategy1, and 1 otherwise."""
score0, score1 = play(strategy0, strategy1)
if score0 > score1:
return 0
else:
return 1
def average_win_rate(strategy, baseline=always_roll(6)):
"""Return the average win rate of STRATEGY against BASELINE. Averages the
winrate when starting the game as player 0 and as player 1.
"""
win_rate_as_player_0 = 1 - make_averaged(winner)(strategy, baseline)
win_rate_as_player_1 = make_averaged(winner)(baseline, strategy)
return (win_rate_as_player_0 + win_rate_as_player_1) / 2
def run_experiments():
"""Run a series of strategy experiments and report results."""
if True: # Change to False when done finding max_scoring_num_rolls
six_sided_max = max_scoring_num_rolls(six_sided)
print('Max scoring num rolls for six-sided dice:', six_sided_max)
if True : #False: # Change to True to test always_roll(8)
print('always_roll(8) win rate:', average_win_rate(always_roll(8)))
if True : #False: # Change to True to test always_roll(4) 这是我自己复制的
print('always_roll(4) win rate:', average_win_rate(always_roll(4)))
if True : #False: # Change to True to test bacon_strategy
print('bacon_strategy win rate:', average_win_rate(bacon_strategy))
if True : #False: # Change to True to test extra_turn_strategy
print('extra_turn_strategy win rate:', average_win_rate(extra_turn_strategy))
if True : #False: # Change to True to test final_strategy
print('final_strategy win rate:', average_win_rate(final_strategy))
"*** You may add additional experiments as you wish ***"
def bacon_strategy(score, opponent_score, cutoff=8, num_rolls=6):
"""This strategy rolls 0 dice if that gives at least CUTOFF points, and
rolls NUM_ROLLS otherwise.
"""
# BEGIN PROBLEM 10
"""
bacon_strategy() ,returns 0 whenever rolling 0 would give at least cutoff points and returns num_rolls otherwise.
def free_bacon(oppent_score):return somevalue + 3
"""
score_now = free_bacon(opponent_score)
if score_now < cutoff :
return num_rolls
else :
return 0
return 6 # Replace this statement
# END PROBLEM 10
def extra_turn_strategy(score, opponent_score, cutoff=8, num_rolls=6):
"""This strategy rolls 0 dice when it triggers an extra turn. It also
rolls 0 dice if it gives at least CUTOFF points and does not give an extra turn.
Otherwise, it rolls NUM_ROLLS.
"""
# BEGIN PROBLEM 11
"""
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))
FIRST_101_DIGITS_OF_PI = 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
"""
now_scored = free_bacon(opponent_score) + score
if extra_turn(now_scored, opponent_score):
return 0
else :
return bacon_strategy(score, opponent_score, cutoff, num_rolls)
return 6 # Replace this statement
# END PROBLEM 11
def final_strategy(score, opponent_score):
"""Write a brief description of your final strategy.
*** YOUR DESCRIPTION HERE ***
"""
# BEGIN PROBLEM 12
return extra_turn_strategy(score, opponent_score)
return 6 # Replace this statement
# END PROBLEM 12
##########################
# Command Line Interface #
##########################
# NOTE: Functions in this section do not need to be changed. They use features
# of Python not yet covered in the course.
@main
def run(*args):
"""Read in the command-line argument and calls corresponding functions."""
import argparse
parser = argparse.ArgumentParser(description="Play Hog")
parser.add_argument('--run_experiments', '-r', action='store_true',
help='Runs strategy experiments')
args = parser.parse_args()
if args.run_experiments:
run_experiments()