def game(strat1: Strategy, strat2: Strategy, crib: int, point_cap: int) -> pd.Series: """ This function takes care of actual game simulation. crib is 1 if strat2 starts with the crib and 0 otherwise. It returns a pandas series with information about the game. - strat1_score: the score for strategy 1 - strat1_hand: the number of points strat1 gained from their hand - strat1_crib: the number of points strat1 gained from their crib - strat1_peg: the number of points strat1 gained from pegging - ... all the same fields for strat2 ... """ game_context = GameContext(crib, point_cap, RandomDeck()) while True: options1, options2, cutCard = game_context.new_turn() crib_hand = [] # Choose strat1 hand hand1 = strat1.chooseHand(options1, 1 - crib) assert (all(card in options1 for card in hand1)) crib_hand.extend(card for card in options1 if card not in hand1) # Choose strat2 hand hand2 = strat2.chooseHand(options2, crib) assert (all(card in options2 for card in hand2)) crib_hand.extend(card for card in options2 if card not in hand2) logger.info(f"{formatCard(cutCard)} was cut.\n") if "J" in formatCard(cutCard) and game_context.add_points( game_context.crib, JACK_POINTS, 2): break if peg(game_context, [strat1, strat2], [hand1.copy(), hand2.copy()]): break # Score the hands here hand_points = [ scoreHand(hand1, cutCard, 1 - game_context.crib), scoreHand(hand2, cutCard, game_context.crib) ] crib_points = scoreHand(crib_hand, cutCard) # The person without the crib always gets the chance to score their # hand first. We'll also check for a win condition after every addition # using the add_points hand. If any of them returns True, the # expression will short-circuit before the rest complete. if game_context.add_points(1 - game_context.crib, HAND_POINTS, hand_points[1 - game_context.crib]) or \ game_context.add_points(game_context.crib, HAND_POINTS, hand_points[game_context.crib]) or \ game_context.add_points(game_context.crib, CRIB_POINTS, crib_points): break return game_context.finish_game()
def _score(crib: bool) -> pd.Series: hand, _, cutCard = deck.deal() options = strat.chooseHand(hand, crib) discarded = [c for c in hand if c not in options] return pd.Series( options + discarded + [cutCard, crib, scoreHand(options, cutCard)], index=fields)
def test_runs(): assert(scoreHand([0, 14, 28, 42], 43) == 7) assert(scoreHand([0, 14, 28, 42], 29) == 10) assert(scoreHand([10, 23, 36, 48], 50) == 15) assert(scoreHand([10, 23, 48, 50], 37) == 16)
def test_pairs(): assert(scoreHand([1, 16, 31, 46], 48) == 0) assert(scoreHand([1, 14, 31, 46], 48) == 2) assert(scoreHand([1, 14, 27, 46], 48) == 6) assert(scoreHand([1, 14, 27, 40], 48) == 12)
def test_best_hand(): assert(scoreHand([4, 30, 17, 36], 43) == 28) assert(scoreHand([4, 43, 17, 36], 30) == 29)
def test_fifteens(): assert(scoreHand([20, 33, 29, 16], 15) == 12) assert(scoreHand([45, 46, 32, 33], 21) == 24) assert(scoreHand([41, 28, 29, 30], 48) == 12) assert(scoreHand([44, 40, 13, 17], 26) == 4)
def test_flush(): assert(scoreHand([1, 3, 5, 20], 9) == 0) assert(scoreHand([1, 3, 5, 7], 22) == 4) assert(scoreHand([1, 3, 5, 7], 22, crib=True) == 0) assert(scoreHand([1, 3, 5, 7], 9) == 5) assert(scoreHand([1, 3, 5, 7], 9, crib=True) == 5)
def getScores(self, hand: List[int], discarded: List[int], crib: bool) -> List[int]: return [scoreHand(hand, cutCard) for cutCard in range(52) \ if cutCard not in hand and cutCard not in discarded]