CS61A 2021 Spring, Project 1: The Game of Hog (Phase 1)

项目说明: https://inst.eecs.berkeley.edu/~cs61a/sp21/proj/hog/#phase-1-simulator
Phase2: https://www.cnblogs.com/ikventure/p/14885436.html
Phase3: https://www.cnblogs.com/ikventure/p/14887555.html


Project 1: The Game of Hog (Phase 1)

  • 成品:https://hog.cs61a.org/
  • 任务:完成hog.py文件
  • 针对每个problem,写代码前python ok -q 00 -u --local确认对问题的理解,理解正确即可解锁代码测试部分python ok -q 00 --local
  • 注意:及时保存!!!尤其是代码测试前!!!(不然找不到代码问题又得不到正确结果,持续几次怀疑人生)

规则及示例

  • Sow Sad,每轮可以投多个骰子,得分为各骰子分数的和,例外:只要其中一个骰子为1,该轮得分为1
  • Piggy Points,选择不投骰子的得分为k+3,k为对手得分平方值的最小数字
  • More Boar,再来一轮的情况:左一数字<对手左一,左二数字<对手左二,小于10在前补0
    image
    image

Phase 1: Simulator

Problem 0

dice.py 文件,定义了骰子类型

  • fair dice:各面等概率的骰子
  • test dice:测试用骰子,循环投出一系列指定值

Problem 1

roll_dice 函数,传入骰子数量 num_rolls 和骰子类型 dice,返回此次投骰子结果(考虑 Sow Sad 规则)。

Problem 2

piggy_points 函数,传入对手分数 score,返回投0次骰子的得分(piggy points 规则)。

Problem 3

take_turn 函数,传入骰子数量 num_rolls, 对手得分 opponent_score, 骰子类型 dice=six_sided, 目标得分 goal=GOAL_SCORE,返回该轮得分。
take_turn 函数,在骰子数量为0时,调用 piggy_points 函数;在骰子数量不为0时,调用 roll_dice 函数。

Problem 4

more_boar 函数,传入选手得分player_score, 对手得分opponent_score,返回布尔值,判断该选手是否再来一轮(more_boar 规则)。

Problem 5

play 函数,传入选手0的骰子策略 strategy0, 选手1的骰子策略s trategy1, 初始得分 score0=0, 初始得分 score1=0, 骰子类型 dice=six_sided, 目标得分 goal=GOAL_SCORE, 注释函数 say=silence,返回游戏结束时的两位选手得分。
分析:
strategy是决定选手的骰子数量的函数,传入选手得分和对手得分;
选手得分score = 初始得分 + 本轮得分,本轮得分由 take_turn 函数返回;
选手得分score达到目标值goal时,本轮结束,游戏结束,返回两选手得分;
选手得分score未达到目标值,more_boar 函数判断是否再来一局;
next_player 函数,判断下一位选手是谁,注意赋值给who。

image

Phase 1 完成

python hog_gui.py
image

附 Phase 1 代码

"""CS 61A Presents The Game of Hog."""

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

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

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


def piggy_points(score):
    """Return the points scored from rolling 0 dice.

    score:  The opponent's current score.
    """
    # BEGIN PROBLEM 2
    "*** YOUR CODE HERE ***"
    return 3 + int(min(str(score ** 2)))
    # END PROBLEM 2


def take_turn(num_rolls, opponent_score, dice=six_sided, goal=GOAL_SCORE):
    """Simulate a turn rolling NUM_ROLLS dice, which may be 0 in the case
    of a player using Piggy Points.
    Return the points scored for the turn by the current player.

    num_rolls:       The number of dice rolls that will be made.
    opponent_score:  The total score of the opponent.
    dice:            A function that simulates a single dice roll outcome.
    goal:            The goal score of the game.
    """
    # Leave these assert statements here; they help check for errors.
    assert type(num_rolls) == int, 'num_rolls must be an integer.'
    assert num_rolls >= 0, 'Cannot roll a negative number of dice in take_turn.'
    assert num_rolls <= 10, 'Cannot roll more than 10 dice.'
    assert opponent_score < goal, 'The game should be over.'
    # BEGIN PROBLEM 3
    "*** YOUR CODE HERE ***"
    if num_rolls == 0:
        return piggy_points(opponent_score)
    return roll_dice(num_rolls, dice)
    # END PROBLEM 3


def more_boar(player_score, opponent_score):
    """Return whether the player gets an extra turn.

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

    >>> more_boar(21, 43)
    True
    >>> more_boar(22, 43)
    True
    >>> more_boar(43, 21)
    False
    >>> more_boar(12, 12)
    False
    >>> more_boar(7, 8)
    False
    """
    # BEGIN PROBLEM 4
    "*** YOUR CODE HERE ***"
    ps = str(player_score) if player_score >= 10 else '0' + str(player_score)
    os = str(opponent_score) if opponent_score >= 10 else '0' + str(opponent_score)
    if ps[0] < os[0] and ps[1] < os[1]:
        return True
    else:
        return False
    # END PROBLEM 4


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

    >>> next_player(0)
    1
    >>> next_player(1)
    0
    """
    return 1 - who


def silence(score0, score1):
    """Announce nothing (see Phase 2)."""
    return silence


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

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

    strategy0:  The strategy function for Player 0, who plays first.
    strategy1:  The strategy function for Player 1, who plays second.
    score0:     Starting score for Player 0
    score1:     Starting score for Player 1
    dice:       A function of zero arguments that simulates a dice roll.
    goal:       The game ends and someone wins when this score is reached.
    say:        The commentary function to call at the end of the first turn.
    """
    who = 0  # Who is about to take a turn, 0 (first) or 1 (second)
    # BEGIN PROBLEM 5
    "*** YOUR CODE HERE ***"
    while score0 < goal and score1 < goal:
        if who == 0:
            score0 += take_turn(strategy0(score0,score1), score1, dice, goal)
            if not more_boar(score0, score1):
                who = next_player(who)
        else:
            score1 += take_turn(strategy1(score1,score0), score0, dice, goal)
            if not more_boar(score1, score0):
                who = next_player(who)
    # END PROBLEM 5
    # (note that the indentation for the problem 6 prompt (***YOUR CODE HERE***) might be misleading)
    # BEGIN PROBLEM 6
        "*** YOUR CODE HERE ***"
        say = say(score0, score1)
    # END PROBLEM 6
    return score0, score1
posted @ 2021-05-27 21:29  ikventure  阅读(6575)  评论(1编辑  收藏  举报