Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Planner for Yahtzee
- Simplifications: only allow discard and roll, only score against upper level
- """
- #http://www.codeskulptor.org/#user43_hIq8DOUzOePl1QE_4.py
- # Used to increase the timeout, if necessary
- import codeskulptor
- codeskulptor.set_timeout(20)
- def gen_all_sequences(outcomes, length):
- """
- Iterative function that enumerates the set of all sequences of
- outcomes of given length.
- """
- answer_set = set([()])
- for dummy_idx in range(length):
- temp_set = set()
- for partial_sequence in answer_set:
- for item in outcomes:
- new_sequence = list(partial_sequence)
- new_sequence.append(item)
- temp_set.add(tuple(new_sequence))
- answer_set = temp_set
- return answer_set
- def score(hand):
- """
- Compute the maximal score for a Yahtzee hand according to the
- upper section of the Yahtzee score card.
- hand: full yahtzee hand
- Returns an integer score
- """
- scores = []
- for die_num in range(max(hand)+1)[1:]:
- num_dice = hand.count(die_num)
- scores.append(num_dice*die_num)
- return max(scores)
- def expected_value(held_dice, num_die_sides, num_free_dice):
- """
- Compute the expected value based on held_dice given that there
- are num_free_dice to be rolled, each with num_die_sides.
- held_dice: dice that you will hold
- num_die_sides: number of sides on each die
- num_free_dice: number of dice to be rolled
- Returns a floating point expected value
- """
- # print "Holding dice ", held_dice
- poss_rolls = gen_all_sequences(range(num_die_sides+1)[1:], num_free_dice)
- # print len(poss_rolls), " possible outcomes for ", num_free_dice, "rolls"
- #poss_scores will store the scores of all possible hands (held_dice + each possible roll)
- poss_scores = []
- for roll in poss_rolls:
- held = list(held_dice)
- # print "Evaluating held ", held, " + outcome ", roll
- for rol in roll:
- held.append(rol)
- my_score = score(held)
- # print "Now holding ", held, " with score " , my_score
- poss_scores.append(my_score)
- # print "Possible scores is now", poss_scores
- # print
- return float(sum(poss_scores))/len(poss_rolls)
- def gen_all_holds(hand):
- """
- Generate all possible choices of dice from hand to hold.
- hand: full yahtzee hand
- Returns a set of tuples, where each tuple is dice to hold
- """
- all_holds = set([()])
- hand_filters = gen_all_sequences([0,1], len(hand))
- for hand_filter in hand_filters:
- hold = []
- for dummy_i in range(len(hand_filter)):
- if hand_filter[dummy_i] == 1:
- hold.append(hand[dummy_i])
- #print hold
- all_holds.add(tuple(hold))
- return all_holds
- def strategy(hand, num_die_sides):
- """
- Compute the hold that maximizes the expected value when the
- discarded dice are rolled.
- hand: full yahtzee hand
- num_die_sides: number of sides on each die
- Returns a tuple where the first element is the expected score and
- the second element is a tuple of the dice to hold
- """
- all_holds = list(gen_all_holds(hand))
- values = []
- for hold in all_holds:
- values.append(expected_value(hold, num_die_sides, len(hand)-len(hold)))
- best_hold = tuple(all_holds[values.index(max(values))])
- my_result = [expected_value(best_hold, num_die_sides, len(hand)-len(best_hold)), best_hold]
- print my_result
- return tuple(my_result)
- def run_example():
- """
- Compute the dice to hold and expected score for an example hand
- """
- num_die_sides = 6
- hand = (1, 1, 1, 5, 6)
- hand_score, hold = strategy(hand, num_die_sides)
- print "Best strategy for hand", hand, "is to hold", hold, "with expected score", hand_score
- #run_example()
- #print score([1,1,3,3,3])
- #print expected_value([], 6, 3)
- #print gen_all_holds([1,2,2])
- #print strategy([1,6],6)
- #import poc_holds_testsuite
- #poc_holds_testsuite.run_suite(gen_all_holds)
Advertisement
Add Comment
Please, Sign In to add comment