abbarnes

Yahtzee Strategy Simulator [codeskulptor]

Dec 12th, 2017
393
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.15 KB | None | 0 0
  1. """
  2. Planner for Yahtzee
  3. Simplifications:  only allow discard and roll, only score against upper level
  4. """
  5. #http://www.codeskulptor.org/#user43_hIq8DOUzOePl1QE_4.py
  6.  
  7. # Used to increase the timeout, if necessary
  8. import codeskulptor
  9. codeskulptor.set_timeout(20)
  10.  
  11. def gen_all_sequences(outcomes, length):
  12.     """
  13.    Iterative function that enumerates the set of all sequences of
  14.    outcomes of given length.
  15.    """
  16.    
  17.     answer_set = set([()])
  18.     for dummy_idx in range(length):
  19.         temp_set = set()
  20.         for partial_sequence in answer_set:
  21.             for item in outcomes:
  22.                 new_sequence = list(partial_sequence)
  23.                 new_sequence.append(item)
  24.                 temp_set.add(tuple(new_sequence))
  25.         answer_set = temp_set
  26.     return answer_set
  27.  
  28.  
  29. def score(hand):
  30.     """
  31.    Compute the maximal score for a Yahtzee hand according to the
  32.    upper section of the Yahtzee score card.
  33.  
  34.    hand: full yahtzee hand
  35.  
  36.    Returns an integer score
  37.    """
  38.     scores = []
  39.     for die_num in range(max(hand)+1)[1:]:
  40.         num_dice = hand.count(die_num)
  41.         scores.append(num_dice*die_num)
  42.     return max(scores)
  43.  
  44.  
  45. def expected_value(held_dice, num_die_sides, num_free_dice):
  46.     """
  47.    Compute the expected value based on held_dice given that there
  48.    are num_free_dice to be rolled, each with num_die_sides.
  49.  
  50.    held_dice: dice that you will hold
  51.    num_die_sides: number of sides on each die
  52.    num_free_dice: number of dice to be rolled
  53.  
  54.    Returns a floating point expected value
  55.    """
  56. #    print "Holding dice ", held_dice
  57.     poss_rolls = gen_all_sequences(range(num_die_sides+1)[1:], num_free_dice)
  58. #    print len(poss_rolls), " possible outcomes for ", num_free_dice, "rolls"
  59.     #poss_scores will store the scores of all possible hands (held_dice + each possible roll)
  60.     poss_scores = []
  61.     for roll in poss_rolls:
  62.         held = list(held_dice)
  63. #        print "Evaluating held ", held, " + outcome ", roll
  64.         for rol in roll:
  65.             held.append(rol)
  66.         my_score = score(held)
  67. #        print "Now holding ", held, " with score " , my_score
  68.         poss_scores.append(my_score)
  69. #        print "Possible scores is now", poss_scores
  70. #        print
  71.    
  72.     return float(sum(poss_scores))/len(poss_rolls)
  73.  
  74.  
  75. def gen_all_holds(hand):
  76.     """
  77.    Generate all possible choices of dice from hand to hold.
  78.  
  79.    hand: full yahtzee hand
  80.  
  81.    Returns a set of tuples, where each tuple is dice to hold
  82.    """
  83.     all_holds = set([()])
  84.     hand_filters = gen_all_sequences([0,1], len(hand))
  85.     for hand_filter in hand_filters:
  86.         hold = []
  87.         for dummy_i in range(len(hand_filter)):
  88.             if hand_filter[dummy_i] == 1:
  89.                 hold.append(hand[dummy_i])
  90.         #print hold
  91.         all_holds.add(tuple(hold))
  92.    
  93.     return all_holds
  94.  
  95.  
  96.  
  97. def strategy(hand, num_die_sides):
  98.     """
  99.    Compute the hold that maximizes the expected value when the
  100.    discarded dice are rolled.
  101.  
  102.    hand: full yahtzee hand
  103.    num_die_sides: number of sides on each die
  104.  
  105.    Returns a tuple where the first element is the expected score and
  106.    the second element is a tuple of the dice to hold
  107.    """
  108.     all_holds = list(gen_all_holds(hand))
  109.     values = []
  110.     for hold in all_holds:
  111.         values.append(expected_value(hold, num_die_sides, len(hand)-len(hold)))
  112.     best_hold = tuple(all_holds[values.index(max(values))])
  113.     my_result = [expected_value(best_hold, num_die_sides, len(hand)-len(best_hold)), best_hold]
  114.     print my_result
  115.    
  116.     return tuple(my_result)
  117.  
  118.  
  119. def run_example():
  120.     """
  121.    Compute the dice to hold and expected score for an example hand
  122.    """
  123.     num_die_sides = 6
  124.     hand = (1, 1, 1, 5, 6)
  125.     hand_score, hold = strategy(hand, num_die_sides)
  126.     print "Best strategy for hand", hand, "is to hold", hold, "with expected score", hand_score
  127.    
  128.    
  129. #run_example()
  130.  
  131. #print score([1,1,3,3,3])
  132. #print expected_value([], 6, 3)
  133.  
  134. #print gen_all_holds([1,2,2])
  135.  
  136. #print strategy([1,6],6)
  137.  
  138. #import poc_holds_testsuite
  139. #poc_holds_testsuite.run_suite(gen_all_holds)
Advertisement
Add Comment
Please, Sign In to add comment