首页 > 其他分享 >Pro1 Hog

Pro1 Hog

时间:2024-05-31 14:56:07浏览次数:16  
标签:Hog num dice Pro1 roll player score rolls

先说下命令:点击hog文件夹,右键选择gitbssh打开

1.测试:python ok -q 02(问题编号) -u --local

2.运行:python ok -q 02 --local

Phase 1: Rules of the Game

Problem 0 (0 pt)

The dice.py file represents dice using non-pure zero-argument functions. These functions are non-pure because they may have different return values each time they are called, and so a side-effect of calling the function is changing what will be returned when the function is called again.

Here's the documentation from dice.py that you need to read in order to simulate dice in this project.

A dice function takes no arguments and returns a number from 1 to n
(inclusive), where n is the number of sides on the dice.

Fair dice produce each possible outcome with equal probability.
Two fair dice are already defined, four_sided and six_sided,
and are generated by the make_fair_dice function.

Test dice are deterministic: they always cycles through a fixed
sequence of values that are passed as arguments.
Test dice are generated by the make_test_dice function.

def make_fair_dice(sides):
    """Return a die that returns 1 to SIDES with equal chance."""
    ...

four_sided = make_fair_dice(4)
six_sided = make_fair_dice(6)

def make_test_dice(...):
    """Return a die that cycles deterministically through OUTCOMES.

    >>> dice = make_test_dice(1, 2, 3)
    >>> dice()
    1
    >>> dice()
    2
    >>> dice()
    3
    >>> dice()
    1
    >>> dice()
    2
View Code

Problem 1 (2 pt)

Implement the roll_dice function in hog.py. It takes two arguments: a positive integer called num_rolls giving the number of times to roll a die and a dice function. It returns the number of points scored by rolling the die that number of times in a turn: either the sum of the outcomes or 1 (Sow Sad).

  • Sow Sad. If any of the dice outcomes is a 1, the current player's score for the turn is 1。
  • Example 1: The current player rolls 7 dice, 5 of which are 1's. They score 1 point for the turn.
  • Example 2: The current player rolls 4 dice, all of which are 3's. Since Sow Sad did not occur, they score 12 points for the turn。

To obtain a single outcome of a dice roll, call dice(). You should call dice() exactly num_rolls times in the body of roll_dice.

Remember to call dice() exactly num_rolls times even if Sow Sad happens in the middle of rolling. By doing so, you will correctly simulate rolling all the dice together (and the user interface will work correctly).

Note: The roll_dice function, and many other functions throughout the project, makes use of default argument values—you can see this in the function heading:

def roll_dice(num_rolls, dice=six_sided): ...

The argument dice=six_sided means that when roll_dice is called, the dice argument is optional. If no value for dice is provided, then six_sided is used by default.

For example, calling roll_dice(3, four_sided), or equivalently roll_dice(3, dice=four_sided), simulates rolling 3 four-sided dice, while calling roll_dice(3) simulates rolling 3 six-sided dice.

如果出现1,那么整轮结果就是1
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
    total = 0
    k = 0
    d = []
    while k < num_rolls:
        k += 1
        d.append(dice())
    if 1 in d:
        return 1
    return sum(d)
View Code

Problem 2 (2 pt)

Implement boar_brawl, which takes the player's current score player_score and the opponent's current score opponent_score, and returns the number of points scored by Boar Brawl when the player rolls 0 dice.

  • Boar Brawl. A player who rolls zero dice scores three times the absolute difference between the tens digit of the opponent’s score and the ones digit of the current player’s score, or 1, whichever is higher. The ones digit refers to the rightmost digit and the tens digit refers to the second-rightmost digit. If a player's score is a single digit (less than 10), the tens digit of that player's score is 0.
  • Example 1:

    • The current player has 21 points and the opponent has 46 points, and the current player chooses to roll zero dice.
    • The tens digit of the opponent's score is 4 and the ones digit of the current player's score is 1.
    • Therefore, the player gains 3 * abs(4 - 1) = 9 points.
  • Example 2:

    • The current player has 45 points and the opponent has 52 points, and the current player chooses to roll zero dice.
    • The tens digit of the opponent's score is 5 and the ones digit of the current player's score is 5.
    • Since 3 * abs(5 - 5) = 0, the player gains 1 point.
  • Example 3:

    • The current player has 2 points and the opponent has 5 points, and the current player chooses to roll zero dice.
    • The tens digit of the opponent's score is 0 and the ones digit of the current player's score is 2.
    • Therefore, the player gains 3 * abs(0 - 2) = 6 points.
取score的个位与opponent-scor的十位数,相减绝对值*3
def boar_brawl(player_score, opponent_score):
    """Return the points scored by rolling 0 dice according to Boar Brawl.

    player_score:     The total score of the current player.
    opponent_score:   The total score of the other player.

    """
    # BEGIN PROBLEM 2
    "*** YOUR CODE HERE ***"
    # END PROBLEM 2
    x = player_score%10
    y = opponent_score//10%10
    sum = abs(x-y)*3
    if sum>1:
        return sum
    else :return 1
View Code

 

Problem 3 (2 pt)

Implement the take_turn function, which returns the number of points scored for a turn by rolling the given dice num_rolls times.

Your implementation of take_turn should call both roll_dice and boar_brawl rather than repeating their implementations.

def take_turn(num_rolls, player_score, opponent_score, dice=six_sided):
    """Return the points scored on a turn rolling NUM_ROLLS dice when the
    player has PLAYER_SCORE points and the opponent has OPPONENT_SCORE points.

    num_rolls:       The number of dice rolls that will be made.
    player_score:    The total score of the current player.
    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
    if num_rolls==0:
        return boar_brawl(player_score,opponent_score)
    else:
        return roll_dice(num_rolls,dice)
View Code

Problem 4 (2 pt)

First, implement num_factors, which takes in a positive integer n and determines the number of factors that n has.

1 and n are both factors of n!

After, implement sus_points and sus_update.

  • sus_points takes in a player's score and returns the player's new score after applying the Sus Fuss rule (for example, sus_points(5) should return 5 and sus_points(21) should return 23). You should use num_factors and the provided is_prime function in your implementation.
  • sus_update returns a player's total score after they roll num_rolls dice, taking both Boar Brawl and Sus Fuss into account. You should use sus_points in this function.

Hint: You can look at the implementation of simple_update provided in hog.py and use that as a starting point for your sus_update function.

  • Sus Fuss. We call a number sus if it has exactly 3 or 4 factors, including 1 and the number itself. If, after rolling, the current player's score is a sus number, they gain enough points such that their score instantly increases to the next prime number.
  • Example 1:

    • A player has 14 points and rolls 2 dice that total 7 points. Their new score would be 21, which has 4 factors: 1, 3, 7, and 21. Because 21 is sus, the score of the player is increased to 23, the next prime number.
  • Example 2:

    • A player has 63 points and rolls 5 dice that total 1 point. Their new score would be 64, which has 7 factors: 1, 2, 4, 8, 16, 32, and 64. Since 64 is not sus, the score of the player is unchanged.
  • Example 3:

    • A player has 49 points and rolls 5 dice that total 18 points. Their new score would be 67, which is prime and has 2 factors: 1 and 67. Since 67 is not sus, the score of the player is unchanged.
判断有几个因数,如果是3个或4个,,就变成下一个质数
def num_factors(n):
    """Return the number of factors of N, including 1 and N itself."""
    # BEGIN PROBLEM 4
    "*** YOUR CODE HERE ***"
    # END PROBLEM 4
    i = 1
    cnt = 0
    while i<=n:
        if n%i==0:
            cnt+=1
        i += 1
    return cnt


def sus_points(score):
    """Return the new score of a player taking into account the Sus Fuss rule."""
    # BEGIN PROBLEM 4
    "*** YOUR CODE HERE ***"
    # END PROBLEM 4
    if num_factors(score)==3 or num_factors(score)==4:
        while not is_prime(score):
            score += 1
        return score
    else:return score

def sus_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* Sus Fuss.
    """
    # BEGIN PROBLEM 4
    "*** YOUR CODE HERE ***"
    # END PROBLEM 4
    score = player_score + take_turn(num_rolls, player_score, opponent_score, dice)
    return sus_points(score)
View Code

Problem 5 (4 pt)

Implement the play function, which simulates a full game of Hog. Players take turns rolling dice until one of the players reaches the goal score, and the final scores of both players are returned by the function.

To determine how many dice are rolled each turn, call the current player's strategy function (Player 0 uses strategy0 and Player 1 uses strategy1). A strategy is a function that, given a player's score and their opponent's score, returns the number of dice that the current player will roll in the turn. An example strategy is always_roll_5 which appears above play.

To determine the updated score for a player after they take a turn, call the update function. An update function 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. Two examples of update functions are simple_update andsus_update.

If a player achieves the goal score by the end of their turn, i.e. after all applicable rules have been applied, the game ends. play will then return the final total scores of both players, with Player 0's score first and Player 1's score second.

Some example calls to play are:

  • play(always_roll_5, always_roll_5, simple_update) simulates two players that both always roll 5 dice each turn, playing with just the Sow Sad and Boar Brawl rules.
  • play(always_roll_5, always_roll_5, sus_update) simulates two players that both always roll 5 dice each turn, playing with the Sus Fuss rule in addition to the Sow Sad and Boar Brawl rules (i.e. all the rules).

Important: For the user interface to work, a strategy function should be called only once per turn. Only call strategy0 when it is Player 0's turn and only call strategy1 when it is Player 1's turn.

Hints:

  • If who is the current player, the next player is 1 - who.
  • To call play(always_roll_5, always_roll_5, sus_update) and print out what happens each turn, run python3 hog_ui.py from the terminal.
模拟过程
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, sus_update) simulates a game in
    which both players always choose to roll 5 dice on every turn and the Sus
    Fuss 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 sus_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 ***"
    while score0<goal and score1<goal:
        if who==0:
            score0 = update(strategy0(score0,score1),score0,score1,dice)
    # END PROBLEM 5
        else:score1 = update(strategy1(score1,score0),score1,score0,dice)
        who = 1-who
    return score0, score1
View Code

Phase 2: Strategies

In this phase, you will experiment with ways to improve upon the basic strategy of always rolling five dice. A strategy is a function that takes two arguments: the current player's score and their opponent's score. It returns the number of dice the player will roll, which can be from 0 to 10 (inclusive).

Problem 6 (2 pt)

Implement always_roll, a higher-order function that takes a number of dice n and returns a strategy that always rolls n dice. Thus, always_roll(5) would be equivalent to always_roll_5.

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 ***"
    def strategy_inner(score0,score1):
        return n
    return strategy_inner
    # END PROBLEM 6
View Code

Problem 7 (2 pt)

A strategy only has a fixed number of possible argument values. For example, in a game to 100, there are 100 possible score values (0-99) and 100 possible opponent_score values (0-99), giving 10,000 possible argument combinations.

Implement is_always_roll, which takes a strategy and returns whether that strategy always rolls the same number of dice for every possible argument combination up to goal points.

Reminder: The game continues until one player reaches goal points (in the above example, goal is set to 100). Make sure your solution accounts for every possible combination for the specified goal argument.

def is_always_roll(strategy, goal=GOAL):
    """Return whether STRATEGY always chooses the same number of dice to roll
    given a game that goes to GOAL points.

    >>> 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 ***"
    score = 0
    opponent_score = 0
    reference = strategy(score,opponent_score)
    while score<goal:
        while opponent_score<goal:
            if reference != strategy(score,opponent_score):
                return False
            opponent_score += 1
        opponent_score = 0
        score += 1
    return True

    # END PROBLEM 7
View Code

Problem 8 (2 pt)

Implement make_averaged, which is a higher-order function that takes a function original_function as an argument.

The return value of make_averaged is a function that takes in the same number of arguments as original_function. When we call this returned function on the arguments, it will return the average value of repeatedly calling original_function on the arguments passed in.

Specifically, this function should call original_function a total of samples_count times and return the average of the results of these calls.

Important: To implement this function, you will need to use a new piece of Python syntax. We would like to write a function that accepts an arbitrary number of arguments, and then calls another function using exactly those arguments. Here's how it works.

Instead of listing formal parameters for a function, you can write *args, which represents all of the arguments that get passed into the function. We can then call another function with these same arguments by passing these *args into this other function. For example:

>>> def printed(f):
...     def print_and_return(*args):
...         result = f(*args)
...         print('Result:', result)
...         return result
...     return print_and_return
>>> printed_pow = printed(pow)
>>> printed_pow(2, 8)
Result: 256
256
>>> printed_abs = printed(abs)
>>> printed_abs(-10)
Result: 10
10

Here, we can pass any number of arguments into print_and_return via the *args syntax. We can also use *args inside our print_and_return function to make another function call with the same arguments.

unlock

question:为什么是6.0?

运用了sowsad规则,摇到1就都是1,

3.0*2=6.0,目前的思路

 

def make_averaged(original_function, samples_count=1000):
    """Return a function that returns the average value of ORIGINAL_FUNCTION
    called SAMPLES_COUNT 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 ***"
    def averge(*args):
        i = 0
        sum = 0
        while i < samples_count:
            sum += original_function(*args)
            i += 1
        return sum / samples_count
    return averge
    # END PROBLEM 8
View Code

Problem 9 (2 pt)

Implement max_scoring_num_rolls, which runs an experiment to determine the number of rolls (from 1 to 10) that gives the maximum average score for a turn. Your implementation should use make_averaged and roll_dice.

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.

You might find it useful to read the doctest and the example shown in the doctest for this problem before doing the unlocking test.

Important: In order to pass all of our tests, please make sure that you are testing dice rolls starting from 1 going up to 10, rather than from 10 to 1.

def max_scoring_num_rolls(dice=six_sided, samples_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 a total of SAMPLES_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 ***"
    i = 1
    max = 1
    num_rolls = 1
    while i<=10:
        ans = make_averaged(roll_dice,samples_count)(i,dice)
        if ans >max:
            max = ans
            num_rolls = i
        i+=1
    return int(num_rolls)
    # END PROBLEM 9
View Code

Problem 10 (2 pt)

A strategy can try to take advantage of the Boar Brawl rule by rolling 0 when it is most beneficial to do so. Implement boar_strategy, which returns 0 whenever rolling 0 would give at least threshold points and returns num_rolls otherwise. This strategy should not also take into account the Sus Fuss rule.

Hint: You can use the boar_brawl function you defined in Problem 2.

如果扔0的结果大于阈值,则扔0
def boar_strategy(score, opponent_score, threshold=11, num_rolls=6):
    """This strategy returns 0 dice if Boar Brawl gives at least THRESHOLD
    points, and returns NUM_ROLLS otherwise. Ignore score and Sus Fuss.
    """
    # BEGIN PROBLEM 10
    boar_score = boar_brawl(score,opponent_score)
    if boar_score>=threshold:
        num_rolls = 0
    return num_rolls  # Remove this line once implemented.
    # END PROBLEM 10
View Code

Problem 11 (2 pt)

A better strategy will take advantage of both Boar Brawl and Sus Fuss in combination. For example, if a player has 53 points and their opponent has 60, rolling 0 would bring them to 62, which is a sus number, and so they would end the turn with 67 points: a gain of 67 - 53 = 14!

The sus_strategy returns 0 whenever rolling 0 would result in a score that is at least threshold points more than the player's score at the start of turn.

Hint: You can use the sus_update function.

在pro10的基础上加上susfuss规则
def sus_strategy(score, opponent_score, threshold=11, num_rolls=6):
    """This strategy returns 0 dice when your score would increase by at least threshold."""
    # BEGIN PROBLEM 11
    sus_pnts = sus_update(0,score,opponent_score)
    if sus_pnts-score>=threshold:
        num_rolls = 0
    return num_rolls  # Remove this line once implemented.
    # END PROBLEM 11
View Code

Optional: Problem 12 (0 pt)

Implement final_strategy, which combines these ideas and any other ideas you have to achieve a high win rate against the baseline strategy. Some suggestions:

  • If you know the goal score (by default it is 100), there's no benefit to scoring more than the goal. Check whether you can win by rolling 0, 1 or 2 dice. If you are in the lead, you might decide to take fewer risks.
  • Instead of using a threshold, roll 0 whenever it would give you more points on average than rolling 6.

You can check that your final strategy is valid by running ok.

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

    *** YOUR DESCRIPTION HERE ***
    """
    # BEGIN PROBLEM 12
    sus_pnts = sus_update(0, score, opponent_score)
    base_6 = sus_update(6, score, opponent_score)
    i = 1
    num_rolls = 0
    while GOAL - 5 <= score <= GOAL and i < 3:
        temp = sus_update(i, score, opponent_score)
        if temp > sus_pnts and temp > base_6:
            num_rolls = i
            sus_pnts = temp
        else:
            num_rolls = 6
        i += 1
    return num_rolls

    # END PROBLEM 12
View Code

 

12个problem全写完后,最终测试结果:

 附上完整运行代码:

"""The Game of Hog."""

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

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

######################
# 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 ***"
    # END PROBLEM 1
    total = 0
    k = 0
    d = []
    while k < num_rolls:
        k += 1
        d.append(dice())
    if 1 in d:
        return 1
    return sum(d)


def boar_brawl(player_score, opponent_score):
    """Return the points scored by rolling 0 dice according to Boar Brawl.

    player_score:     The total score of the current player.
    opponent_score:   The total score of the other player.

    """
    # BEGIN PROBLEM 2
    "*** YOUR CODE HERE ***"
    # END PROBLEM 2
    x = player_score%10
    y = opponent_score//10%10
    sum = abs(x-y)*3
    if sum>1:
        return sum
    else :return 1



def take_turn(num_rolls, player_score, opponent_score, dice=six_sided):
    """Return the points scored on a turn rolling NUM_ROLLS dice when the
    player has PLAYER_SCORE points and the opponent has OPPONENT_SCORE points.

    num_rolls:       The number of dice rolls that will be made.
    player_score:    The total score of the current player.
    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
    if num_rolls==0:
        return boar_brawl(player_score,opponent_score)
    else:
        return roll_dice(num_rolls,dice)


def simple_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, ignoring Sus Fuss.
    """
    score = player_score + take_turn(num_rolls, player_score, opponent_score, dice)
    return score

def is_prime(n):
    """Return whether N is prime."""
    if n == 1:
        return False
    k = 2
    while k < n:
        if n % k == 0:
            return False
        k += 1
    return True

def num_factors(n):
    """Return the number of factors of N, including 1 and N itself."""
    # BEGIN PROBLEM 4
    "*** YOUR CODE HERE ***"
    # END PROBLEM 4
    i = 1
    cnt = 0
    while i<=n:
        if n%i==0:
            cnt+=1
        i += 1
    return cnt


def sus_points(score):
    """Return the new score of a player taking into account the Sus Fuss rule."""
    # BEGIN PROBLEM 4
    "*** YOUR CODE HERE ***"
    # END PROBLEM 4
    if num_factors(score)==3 or num_factors(score)==4:
        while not is_prime(score):
            score += 1
        return score
    else:return score

def sus_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* Sus Fuss.
    """
    # BEGIN PROBLEM 4
    "*** YOUR CODE HERE ***"
    # END PROBLEM 4
    score = player_score + take_turn(num_rolls, player_score, opponent_score, dice)
    return sus_points(score)

def always_roll_5(score, opponent_score):
    """A strategy of always rolling 5 dice, regardless of the player's score or
    the opponent's score.
    """
    return 5


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, sus_update) simulates a game in
    which both players always choose to roll 5 dice on every turn and the Sus
    Fuss 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 sus_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 ***"
    while score0<goal and score1<goal:
        if who==0:
            score0 = update(strategy0(score0,score1),score0,score1,dice)
    # END PROBLEM 5
        else:score1 = update(strategy1(score1,score0),score1,score0,dice)
        who = 1-who
    return score0, score1


#######################
# Phase 2: Strategies #
#######################


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 ***"
    def strategy_inner(score0,score1):
        return n
    return strategy_inner
    # END PROBLEM 6


def catch_up(score, opponent_score):
    """A player strategy that always rolls 5 dice unless the opponent
    has a higher score, in which case 6 dice are rolled.

    >>> catch_up(9, 4)
    5
    >>> strategy(17, 18)
    6
    """
    if score < opponent_score:
        return 6  # Roll one more to catch up
    else:
        return 5


def is_always_roll(strategy, goal=GOAL):
    """Return whether STRATEGY always chooses the same number of dice to roll
    given a game that goes to GOAL points.

    >>> 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 ***"
    score = 0
    opponent_score = 0
    reference = strategy(score,opponent_score)
    while score<goal:
        while opponent_score<goal:
            if reference != strategy(score,opponent_score):
                return False
            opponent_score += 1
        opponent_score = 0
        score += 1
    return True

    # END PROBLEM 7


def make_averaged(original_function, samples_count=1000):
    """Return a function that returns the average value of ORIGINAL_FUNCTION
    called SAMPLES_COUNT 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 ***"
    def averge(*args):
        i = 0
        sum = 0
        while i < samples_count:
            sum += original_function(*args)
            i += 1
        return sum / samples_count
    return averge
    # END PROBLEM 8


def max_scoring_num_rolls(dice=six_sided, samples_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 a total of SAMPLES_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 ***"
    i = 1
    max = 1
    num_rolls = 1
    while i<=10:
        ans = make_averaged(roll_dice,samples_count)(i,dice)
        if ans >max:
            max = ans
            num_rolls = i
        i+=1
    return int(num_rolls)
    # END PROBLEM 9


def winner(strategy0, strategy1):
    """Return 0 if strategy0 wins against strategy1, and 1 otherwise."""
    score0, score1 = play(strategy0, strategy1, sus_update)
    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."""
    six_sided_max = max_scoring_num_rolls(six_sided)
    print('Max scoring num rolls for six-sided dice:', six_sided_max)

    print('always_roll(6) win rate:', average_win_rate(always_roll(6))) # near 0.5
    print('catch_up win rate:', average_win_rate(catch_up))
    print('always_roll(3) win rate:', average_win_rate(always_roll(3)))
    print('always_roll(8) win rate:', average_win_rate(always_roll(8)))

    print('boar_strategy win rate:', average_win_rate(boar_strategy))
    print('sus_strategy win rate:', average_win_rate(sus_strategy))
    print('final_strategy win rate:', average_win_rate(final_strategy))
    "*** You may add additional experiments as you wish ***"



def boar_strategy(score, opponent_score, threshold=11, num_rolls=6):
    """This strategy returns 0 dice if Boar Brawl gives at least THRESHOLD
    points, and returns NUM_ROLLS otherwise. Ignore score and Sus Fuss.
    """
    # BEGIN PROBLEM 10
    boar_score = boar_brawl(score,opponent_score)
    if boar_score>=threshold:
        num_rolls = 0
    return num_rolls  # Remove this line once implemented.
    # END PROBLEM 10


def sus_strategy(score, opponent_score, threshold=11, num_rolls=6):
    """This strategy returns 0 dice when your score would increase by at least threshold."""
    # BEGIN PROBLEM 11
    sus_pnts = sus_update(0,score,opponent_score)
    if sus_pnts-score>=threshold:
        num_rolls = 0
    return num_rolls  # Remove this line once implemented.
    # END PROBLEM 11


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

    *** YOUR DESCRIPTION HERE ***
    """
    # BEGIN PROBLEM 12
    sus_pnts = sus_update(0, score, opponent_score)
    base_6 = sus_update(6, score, opponent_score)
    i = 1
    num_rolls = 0
    while GOAL - 5 <= score <= GOAL and i < 3:
        temp = sus_update(i, score, opponent_score)
        if temp > sus_pnts and temp > base_6:
            num_rolls = i
            sus_pnts = temp
        else:
            num_rolls = 6
        i += 1
    return num_rolls

    # END PROBLEM 12


##########################
# Command Line Interface #
##########################

# NOTE: The function in this section does not need to be changed. It uses
# 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()
View Code

--------------------------------------------------================================------------------------------------------------------------=============================---------------------------------

后记:写了几天吧,都是抽空写的,没有完整的一次性做完,导致第二天看的时候一头雾水,又要从头看起,下次要找完整的时间做pro,一次性做完!

 

标签:Hog,num,dice,Pro1,roll,player,score,rolls
From: https://www.cnblogs.com/cancanneed/p/18222916

相关文章

  • Hogervorst classAB结构
    classAB减少运放的噪声和漂移??轨到轨放大器的缺点是当共模输入电压变化时,其中由于共模输入范围存在重叠区,所以导致N管和P管同时导通时其跨导会变化,这会影响电路频率特性,因为一个好的频率补偿电路需要一个恒定的跨导,所以为了在共模输入范围内得到恒定的跨导提升在共模输入在较低电......
  • [Paper Reading] OFT Orthographic Feature Transform for Monocular 3D Object Detec
    OFTOrthographicFeatureTransformforMonocular3DObjectDetectionOFTOrthographicFeatureTransformforMonocular3DObjectDetection时间:18.11机构:UniversityofCambridgeTL;DR当时纯视觉自动驾驶方案效果上仅达到Lidar方案有10%的水平,本文claim部分差距源于pe......
  • 【笔记】RedmiBookPro15锐龙板(7840hs)安装ubuntu2204注意事项
    /** 2024-04-17 12:53:52*/1、不要安装ubuntu2004,驱动问题很烦入,尤其是AMD的显卡驱动,不论哪个版本都不要打AMD的官方驱动,经常花屏,卡的完全不能操作,自带的开源驱动就行了,偶尔出现一两道花屏的,不影响使用,而且一会就消失了。如果经常出现在bios里调大显存试试,默认512估计不够,我......
  • 【BlueZ协议栈】HOG实现通路完整分析
    1.1HOG概述HOGP是HIDOverGATTProfile的缩写,即蓝牙HID设备是通过BLE的GATT来实现HID协议的。常见的蓝牙鼠标、蓝牙键盘、蓝牙手柄,它们都属于HID设备,但与有线设备不同的是,有线鼠标等设备属于USBHID设备,而蓝牙鼠标等设备属于BluetoothHID设备,即协议是一样的,只是通信方......
  • centos8 --上yum无法使用的问题以及无法用yum安装screen,iftop,nethogs等的解决办法
    centos8--上yum无法使用的问题以及无法用yum安装screen,iftop,nethogs等的解决办法大家可能都发现了centos8已经不在更新了。当我们使用yum安装某些工具的时候,会提示安装源失败解决方案:删除repo文件然后重新下载即可修复yum安装报错问题1.进入/etc/yum.repos.d/目录cd/etc......
  • 在VMware Workstation pro16 中安装Red Hat Enterprise 8时屏幕屏幕缩小,无法继续。
    情况说明:1.在vm里设置自由拉伸2.不等待,回车选中。3.避免点击“添加磁盘”done......
  • 机器学习策略篇:详解正交化(Orthogonalization)
    正交化这是一张老式电视图片,有很多旋钮可以用来调整图像的各种性质,所以对于这些旧式电视,可能有一个旋钮用来调图像垂直方向的高度,另外有一个旋钮用来调图像宽度,也许还有一个旋钮用来调梯形角度,还有一个旋钮用来调整图像左右偏移,还有一个旋钮用来调图像旋转角度之类的。电视设计......
  • 小新Pro13 新手安装linux 注意事项
    家中有闲置的小新,是A卡正好合适装linux安装前关闭安全引导通过关机键旁边的重置口重新开机OR在开机界面按F2(开启Hotkey模式的要按Fn+F2)进入BIOS设置界面,关闭SecureBoot,这样方便安装linux系统刻录linux有很多发行版大家可以自行选择,推荐Ubuntu,相关资源比较丰富。我......
  • HoG / SIFT 学习指北
    本文OI/ACM无关。ExplainHoG原文出处:N.Dalal,andB.Triggs,Histogramsoforientedgradientsforhumandetection,ComputerVisionandPatternRecognition,CVPR2005,GoogleCitations:21911简介Histogramsoforientedgradients(HoG):方向梯度直方图,一种......
  • 基于HOG特征提取和GRNN神经网络的人脸表情识别算法matlab仿真,测试使用JAFFE表情数据
    1.算法运行效果图预览 2.算法运行软件版本matlab2022a 3.算法理论概述        该算法主要由两个部分组成:HOG特征提取和GRNN神经网络。下面将详细介绍这两个部分的原理和数学公式。 1.HOG特征提取      HOG(HistogramofOrientedGradients)是......