一亩三分地论坛

 找回密码
 获取更多干货,去instant注册!

扫码关注一亩三分地公众号
查看: 3551|回复: 17
收起左侧

[CS61A]Hog

[复制链接] |试试Instant~ |关注本帖
sky420 发表于 2015-5-6 05:51:40 | 显示全部楼层 |阅读模式

[其他]CS61A #1 - 4@UCBerkely

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看,没有帐号?获取更多干货,去instant注册!

x
本帖最后由 AveMaleficum 于 2015-5-7 01:39 编辑

第一个project, Hog。还没有开始做,不过既然Project是一个游戏,应该还是蛮有意思的吧
http://gaotx.com/cs61a/proj/hog/
goldpanda 发表于 2015-5-10 04:11:58 | 显示全部楼层
from dice import four_sided, six_sided, make_test_dice
from ucb import main, trace, log_current_line, interact

GOAL_SCORE = 100 # The goal of Hog is to score 100 points.

######################
# Phase 1: Simulator #
######################

def roll_dice(num_rolls, dice=six_sided):
    assert type(num_rolls) == int, 'num_rolls must be an integer.'
    assert num_rolls > 0, 'Must roll at least once.'
   
    sum = 0
    for i in range(0, num_rolls):
        outcome = dice()
        if outcome == 1:
            return 1
        else:
            sum += outcome
    return outcome

def take_turn(num_rolls, opponent_score, dice=six_sided):
    assert type(num_rolls) == int, 'num_rolls must be an integer.'
    assert num_rolls >= 0, 'Cannot roll a negative number of dice.'
    assert num_rolls <= 10, 'Cannot roll more than 10 dice.'
    assert opponent_score < 100, 'The game should be over.'
   
    if num_rolls == 0:
        return 1 + max(opponent_score%10,opponent_score//10)
    else:
        return roll_dice(num_rolls, dice)

def select_dice(score, opponent_score):
    if ((score + opponent_score) % 7 == 0) and (score+opponent_score != 0):
        return four_sided
    else:
        return six_sided

def is_prime(n):
    assert type(n) == int, 'n must be an integer.'
    assert n >= 0, 'n must be non-negative.'
   
    if n == 1:
        return False
   
    k = 2
    while k < n:
        if n % k == 0:
            return False
        else:
            k += 1
    return True

def other(who):
    return 1 - who

def play(strategy0, strategy1, score0=0, score1=0, goal=GOAL_SCORE):
    who = 0  # Which player is about to take a turn, 0 (first) or 1 (second)
   
    while (score0 < goal) and (score1 < goal):
        if who == 0:
            num_rolls = strategy0(score0, score1)
            dice = select_dice(score0, score1)
            score = take_turn(num_rolls, score1, dice)
            score0 += score
        else:
            num_rolls = strategy1(score1, score0)
            dice = select_dice(score1, score0)
            score = take_turn(num_rolls, score0, dice)
            score1 += score
        if is_prime(score0 + score1):
            if score0 > score1:
                score0 += score
            elif score1 > score0:
                score1 += score
        who = other(who)

    return score0, score1  # You may want to change this line.

#######################
# Phase 2: 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

# Experiments

def make_averaged(fn, num_samples=1000):
    """Return a function that returns the average_value of FN 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(3, 1, 5, 6)
    >>> averaged_dice = make_averaged(dice, 1000)
    >>> averaged_dice()
    3.75
    >>> make_averaged(roll_dice, 1000)(2, dice)
    6.0

    In this last example, two different turn scenarios are averaged.
    - In the first, the player rolls a 3 then a 1, receiving a score of 1.
    - In the other, the player rolls a 5 and 6, scoring 11.
    Thus, the average value is 6.0.
    """

    def aver(*args):
        sum = 0
        for i in range(num_samples):
            sum += fn(*args)
        return sum / num_samples

    return aver

def max_scoring_num_rolls(dice=six_sided):
    """Return the number of dice (1 to 10) that gives the highest average turn
    score by calling roll_dice with the provided DICE.  Assume that dice always
    return positive outcomes.

    >>> dice = make_test_dice(3)
    >>> max_scoring_num_rolls(dice)
    10
    """
    num_rolls = 0
    aver = 0
    for i in range(1,11):
        current_value = make_averaged(roll_dice)(i, dice)
        if current_value > aver:
            aver = current_value
            num_rolls = i
    return num_rolls
   
def winner(strategy0, strategy1):
    score0, score1 = play(strategy0, strategy1)
    if score0 > score1:
        return 0
    else:
        return 1

def average_win_rate(strategy, baseline=always_roll(5)):
    """Return the average win rate (0 to 1) of STRATEGY against BASELINE."""
    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 # Average results

def run_experiments():
    """Run a series of strategy experiments and report results."""
    if False: # 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)
        four_sided_max = max_scoring_num_rolls(four_sided)
        print('Max scoring num rolls for four-sided dice:', four_sided_max)

    if False: # Change to True to test always_roll(8)
        print('always_roll(8) win rate:', average_win_rate(always_roll(8)))

    if False: # Change to True to test bacon_strategy
        print('bacon_strategy win rate:', average_win_rate(bacon_strategy))

    if False: # Change to True to test prime_strategy
        print('prime_strategy win rate:', average_win_rate(prime_strategy))

    if True: # 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 ***"

# Strategies

def bacon_strategy(score, opponent_score, margin=8, num_rolls=5):
    if take_turn(0, opponent_score) >= margin:
        return 0
    else:
        return num_rolls
   
def prime_strategy(score, opponent_score, margin=8, num_rolls=5):
    bacon_points = take_turn(0, opponent_score)
    current_score = score + bacon_points
    if is_prime(current_score + opponent_score):
        if current_score > opponent_score:
            return 0
        elif current_score < opponent_score:
            return num_rolls
    return bacon_strategy(score, opponent_score, margin, num_rolls)

def final_strategy(score, opponent_score):
    if score - opponent_score > 15:
        if score > 80:
            return 0
   
    elif opponent_score - score > 80:
        return 10
    elif opponent_score - score > 60:
        return 8
    elif opponent_score - score > 40:
        return 6
    elif opponent_score - score > 20:
        return 5

    if select_dice(score+take_turn(0, opponent_score),
                                opponent_score) == four_sided:
        return 0
    if select_dice(score,opponent_score) == four_sided:
        return 2
    else:
        return 5

##########################
# 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.

    This function uses Python syntax/techniques not yet covered in this course.
    """
    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()

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

 楼主| sky420 发表于 2015-5-11 04:45:25 | 显示全部楼层
"""The Game of Hog."""

from dice import four_sided, six_sided, make_test_dice
from ucb import main, trace, log_current_line, interact

GOAL_SCORE = 100 # The goal of Hog is to score 100 points.

######################
# Phase 1: Simulator #
######################

def roll_dice(num_rolls, dice=six_sided):
    """Roll DICE for NUM_ROLLS times. Return either the sum of the outcomes,
    or 1 if a 1 is rolled (Pig out). This calls DICE exactly NUM_ROLLS times.

    num_rolls:  The number of dice rolls that will be made; at least 1.
    dice:       A zero-argument function that returns an integer 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.'
   
    outcomes = 0
    i = 0
    while i < num_rolls:
        outcome = dice()
        if outcome == 1:
            return 1
        else:
            outcomes += outcome
        i += 1
    return outcomes

def take_turn(num_rolls, opponent_score, dice=six_sided):
    """Simulate a turn rolling NUM_ROLLS dice, which may be 0 (Free bacon).

    num_rolls:       The number of dice rolls that will be made.
    opponent_score:  The total score of the opponent.
    dice:            A function of no args that returns an integer outcome.
    """
    assert type(num_rolls) == int, 'num_rolls must be an integer.'
    assert num_rolls >= 0, 'Cannot roll a negative number of dice.'
    assert num_rolls <= 10, 'Cannot roll more than 10 dice.'
    assert opponent_score < 100, 'The game should be over.'
    if num_rolls == 0:
        ones = opponent_score % 10
        tens = opponent_score // 10
        return 1 + max(ones, tens)
    return roll_dice(num_rolls, dice)

def select_dice(score, opponent_score):
    """Select six-sided dice unless the sum of SCORE and OPPONENT_SCORE is a
    multiple of 7, in which case select four-sided dice (Hog wild).
    """
    sum = score + opponent_score
    if sum % 7 == 0 and sum != 0:
        return four_sided
    return six_sided

def is_prime(n):
    """Return True if a non-negative number N is prime, otherwise return
    False. 1 is not a prime number!
    """
    assert type(n) == int, 'n must be an integer.'
    assert n >= 0, 'n must be non-negative.'
    if n == 1:
        return False
    k = 2
    while k < n:
        if n % k == 0:
            return False
        k += 1
    return True


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 play(strategy0, strategy1, score0=0, score1=0, goal=GOAL_SCORE):
    """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   :  The starting score for Player 0
    score1   :  The starting score for Player 1
    """
    who = 0  # Which player is about to take a turn, 0 (first) or 1 (second)
    while max(score0, score1) < goal:
        if who == 0:
            dice = select_dice(score0, score1)
            num_rolls = strategy0(score0, score1)
            score = take_turn(num_rolls, score1, dice)
            score0 += score
        else:
            dice = select_dice(score1, score0)
            num_rolls = strategy1(score1, score0)
            score = take_turn(num_rolls, score0, dice)
            score1 += score
        if is_prime(score0 + score1):
            if score0 > score1:
                score0 += score
            elif score0 < score1:
                score1 += score
        who = other(who)
    return score0, score1  # You may want to change this line.

#######################
# Phase 2: 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

# Experiments

def make_averaged(fn, num_samples=1000):
    """Return a function that returns the average_value of FN 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(3, 1, 5, 6)
    >>> averaged_dice = make_averaged(dice, 1000)
    >>> averaged_dice()
    3.75
    >>> make_averaged(roll_dice, 1000)(2, dice)
    6.0

    In this last example, two different turn scenarios are averaged.
    - In the first, the player rolls a 3 then a 1, receiving a score of 1.
    - In the other, the player rolls a 5 and 6, scoring 11.
    Thus, the average value is 6.0.
    """
    def avg(*args):
        i, total = 0, 0
        while i < num_samples:
            total += fn(*args)
            i += 1
        return total / num_samples
    return avg     

def max_scoring_num_rolls(dice=six_sided):
    """Return the number of dice (1 to 10) that gives the highest average turn
    score by calling roll_dice with the provided DICE.  Assume that dice always
    return positive outcomes.

    >>> dice = make_test_dice(3)
    >>> max_scoring_num_rolls(dice)
    10
    """
    num_rolls, i = 0, 1
    pre_scoring = 0
    while i <= 10:
        curr_scoring = make_averaged(roll_dice)(i, dice)
        if curr_scoring > pre_scoring:
            num_rolls, pre_scoring = i, curr_scoring
        i += 1
    return num_rolls

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(5)):
    """Return the average win rate (0 to 1) of STRATEGY against BASELINE."""
    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 # Average results

def run_experiments():
    """Run a series of strategy experiments and report results."""
    if False: # 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)
        four_sided_max = max_scoring_num_rolls(four_sided)
        print('Max scoring num rolls for four-sided dice:', four_sided_max)

    if False: # Change to True to test always_roll(8)
        print('always_roll(8) win rate:', average_win_rate(always_roll(8)))

    if False: # Change to True to test bacon_strategy
        print('bacon_strategy win rate:', average_win_rate(bacon_strategy))

    if False: # Change to True to test prime_strategy
        print('prime_strategy win rate:', average_win_rate(prime_strategy))

    if True: # 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 ***"

# Strategies

def bacon_strategy(score, opponent_score, margin=8, num_rolls=5):
    """This strategy rolls 0 dice if that gives at least MARGIN points,
    and rolls NUM_ROLLS otherwise.
    """
    if take_turn(0, opponent_score) >= margin:
        return 0
    return num_rolls

def prime_strategy(score, opponent_score, margin=8, num_rolls=5):
    """This strategy rolls 0 dice when it results in a beneficial boost and
    rolls NUM_ROLLS if rolling 0 dice gives the opponent a boost. It also
    rolls 0 dice if that gives at least MARGIN points and rolls NUM_ROLLS
    otherwise.
    """
    bacan_score = take_turn(0, opponent_score)
    curr_score = score + bacan_score
    if is_prime(curr_score + opponent_score):
        if curr_score > opponent_score:
            return 0
        else:
            return num_rolls
    return bacon_strategy(score, opponent_score, margin, num_rolls)

from functools import lru_cache
memoize = lru_cache(None)

def final_strategy(score, opponent_score):
    """Write a brief description of your final strategy.

    *** YOUR DESCRIPTION HERE ***
    """
    num_rolls = 5
    bacan_score = score + take_turn(0, opponent_score)

    # bacon
    if bacan_score >= 100:
        return 0

    # prime
    if is_prime(bacan_score + opponent_score):
        if bacan_score > opponent_score:
            return 0
        else:
            return num_rolls
    # near 100
    if 100-score <= 20:
        return 2
    # in lead
    if score - opponent_score > 20:
        return 3
    # losing
    if opponent_score - score > 20:
        return num_rolls + 2
    # general
    return num_rolls





##########################
# 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.

    This function uses Python syntax/techniques not yet covered in this course.
    """
    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()

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

dreamvsfact 发表于 2015-5-27 03:20:02 | 显示全部楼层
请问楼上各位使用ok file 进行test 了吗? 楼上两位的code 貌似都没有100% 通过test 呀。。。
回复 支持 反对

使用道具 举报

 楼主| sky420 发表于 2015-5-28 01:52:09 | 显示全部楼层
dreamvsfact 发表于 2015-5-27 03:20
请问楼上各位使用ok file 进行test 了吗? 楼上两位的code 貌似都没有100% 通过test 呀。。。

我自己写了几个test,没有用OK做test。嗯,是应该用OK再试一下
回复 支持 反对

使用道具 举报

wkh279 发表于 2015-7-17 20:20:10 | 显示全部楼层
本帖最后由 wkh279 于 2015-7-17 20:29 编辑

这个Project做了挺久的,但是很有意思哈,只是最后一问Final的策略,可能自己没优化好,Python跑了大概半个小时才出结果,不过好歹胜率有0.564,超过了他0.56的要求哈
"""The Game of Hog."""

from dice import four_sided, six_sided, make_test_dice
from ucb import main, trace, log_current_line, interact

GOAL_SCORE = 100 # The goal of Hog is to score 100 points.

######################
# Phase 1: Simulator #
######################

def roll_dice(num_rolls, dice=six_sided):
    """Roll DICE for NUM_ROLLS times. Return either the sum of the outcomes,
    or 1 if a 1 is rolled (Pig out). This calls DICE exactly NUM_ROLLS times.

    num_rolls:  The number of dice rolls that will be made; at least 1.
    dice:       A zero-argument function that returns an integer 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.'
    outcome,flag=0,0
    for i in range(num_rolls):
        dice_now=dice()
        if dice_now==1:
            flag=1
        outcome+=dice_now
    if flag==1:outcome=1
    return outcome



def take_turn(num_rolls, opponent_score, dice=six_sided):
    """Simulate a turn rolling NUM_ROLLS dice, which may be 0 (Free bacon).

    num_rolls:       The number of dice rolls that will be made.
    opponent_score:  The total score of the opponent.
    dice:            A function of no args that returns an integer outcome.
    """
    assert type(num_rolls) == int, 'num_rolls must be an integer.'
    assert num_rolls >= 0, 'Cannot roll a negative number of dice.'
    assert num_rolls <= 10, 'Cannot roll more than 10 dice.'
    assert opponent_score < 100, 'The game should be over.'
    if num_rolls>0:
        return roll_dice(num_rolls,dice)
    else:
        x,y=opponent_score//10,opponent_score%10
        return max(x,y)+1

def select_dice(score, opponent_score):
    """Select six-sided dice unless the sum of SCORE and OPPONENT_SCORE is a
    multiple of 7, in which case select four-sided dice (Hog wild).
    """
    sum_score=score+opponent_score
    if sum_score%7==0:
        return four_sided
    else:
        return six_sided



def is_prime(n):
    """Return True if a non-negative number N is prime, otherwise return
    False. 1 is not a prime number!
    """
    assert type(n) == int, 'n must be an integer.'
    assert n >= 0, 'n must be non-negative.'
    if n<=1:return False
    k = 2
    while k < n:
        if n % k == 0:
            return False
        k+=1
    return True


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 play(strategy0, strategy1, score0=0, score1=0, goal=GOAL_SCORE):
    """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   :  The starting score for Player 0
    score1   :  The starting score for Player 1
    """
    who = 0  # Which player is about to take a turn, 0 (first) or 1 (second)
    while score0<goal and score1<goal:
        if who==0:
            score,opponent_score=score0,score1
            strategy=strategy0
        else:
            score,opponent_score=score1,score0
            strategy=strategy1
        num_rolls=strategy(score,opponent_score)
        dice=select_dice(score,opponent_score)
        roll=take_turn(num_rolls,opponent_score,dice)
        score+=roll
        if is_prime(score+opponent_score):
            if score>opponent_score: score+=roll
            elif score<opponent_score: opponent_score+=roll
        if who==0: score0,score1=score,opponent_score
        else: score0,score1=opponent_score,score
        who=other(who)
    return score0, score1  # You may want to change this line.

#######################
# Phase 2: 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

# Experiments

def make_averaged(fn, num_samples=1000):
    """Return a function that returns the average_value of FN 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(3, 1, 5, 6)
    >>> averaged_dice = make_averaged(dice, 1000)
    >>> averaged_dice()
    3.75
    >>> make_averaged(roll_dice, 1000)(2, dice)
    6.0

    In this last example, two different turn scenarios are averaged.
    - In the first, the player rolls a 3 then a 1, receiving a score of 1.
    - In the other, the player rolls a 5 and 6, scoring 11.
    Thus, the average value is 6.0.
    """
    def g(*args):
        sum_value=0
        for i in range(num_samples):
            sum_value+=fn(*args)
        return sum_value/num_samples
    return g
   



def max_scoring_num_rolls(dice=six_sided):
    """Return the number of dice (1 to 10) that gives the highest average turn
    score by calling roll_dice with the provided DICE.  Assume that dice always
    return positive outcomes.

    >>> dice = make_test_dice(3)
    >>> max_scoring_num_rolls(dice)
    10
    """
    rolls,max_averaged=0,0
    for i in range(1,11):
        average=make_averaged(roll_dice)(i,dice)
        if average>max_averaged:
            max_averaged=average
            rolls=i
    return rolls

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(5)):
    """Return the average win rate (0 to 1) of STRATEGY against BASELINE."""
    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 # Average results

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)
        four_sided_max = max_scoring_num_rolls(four_sided)
        print('Max scoring num rolls for four-sided dice:', four_sided_max)

    if True: # Change to True to test always_roll(8)
        print('always_roll(8) win rate:', average_win_rate(always_roll(8)))

    if True: # Change to True to test bacon_strategy
        print('bacon_strategy win rate:', average_win_rate(bacon_strategy))

    if True: # Change to True to test prime_strategy
        print('prime_strategy win rate:', average_win_rate(prime_strategy))

    if True: # 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 ***"

# Strategies

def bacon_strategy(score, opponent_score, margin=8, num_rolls=5):
    """This strategy rolls 0 dice if that gives at least MARGIN points,
    and rolls NUM_ROLLS otherwise.
    """
    if take_turn(0,opponent_score)>=margin:
        return 0
    else:
        return num_rolls



    return None # Replace this statement

def prime_strategy(score, opponent_score, margin=8, num_rolls=5):
    """This strategy rolls 0 dice when it results in a beneficial boost and
    rolls NUM_ROLLS if rolling 0 dice gives the opponent a boost. It also
    rolls 0 dice if that gives at least MARGIN points and rolls NUM_ROLLS
    otherwise.
    """
    zero_roll= take_turn(0,opponent_score)
    score+=zero_roll
    if is_prime(score+opponent_score):
        if score>opponent_score:
            return 0
        elif score<opponent_score:
            return num_rolls
    if zero_roll>=margin:
        return 0
    else:
        return num_rolls

def final_strategy(score, opponent_score):
"""This strategy rolls NUM_ROLLS if rolling 0 dice gives the opponent a boost.
        If rolling 0 results in a beneficial boost, it compares the highest average turn
        score (of which the number of dice (1 to 10) is max_rolls) and the score of rolling
        0 dice (boost already added), then return the number of dice(max_rolls or 0) of the
        larger one.
    If rolling 0 results in no boost, it simply compares the result of the highest average
        turn scoreand the score of rolling 0 dice(no boost), then return the number of dice
        (max_rolls or 0) of the larger one.
    final_strategy win rate: 0.5640000000000001
    """
    dice=select_dice(score,opponent_score)
    max_rolls=max_scoring_num_rolls(dice)
    max_num=make_averaged(roll_dice)(max_rolls,dice)
    zero_roll_num=take_turn(0,opponent_score)
    score+=zero_roll_num
    if is_prime(score+opponent_score):
        if score<opponent_score: return max_rolls
        if score>opponent_score:
            if max_num>2*zero_roll_num:
                return max_rolls
            else:
                return 0
    else:
        if max_num>zero_roll_num: return max_rolls
        else: return 0

##########################
# 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.

    This function uses Python syntax/techniques not yet covered in this course.
    """
    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()

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

fubupc 发表于 2015-9-15 11:25:33 | 显示全部楼层
这个 HOG 项目的 第5个 测试没法通过。好像是因为少了 always 函数, 还有它要求 筛子 是固定的(非随机)的才行。
回复 支持 反对

使用道具 举报

rainbow0206 发表于 2015-9-30 09:57:37 | 显示全部楼层
做了挺久,最后的最后胜率达不到0.77,有人做出来超过0.77的吗? hog_10.png


回复 支持 反对

使用道具 举报

lh6210 发表于 2015-9-30 11:06:16 | 显示全部楼层
请问一下:

Assignment: Lab 0
OK, version v1.4.1
=====================================================================

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running tests

---------------------------------------------------------------------
Test summary
    1 test cases passed! No cases failed.

Performing authentication
Please enter your bCourses email.
bCourses email:  xxxx@gmail.com
输入后,提示以下内容,不知 怎么 enroll呢?  望指教
okquestion.png
回复 支持 反对

使用道具 举报

rainbow0206 发表于 2015-10-1 02:20:17 | 显示全部楼层
lh6210 发表于 2015-9-30 11:06
请问一下:

Assignment: Lab 0

不是ucb学生不能enroll
回复 支持 反对

使用道具 举报

lh6210 发表于 2015-10-1 09:25:26 | 显示全部楼层
rainbow0206 发表于 2015-10-1 02:20
不是ucb学生不能enroll

噢,明白了。
那做完实验还是可以用 OK 来验证下是否正确的对吗?
回复 支持 反对

使用道具 举报

rainbow0206 发表于 2015-10-1 09:29:50 | 显示全部楼层
lh6210 发表于 2015-10-1 09:25
噢,明白了。
那做完实验还是可以用 OK 来验证下是否正确的对吗?

对,test超好用,先test是否理解了,再test写得代码,很好用。
回复 支持 反对

使用道具 举报

Liaeve 发表于 2015-10-22 17:21:17 | 显示全部楼层
为什么我计算胜率的时候,除了预置的True可以输出结果,其他任何一个改成True以后都只输出空白?
回复 支持 反对

使用道具 举报

liyimeng 发表于 2016-1-14 10:49:50 | 显示全部楼层
求加分!!!!
hog.png

另外是代码:
  1. """The Game of Hog."""

  2. from dice import four_sided, six_sided, make_test_dice
  3. from ucb import main, trace, log_current_line, interact

  4. GOAL_SCORE = 100 # The goal of Hog is to score 100 points.

  5. ######################
  6. # Phase 1: Simulator #
  7. ######################

  8. def roll_dice(num_rolls, dice=six_sided):
  9.         """Roll DICE for NUM_ROLLS times. Return either the sum of the outcomes,
  10.         or 1 if a 1 is rolled (Pig out). This calls DICE exactly NUM_ROLLS times.

  11.         num_rolls:  The number of dice rolls that will be made; at least 1.
  12.         dice:       A zero-argument function that returns an integer outcome.
  13.         """
  14.         # These assert statements ensure that num_rolls is a positive integer.
  15.         assert type(num_rolls) == int, 'num_rolls must be an integer.'
  16.         assert num_rolls > 0, 'Must roll at least once.'
  17.         "*** YOUR CODE HERE ***"
  18.         i = 0
  19.         outcome = 0
  20.         pig_out = False     
  21.         for i in range(num_rolls):
  22.                 tmp = dice()
  23.                 if tmp == 1:
  24.                         pig_out = True # Special case: pig out, but the iteration should be continued
  25.                 outcome += tmp

  26.         if pig_out == True:
  27.                 return 1
  28.         else:
  29.                 return outcome


  30. def take_turn(num_rolls, opponent_score, dice=six_sided):
  31.         """Simulate a turn rolling NUM_ROLLS dice, which may be 0 (Free bacon).

  32.         num_rolls:       The number of dice rolls that will be made.
  33.         opponent_score:  The total score of the opponent.
  34.         dice:            A function of no args that returns an integer outcome.
  35.         """
  36.         assert type(num_rolls) == int, 'num_rolls must be an integer.'
  37.         assert num_rolls >= 0, 'Cannot roll a negative number of dice.'
  38.         assert num_rolls <= 10, 'Cannot roll more than 10 dice.'
  39.         assert opponent_score < 100, 'The game should be over.'
  40.         "*** YOUR CODE HERE ***"
  41.         # Normal case:
  42.         if num_rolls > 0:
  43.                 return roll_dice(num_rolls, dice)
  44.         max_num = -1
  45.         # Free Bacon case: Select the max digit in opponent_score
  46.         for c in str(opponent_score):
  47.                 i = int(c)
  48.                 if i > max_num:
  49.                         max_num = i

  50.         return max_num + 1


  51. def select_dice(score, opponent_score):
  52.         """Select six-sided dice unless the sum of SCORE and OPPONENT_SCORE is a
  53.         multiple of 7, in which case select four-sided dice (Hog wild).
  54.         """
  55.         "*** YOUR CODE HERE ***"
  56.         if (score + opponent_score) % 7 == 0:
  57.                 return four_sided
  58.         return six_sided


  59. def is_prime(n):
  60.         """Return True if a non-negative number N is prime, otherwise return
  61.         False. 1 is not a prime number!
  62.         """
  63.         assert type(n) == int, 'n must be an integer.'
  64.         assert n >= 0, 'n must be non-negative.'
  65.         if n == 1 or n == 0:
  66.                 return False
  67.         if n == 2 or n == 3:
  68.                 return True
  69.         k = 2
  70.         while k * 2 <= n:
  71.                 if n % k == 0:
  72.                         return False
  73.                 k += 1
  74.         return True


  75. def other(who):
  76.         """Return the other player, for a player WHO numbered 0 or 1.

  77.         >>> other(0)
  78.         1
  79.         >>> other(1)
  80.         0
  81.         """
  82.         return 1 - who


  83. def play(strategy0, strategy1, score0=0, score1=0, goal=GOAL_SCORE):
  84.         """Simulate a game and return the final scores of both players, with
  85.         Player 0's score first, and Player 1's score second.

  86.         A strategy is a function that takes two total scores as arguments
  87.         (the current player's score, and the opponent's score), and returns a
  88.         number of dice that the current player will roll this turn.

  89.         strategy0:  The strategy function for Player 0, who plays first
  90.         strategy1:  The strategy function for Player 1, who plays second
  91.         score0   :  The starting score for Player 0
  92.         score1   :  The starting score for Player 1
  93.         """
  94.         who = 0  # Which player is about to take a turn, 0 (first) or 1 (second)
  95.         "*** YOUR CODE HERE ***"
  96.         while score0 < goal and score1 < goal:
  97.                 dice = select_dice(score0, score1)
  98.                 if who == 0:
  99.                         num_rolls = strategy0(score0, score1)
  100.                         score = take_turn(num_rolls, score1, dice)
  101.                         score0 += score
  102.                 else:
  103.                         num_rolls = strategy1(score1, score0)
  104.                         score = take_turn(num_rolls, score0, dice)
  105.                         score1 += score
  106.                 # Hogtimus prime condition
  107.                 if is_prime(score0 + score1):
  108.                         if score1 > score0:
  109.                                 score1 += score
  110.                         elif score0 > score1:
  111.                                 score0 += score
  112.                 who = other(who)        # take turn
  113. #            print(str(score0) + " " + str(score1) + " " + str(tmp))
  114.         return score0, score1  # You may want to change this line.


  115. #######################
  116. # Phase 2: Strategies #
  117. #######################


  118. def always_roll(n):
  119.         """Return a strategy that always rolls N dice.

  120.         A strategy is a function that takes two total scores as arguments
  121.         (the current player's score, and the opponent's score), and returns a
  122.         number of dice that the current player will roll this turn.

  123.         >>> strategy = always_roll(5)
  124.         >>> strategy(0, 0)
  125.         5
  126.         >>> strategy(99, 99)
  127.         5
  128.         """
  129.         def strategy(score, opponent_score):
  130.                 return n
  131.         return strategy


  132. # Experiments

  133. def make_averaged(fn, num_samples=1000):
  134.         """Return a function that returns the average_value of FN when called.

  135.         To implement this function, you will have to use *args syntax, a new Python
  136.         feature introduced in this project.  See the project description.

  137.         >>> dice = make_test_dice(3, 1, 5, 6)
  138.         >>> averaged_dice = make_averaged(dice, 1000)
  139.         >>> averaged_dice()
  140.         3.75
  141.         >>> make_averaged(roll_dice, 1000)(2, dice)
  142.         6.0

  143.         In this last example, two different turn scenarios are averaged.
  144.         - In the first, the player rolls a 3 then a 1, receiving a score of 1.
  145.         - In the other, the player rolls a 5 and 6, scoring 11.
  146.         Thus, the average value is 6.0.
  147.         """
  148.         "*** YOUR CODE HERE ***"
  149.         def average_return(*args):
  150.                 result = 0
  151.                 for i in range(num_samples):
  152.                         result += fn(*args)
  153.                 return result / num_samples

  154.         return average_return


  155. def max_scoring_num_rolls(dice=six_sided):
  156.         """Return the number of dice (1 to 10) that gives the highest average turn
  157.         score by calling roll_dice with the provided DICE.  Assume that dice always
  158.         return positive outcomes.

  159.         >>> dice = make_test_dice(3)
  160.         >>> max_scoring_num_rolls(dice)
  161.         10
  162.         """
  163.         "*** YOUR CODE HERE ***"
  164.         number = 0                 # num_rolls
  165.         max_scoring = 0
  166.         for i in range(1, 11):
  167.                 score = make_averaged(roll_dice, i)(i, dice)
  168.                 if score > max_scoring:
  169.                         max_scoring = score
  170.                         number = i

  171.         return number


  172. def winner(strategy0, strategy1):
  173.         """Return 0 if strategy0 wins against strategy1, and 1 otherwise."""
  174.         score0, score1 = play(strategy0, strategy1)
  175.         if score0 > score1:
  176.                 return 0
  177.         else:
  178.                 return 1

  179. def average_win_rate(strategy, baseline=always_roll(5)):
  180.         """Return the average win rate (0 to 1) of STRATEGY against BASELINE."""
  181.         win_rate_as_player_0 = 1 - make_averaged(winner)(strategy, baseline)
  182.         win_rate_as_player_1 = make_averaged(winner)(baseline, strategy)
  183.         return (win_rate_as_player_0 + win_rate_as_player_1) / 2 # Average results

  184. def run_experiments():
  185.         """Run a series of strategy experiments and report results."""
  186.         if True: # Change to False when done finding max_scoring_num_rolls
  187.                 six_sided_max = max_scoring_num_rolls(six_sided)
  188.                 print('Max scoring num rolls for six-sided dice:', six_sided_max)
  189.                 four_sided_max = max_scoring_num_rolls(four_sided)
  190.                 print('Max scoring num rolls for four-sided dice:', four_sided_max)

  191.         if False: # Change to True to test always_roll(8)
  192.                 print('always_roll(8) win rate:', average_win_rate(always_roll(8)))

  193.         if False: # Change to True to test bacon_strategy
  194.                 print('bacon_strategy win rate:', average_win_rate(bacon_strategy))

  195.         if False: # Change to True to test prime_strategy
  196.                 print('prime_strategy win rate:', average_win_rate(prime_strategy))

  197.         if False: # Change to True to test final_strategy
  198.                 print('final_strategy win rate:', average_win_rate(final_strategy))

  199.         "*** You may add additional experiments as you wish ***"

  200. # Strategies

  201. def bacon_strategy(score, opponent_score, margin=8, num_rolls=5):
  202.         """This strategy rolls 0 dice if that gives at least MARGIN points,
  203.         and rolls NUM_ROLLS otherwise.
  204.         """
  205.         "*** YOUR CODE HERE ***"
  206.         dice = select_dice(score, opponent_score)
  207.         tmp_score = take_turn(0, opponent_score, dice)
  208.         if tmp_score >= margin:
  209.                 return 0
  210.         return num_rolls
  211.        

  212. def prime_strategy(score, opponent_score, margin=8, num_rolls=5):
  213.         """This strategy rolls 0 dice when it results in a beneficial boost and
  214.         rolls NUM_ROLLS if rolling 0 dice gives the opponent a boost. It also
  215.         rolls 0 dice if that gives at least MARGIN points and rolls NUM_ROLLS
  216.         otherwise.
  217.         """
  218.         "*** YOUR CODE HERE ***"
  219.         dice = select_dice(score, opponent_score)
  220.         tmp_score = take_turn(0, opponent_score, dice)
  221.         if is_prime(tmp_score + opponent_score + score):
  222.                 if tmp_score + score > opponent_score:
  223.                         return 0
  224.                 elif opponent_score > tmp_score + score:
  225.                         return num_rolls

  226.         return bacon_strategy(score, opponent_score, margin, num_rolls)

  227. def final_strategy(score, opponent_score):
  228.         """Write a brief description of your final strategy.

  229.         *** YOUR DESCRIPTION HERE ***
  230.         """
  231.         "*** YOUR CODE HERE ***"
  232.         if score > 85:
  233.                 return 0
  234.         if score >= opponent_score:
  235.                 return 0
  236.         else:
  237.                 if opponent_score - score > 60:
  238.                         return 8
  239.                 elif opponent_score - score > 40:
  240.                         return 6
  241.                 elif opponent_score - score > 20:
  242.                         return 4
  243.         dice = select_dice(score, opponent_score)
  244.         tmp_score = take_turn(0, opponent_score, dice)
  245.         if select_dice(score + tmp_score, opponent_score) == four_sided:
  246.                 return 0
  247.         return 2 # Replace this statement



  248. ##########################
  249. # Command Line Interface #
  250. ##########################

  251. # Note: Functions in this section do not need to be changed.  They use features
  252. #       of Python not yet covered in the course.


  253. @main
  254. def run(*args):
  255.         """Read in the command-line argument and calls corresponding functions.

  256.         This function uses Python syntax/techniques not yet covered in this course.
  257.         """
  258.         import argparse
  259.         parser = argparse.ArgumentParser(description="Play Hog")
  260.         parser.add_argument('--run_experiments', '-r', action='store_true',
  261.                                                 help='Runs strategy experiments')
  262.         args = parser.parse_args()

  263.         if args.run_experiments:
  264.                 run_experiments()
复制代码
前面的test都通过了,最后一个计算胜率的,我的作业是2015 spring版本,胜率只要求56%,但是貌似Fall版本要求七十多。。我就是折中按60算得,因为觉得这个不是很重要,所以没有花太大的功夫选择最终的策略。。
回复 支持 反对

使用道具 举报

zhizhizhimon 发表于 2016-1-14 17:31:01 | 显示全部楼层
lh6210 发表于 2015-10-1 09:25
噢,明白了。
那做完实验还是可以用 OK 来验证下是否正确的对吗?

求问一个弱智的问题。。。unclock完test之后都会提示输入mail哎,跳出再检测correctness的时候就显示there are still locked tests.....求解
回复 支持 反对

使用道具 举报

liyimeng 发表于 2016-1-15 04:35:08 | 显示全部楼层
zhizhizhimon 发表于 2016-1-14 17:31
求问一个弱智的问题。。。unclock完test之后都会提示输入mail哎,跳出再检测correctness的时候就显示ther ...

后面加 --local 就行了,不会问Email
回复 支持 反对

使用道具 举报

zhizhizhimon 发表于 2016-1-15 11:28:55 | 显示全部楼层
liyimeng 发表于 2016-1-15 04:35
后面加 --local 就行了,不会问Email

恩恩~感谢!!!
回复 支持 反对

使用道具 举报

wkh279 发表于 2016-11-16 21:02:01 | 显示全部楼层
去年跟了一半课程弃了今年重新做一遍,发现自己与去年写的代码谜之相似,果然思路基本没啥变化呀。。。
  1. """The Game of Hog."""

  2. from dice import four_sided, six_sided, make_test_dice
  3. from ucb import main, trace, log_current_line, interact

  4. GOAL_SCORE = 100 # The goal of Hog is to score 100 points.

  5. ######################
  6. # Phase 1: Simulator #
  7. ######################

  8. def roll_dice(num_rolls, dice=six_sided):
  9.     """Roll DICE for NUM_ROLLS times. Return either the sum of the outcomes,
  10.     or 1 if a 1 is rolled (Pig out). This calls DICE exactly NUM_ROLLS times.

  11.     num_rolls:  The number of dice rolls that will be made; at least 1.
  12.     dice:       A zero-argument function that returns an integer outcome.
  13.     """
  14.     # These assert statements ensure that num_rolls is a positive integer.
  15.     assert type(num_rolls) == int, 'num_rolls must be an integer.'
  16.     assert num_rolls > 0, 'Must roll at least once.'
  17.     results = []
  18.     for _ in range(0, num_rolls):
  19.          results.append(dice())
  20.     if 1 in results:
  21.         return 1
  22.     else:
  23.         return sum(results)


  24. def take_turn(num_rolls, opponent_score, dice=six_sided):
  25.     """Simulate a turn rolling NUM_ROLLS dice, which may be 0 (Free bacon).

  26.     num_rolls:       The number of dice rolls that will be made.
  27.     opponent_score:  The total score of the opponent.
  28.     dice:            A function of no args that returns an integer outcome.
  29.     """
  30.     assert type(num_rolls) == int, 'num_rolls must be an integer.'
  31.     assert num_rolls >= 0, 'Cannot roll a negative number of dice.'
  32.     assert num_rolls <= 10, 'Cannot roll more than 10 dice.'
  33.     assert opponent_score < 100, 'The game should be over.'
  34.     if not num_rolls == 0:
  35.         return roll_dice(num_rolls,dice)
  36.     else:
  37.         x,y = opponent_score//10,opponent_score%10
  38.         return 1+max(x,y)

  39. def select_dice(score, opponent_score):
  40.     """Select six-sided dice unless the sum of SCORE and OPPONENT_SCORE is a
  41.     multiple of 7, in which case select four-sided dice (Hog wild).
  42.     """
  43.     if (score+opponent_score)%7 ==0:
  44.         return four_sided
  45.     else:
  46.         return six_sided

  47. def is_prime(n):
  48.     """Return True if a non-negative number N is prime, otherwise return
  49.     False. 1 is not a prime number!
  50.     """
  51.     assert type(n) == int, 'n must be an integer.'
  52.     assert n >= 0, 'n must be non-negative.'
  53.     k = 1
  54.     while k < n-1:
  55.         k += 1
  56.         if n % k == 0:
  57.             return False
  58.     if n in [0,1]:
  59.         return False
  60.     return True


  61. def other(who):
  62.     """Return the other player, for a player WHO numbered 0 or 1.

  63.     >>> other(0)
  64.     1
  65.     >>> other(1)
  66.     0
  67.     """
  68.     return 1 - who

  69. def play(strategy0, strategy1, score0=0, score1=0, goal=GOAL_SCORE):
  70.     """Simulate a game and return the final scores of both players, with
  71.     Player 0's score first, and Player 1's score second.

  72.     A strategy is a function that takes two total scores as arguments
  73.     (the current player's score, and the opponent's score), and returns a
  74.     number of dice that the current player will roll this turn.

  75.     strategy0:  The strategy function for Player 0, who plays first
  76.     strategy1:  The strategy function for Player 1, who plays second
  77.     score0   :  The starting score for Player 0
  78.     score1   :  The starting score for Player 1
  79.     """
  80.     who = 0  # Which player is about to take a turn, 0 (first) or 1 (second)
  81.     while score0<goal and score1<goal:
  82.         if who==0:
  83.             score,opponent_score=score0,score1
  84.             strategy=strategy0
  85.         else:
  86.             score,opponent_score=score1,score0
  87.             strategy=strategy1
  88.         num_rolls=strategy(score,opponent_score)
  89.         dice=select_dice(score,opponent_score)
  90.         score_turn=take_turn(num_rolls,opponent_score,dice)
  91.         score+=score_turn
  92.         if is_prime(score+opponent_score):
  93.             if score>opponent_score:
  94.                 score+=score_turn
  95.             elif score<opponent_score:
  96.                 opponent_score+=score_turn
  97.         if who==0:
  98.             score0,score1=score,opponent_score
  99.         else:
  100.             score1,score0=score,opponent_score
  101.         who=other(who)
  102.     return score0, score1  # You may want to change this line.

  103. #######################
  104. # Phase 2: Strategies #
  105. #######################

  106. def always_roll(n):
  107.     """Return a strategy that always rolls N dice.

  108.     A strategy is a function that takes two total scores as arguments
  109.     (the current player's score, and the opponent's score), and returns a
  110.     number of dice that the current player will roll this turn.

  111.     >>> strategy = always_roll(5)
  112.     >>> strategy(0, 0)
  113.     5
  114.     >>> strategy(99, 99)
  115.     5
  116.     """
  117.     def strategy(score, opponent_score):
  118.         return n
  119.     return strategy

  120. # Experiments

  121. def make_averaged(fn, num_samples=1000):
  122.     """Return a function that returns the average_value of FN when called.

  123.     To implement this function, you will have to use *args syntax, a new Python
  124.     feature introduced in this project.  See the project description.

  125.     >>> dice = make_test_dice(3, 1, 5, 6)
  126.     >>> averaged_dice = make_averaged(dice, 1000)
  127.     >>> averaged_dice()
  128.     3.75
  129.     >>> make_averaged(roll_dice, 1000)(2, dice)
  130.     6.0

  131.     In this last example, two different turn scenarios are averaged.
  132.     - In the first, the player rolls a 3 then a 1, receiving a score of 1.
  133.     - In the other, the player rolls a 5 and 6, scoring 11.
  134.     Thus, the average value is 6.0.
  135.     """
  136.     def average_fn(*args):
  137.         result=[]
  138.         for _ in range(0,num_samples):
  139.             result.append(fn(*args))
  140.         return sum(result)/num_samples
  141.     return average_fn

  142. def max_scoring_num_rolls(dice=six_sided):
  143.     """Return the number of dice (1 to 10) that gives the highest average turn
  144.     score by calling roll_dice with the provided DICE.  Assume that dice always
  145.     return positive outcomes.

  146.     >>> dice = make_test_dice(3)
  147.     >>> max_scoring_num_rolls(dice)
  148.     10
  149.     """
  150.     result=[]
  151.     for i in range(1,11):
  152.         result.append(make_averaged(roll_dice)(i,dice))
  153.     return result.index(max(result))+1
  154. def winner(strategy0, strategy1):
  155.     """Return 0 if strategy0 wins against strategy1, and 1 otherwise."""
  156.     score0, score1 = play(strategy0, strategy1)
  157.     if score0 > score1:
  158.         return 0
  159.     else:
  160.         return 1

  161. def average_win_rate(strategy, baseline=always_roll(5)):
  162.     """Return the average win rate (0 to 1) of STRATEGY against BASELINE."""
  163.     win_rate_as_player_0 = 1 - make_averaged(winner)(strategy, baseline)
  164.     win_rate_as_player_1 = make_averaged(winner)(baseline, strategy)
  165.     return (win_rate_as_player_0 + win_rate_as_player_1) / 2 # Average results

  166. def run_experiments():
  167.     """Run a series of strategy experiments and report results."""
  168.     if False: # Change to False when done finding max_scoring_num_rolls
  169.         six_sided_max = max_scoring_num_rolls(six_sided)
  170.         print('Max scoring num rolls for six-sided dice:', six_sided_max)
  171.         four_sided_max = max_scoring_num_rolls(four_sided)
  172.         print('Max scoring num rolls for four-sided dice:', four_sided_max)

  173.     if False: # Change to True to test always_roll(8)
  174.         print('always_roll(8) win rate:', average_win_rate(always_roll(8)))

  175.     if False: # Change to True to test bacon_strategy
  176.         print('bacon_strategy win rate:', average_win_rate(bacon_strategy))

  177.     if False: # Change to True to test prime_strategy
  178.         print('prime_strategy win rate:', average_win_rate(prime_strategy))

  179.     if True: # Change to True to test final_strategy
  180.         print('final_strategy win rate:', average_win_rate(final_strategy))

  181.     "*** You may add additional experiments as you wish ***"

  182. # Strategies

  183. def bacon_strategy(score, opponent_score, margin=8, num_rolls=5):
  184.     """This strategy rolls 0 dice if that gives at least MARGIN points,
  185.     and rolls NUM_ROLLS otherwise.
  186.     """
  187.     if max(opponent_score//10,opponent_score%10)+1>=margin:
  188.         return 0
  189.     return num_rolls

  190. def prime_strategy(score, opponent_score, margin=8, num_rolls=5):
  191.     """This strategy rolls 0 dice when it results in a beneficial boost and
  192.     rolls NUM_ROLLS if rolling 0 dice gives the opponent a boost. It also
  193.     rolls 0 dice if that gives at least MARGIN points and rolls NUM_ROLLS
  194.     otherwise.
  195.     """
  196.     score_zero_dice=max(opponent_score//10,opponent_score%10)+1
  197.     score+=score_zero_dice
  198.     if is_prime(score+opponent_score):
  199.         if score>opponent_score:
  200.             return 0
  201.         elif score<opponent_score:
  202.             return num_rolls
  203.     if score_zero_dice>=margin:
  204.         return 0
  205.     else:
  206.         return num_rolls


  207. def final_strategy(score, opponent_score,margin_six=8,margin_four=4):
  208.     """This strategy is like the prime_strategy. There only exit two
  209.     differences.
  210.     First is that this strategy divides the margin into margin_six and
  211.     margin_four, depending on the dice.
  212.     Second is that the prime_strategy rolls 0 dice when it results in a
  213.     beneficial boost, while this strategy calls for that the result of
  214.     rolling 0 dice, simultaneously, is at least half of the margin.

  215.     Final winning rate:0.572-0.5735
  216.     """
  217.     dice=select_dice(score,opponent_score)
  218.     if dice==six_sided:
  219.         num_rolls=6
  220.         margin=margin_six
  221.     else:
  222.         num_rolls=4
  223.         margin=margin_four
  224.     score_zero_dice=max(opponent_score//10,opponent_score%10)+1
  225.     score+=score_zero_dice
  226.     if is_prime(score+opponent_score):
  227.         if score>opponent_score and score_zero_dice>=margin:
  228.             return 0
  229.         elif score<opponent_score:
  230.             return num_rolls
  231.     if score_zero_dice>=margin:
  232.         return 0
  233.     else:
  234.         return num_rolls




  235. ##########################
  236. # Command Line Interface #
  237. ##########################

  238. # Note: Functions in this section do not need to be changed.  They use features
  239. #       of Python not yet covered in the course.


  240. @main
  241. def run(*args):
  242.     """Read in the command-line argument and calls corresponding functions.

  243.     This function uses Python syntax/techniques not yet covered in this course.
  244.     """
  245.     import argparse
  246.     parser = argparse.ArgumentParser(description="Play Hog")
  247.     parser.add_argument('--run_experiments', '-r', action='store_true',
  248.                         help='Runs strategy experiments')
  249.     args = parser.parse_args()

  250.     if args.run_experiments:
  251.         run_experiments()
复制代码
回复 支持 反对

使用道具 举报

本版积分规则

请点这里访问我们的新网站:一亩三分地Instant.

Instant搜索更强大,不扣积分,内容组织的更好更整洁!目前仍在beta版本,努力完善中!反馈请点这里

关闭

一亩三分地推荐上一条 /5 下一条

手机版|小黑屋|一亩三分地论坛声明 ( 沪ICP备11015994号 )

custom counter

GMT+8, 2016-12-3 14:56

Powered by Discuz! X3

© 2001-2013 Comsenz Inc. Design By HUXTeam

快速回复 返回顶部 返回列表