def test_ai_get_best_adj_triple_alone(self): # should not take 777888 because need two sevens for 556677 card_strs = [ '5c', '5d', '6h', '6s', '7h', '7d', '7c', '8s', '8d', '8c', '9s', '9d', '9c', '0h' ] player = TestAIPlayer.generate_ai_from_card_strs(card_strs) prev_play1 = Play( 0, [Card('2', 'd'), Card('2', 's'), Card('2', 'c')], 0, play_type=TRIPLES) prev_play2 = Play(2, [ Card('3', 'h'), Card('3', 'd'), Card('3', 'c'), Card('4', 'd'), Card('4', 's'), Card('4', 'c'), Card('5', 'h'), Card('6', 'd') ], 2, play_type=ADJ_TRIPLES) self.setup_game_state([prev_play1, prev_play2]) best_play = player.get_best_adj_triples(self.game_state) assert best_play[0].name == '8' assert best_play[3].name == '9' assert best_play[6].name == '7' assert best_play[7].name == '0' _check_adj_triple(best_play.cards, 2)
def get_play_from_input(user_input): """returns card play based on user's input""" if not user_input: return Play.get_pass_play() player_card_strs = user_input.split() played_cards = Card.strs_to_cards(player_card_strs) return Play.get_play_from_cards(played_cards)
def generate_possible_straights(self, other_card, each_count, length): """ Returns an iterator of all the possible straights length = each_count * distinct number of cards """ play_type = CATEGORIES[4 + each_count - 1] for card_group in self._categories[play_type]: if not other_card: yield Play(-1, card_group, 0, play_type=play_type) continue for i, c in enumerate(card_group): if c.value > other_card.value and len(card_group) - i >= length * each_count: yield Play(-1, card_group[i: i + length * each_count], 0, play_type=play_type)
def get_best_play(self, game_state): """ Returns lowest play of play_type """ prev_play = game_state.prev_play unrevealed_cards = [] if not prev_play or prev_play.position == self.position: # lead play next_play = self.get_best_lead_play(game_state) else: prev_type = prev_play.play_type if prev_type == DOUBLE_JOKER: return Play.get_pass_play(position=self.position) elif prev_type == SINGLES: next_play = self.get_best_singles(game_state) elif prev_type == DOUBLES: next_play = self.get_best_doubles(game_state) elif prev_type == TRIPLES: next_play = self.get_best_triples(game_state) elif prev_type == STRAIGHTS: next_play = self.get_best_straights(game_state) elif prev_type == DOUBLE_STRAIGHTS: next_play = self.get_best_double_straights(game_state) elif prev_type == ADJ_TRIPLES: next_play = self.get_best_adj_triples(game_state) elif prev_type == QUADRUPLES: next_play = self.get_best_quad(game_state) # if next play is none and the player has less than 5 * (number of wilds in hand) cards, # play wilds # and game_state.get_player_num_cards(prev_play.position) <= 5 * self.hand.get_num_wild(): if next_play: next_play.position = self.position return next_play
def get_best_adj_triples(self, game_state): best_play = self._get_best_singular_straight(game_state, 3) if not best_play: return Play.get_pass_play(position=self.position) extra_each_count = game_state.prev_play.num_extra // 2 return self._get_best_play_with_extra(game_state, best_play, 2, extra_each_count)
def generate_possible_wilds(self, other_card): """ Returns an iterator of all the possible wilds """ yield from self.generate_possible_basics(other_card, 4) if self._categories[DOUBLE_JOKER]: yield Play(-1, self._categories[DOUBLE_JOKER][0], 0, play_type=DOUBLE_JOKER)
def get_low_wild(self, other_card): """ Returns the lowest wild play that is above given card Pos of the play is -1 """ iterator = self.generate_possible_wilds(other_card) return next(iterator, Play.get_pass_play())
def test_ai_get_best_doubles(self): prev_play = Play(2, [Card('8', 'c'), Card('8', 'd')], 0, play_type=DOUBLES) self.setup_game_state([prev_play]) best_play = self.test_ai_player_lv2.get_best_doubles(self.game_state) assert best_play[0].name == '9' _check_double(best_play.cards)
def _get_single_best_play(card_plays, player, game_state): """Gets the best play optimized for returning only one play""" best_play = Play.get_pass_play(position=player.position) for play in card_plays: play.position = player.position play.strength = estimate_play_strength(play, player, game_state) if not best_play or play.strength > best_play.strength: best_play = play return best_play
def test_ai_get_best_triples_alone(self): prev_play = Play( 2, [Card('J', 'h'), Card('J', 'd'), Card('J', 'c')], 0, play_type=TRIPLES) self.setup_game_state([prev_play]) best_play = self.test_ai_player_lv3.get_best_triples(self.game_state) assert best_play[0].name == 'Q' _check_triple(best_play.cards)
def generate_possible_low_foundations(self, other_card, play_type): """ Returns an iterator of all basic foundations (individual singles, doubles, triples, or quadruples) """ possibles = [] for card_group in self._categories[play_type]: card = card_group[0] if not other_card or card.value > other_card.value: yield Play(-1, card_group, 0, play_type=play_type)
def test_best_play_single_and_triple(self): """tests best play function""" computer_card_strs = ['3d', '3s', '3c', '4c', 'Ah'] unrevealed_card_strs = ['Qd', 'Qs', 'Qc', '7c', 'Kd', 'Ks', 'Kc', '8d'] game_state, computer = TestMC.generate_game_state( computer_card_strs, unrevealed_card_strs, 1) play1 = computer.get_best_play(game_state) game_state.prev_play = Play(2, [Card('K', 'h')], 0) play2 = computer.get_best_play(game_state) assert get_best_play(iter([play1, play2]), computer, game_state) == play2
def test_ai_get_best_wild(self): card_strs = [ '5c', '5d', '6h', '6s', '7h', '7d', '7c', '7s', '8d', '8c', 'As', 'Ad', 'Ac', 'Ah', 'Z0', 'Z1' ] player = TestAIPlayer.generate_ai_from_card_strs(card_strs) prev_play1 = Play(0, [Card('2', 'd')], 0, play_type=SINGLES) prev_play2 = Play( 2, [Card('4', 's'), Card('4', 'c'), Card('4', 'd'), Card('4', 'h')], 0, play_type=QUADRUPLES) self.setup_game_state([prev_play1, prev_play2]) best_play = player.get_best_wild(self.game_state) assert best_play.get_base_card().name == 'A' _check_quadruples(best_play.cards)
def test_best_play_two_singles(self): """tests best play function""" computer_card_strs = ['0d', '2s'] unrevealed_card_strs = ['Qd', 'kd'] game_state, computer = TestMC.generate_game_state( computer_card_strs, unrevealed_card_strs, 1) play1 = computer.get_best_play(game_state) game_state.prev_play = Play(2, [Card('K', 'h')], 0) play2 = computer.get_best_play(game_state) assert get_best_play(iter([play1, play2]), computer, game_state) == play2
def get_low_adj_triple(self, other_card, num_extra): """ Gets the lowest adj triple that meets the properties Arguments: other_card -- the lowest card value of the triples num_extra -- 2 if it carries 2 singles 4 if it carries 2 doubles Returns play with pos of -1 or None """ iterator = self.generate_possible_adj_triples(other_card, num_extra) return next(iterator, Play.get_pass_play())
def get_low(self, other_card, each_count, extra=0): """ Gets the lowest basic that meets the properties Arguments: other_card -- lowest card in the basic each_count -- if its a single, double, triple, or quad (wild) extra -- the number of extra cards (1 or 2 for triple) (2 or 4 for quad) Returns the lowest play with pos -1 or None """ iterator = self.generate_possible_basics(other_card, each_count, extra=extra) return next(iterator, Play.get_pass_play())
def wrapper(self, game_state): best_play = get_best_specific_play(self, game_state) if best_play: pass_play_strength = estimate_play_strength( None, self, game_state) if best_play.strength < pass_play_strength - self.pass_play_significance: pass_play = Play.get_pass_play(position=self.position) pass_play.strength = pass_play_strength return pass_play return best_play
def get_low_straight(self, other_card, each_count, length): """ Gets the lowest straight that meets the properties Arguments: other_card -- lowest card in the opposing straight each_count -- if its a single, double, or triple straight length -- length of the opposing straight each_count * distinct number of cards length is ignored when other_card is None Returns play with pos of -1 or None """ iterator = self.generate_possible_straights(other_card, each_count, length) return next(iterator, Play.get_pass_play())
def test_ai_get_best_quad_double(self): # should take 77775566 (follow up with AAAA then 88) card_strs = [ '5c', '5d', '6h', '6s', '7h', '7d', '7c', '7s', '8d', '8c', 'As', 'Ad', 'Ac', 'Ah' ] player = TestAIPlayer.generate_ai_from_card_strs(card_strs) prev_play1 = Play( 0, [Card('2', 'd'), Card('2', 's'), Card('2', 'c')], 0, play_type=TRIPLES) prev_play2 = Play(1, [ Card('9', 'd'), Card('0', 'd'), Card('J', 's'), Card('Q', 'c'), Card('K', 'c') ], 0, play_type=STRAIGHTS) prev_play3 = Play(2, [ Card('4', 's'), Card('4', 'c'), Card('4', 'd'), Card('4', 'h'), Card('3', 'h'), Card('3', 's'), Card('5', 'h'), Card('5', 's') ], 4, play_type=QUADRUPLES) self.setup_game_state([prev_play1, prev_play2, prev_play3]) best_play = player.get_best_quad(self.game_state) assert best_play[0].name == '7' _check_quadruples(best_play.cards)
def test_multiple_best_play(self): """tests multiple best play function""" computer_card_strs = ['3d', '3s', '3c', '4c', 'Ah'] unrevealed_card_strs = ['Qd', 'Qs', 'Qc', '7c', 'Kd', 'Ks', 'Kc', '8d'] game_state, computer = TestMC.generate_game_state( computer_card_strs, unrevealed_card_strs, 1) play1 = computer.get_best_play(game_state) game_state.prev_play = Play(2, [Card('K', 'h')], 0) play2 = computer.get_best_play(game_state) ordered_best_plays = get_best_play(iter([play1, play2]), computer, game_state, num_best=2) assert ordered_best_plays[0] == play2 assert ordered_best_plays[1] == play1
def _get_best_play_with_extra(self, game_state, base_play, extra_count, extra_each_count): """ Gets the best play with extras assuming that the base play is the best of the base plays game_state -- current game state base_play -- the play to add extras to extra_count -- number of extras to add (1 for a one single or double; 2 for two singles or doubles) extra_each_count -- the occurance of the extras (1 for single, 2 for double) """ prev_play = game_state.prev_play if not prev_play or not prev_play.num_extra: # TODO: if prev play is None, get best possible triple extras return base_play possible_extras = self.hand.generate_possible_extra_cards( base_play.cards, extra_each_count, extra_count) possible_plays = [Play(self.position, base_play.cards + extra, prev_play.num_extra, prev_play.play_type)\ for extra in possible_extras] return get_best_play(possible_plays, self, game_state)
def test_ai_get_best_single_straight(self): card_strs = [ '3c', '3d', '4s', '6h', '6d', '6c', '7h', '7d', '9c', '0s', 'Jd', 'Qc', 'Qs', 'Kd', 'Ac', 'Ah', 'Z0' ] player = TestAIPlayer.generate_ai_from_card_strs(card_strs) prev_play = Play(2, [ Card('3', 'h'), Card('4', 'd'), Card('5', 'c'), Card('6', 's'), Card('7', 's') ], 0, play_type=STRAIGHTS) self.setup_game_state([prev_play]) best_play = player.get_best_straights(self.game_state) assert best_play[0].name == '9' _check_straight(best_play.cards, 1)
def test_ai_get_best_double_straight(self): card_strs = [ '6h', '6c', '6s', '7s', '7d', '7c', '8d', '8h', '9H', '9D', '0H', '0S', 'Js', 'Qd', 'KD', 'KC', '2C' ] player = TestAIPlayer.generate_ai_from_card_strs(card_strs) prev_play = Play(2, [ Card('3', 'h'), Card('3', 'd'), Card('4', 'c'), Card('4', 's'), Card('5', 's'), Card('5', 'c') ], 0, play_type=DOUBLE_STRAIGHTS) self.setup_game_state([prev_play]) best_play = player.get_best_double_straights(self.game_state) assert best_play[0].name == '8' _check_straight(best_play.cards, 2)
def test_ai_get_best_triples_double(self): card_strs = [ '3c', '3d', '6h', '6s', '6d', '6c', '7h', '7d', '7c', '8s', '9d', '0c', 'Qs', 'Kd', 'Ac', '2h', 'Z0' ] player = TestAIPlayer.generate_ai_from_card_strs(card_strs) prev_play = Play(2, [ Card('5', 'h'), Card('5', 'd'), Card('5', 'c'), Card('4', 'c'), Card('4', 's') ], 2, play_type=TRIPLES) self.setup_game_state([prev_play]) best_play = player.get_best_triples(self.game_state) assert best_play[0].name == '7' assert best_play[3].name == '3' _check_triple(best_play.cards)
def test_ai_get_best_singles(self): prev_play = Play(2, [Card('3', 'h')], 0, play_type=SINGLES) self.setup_game_state([prev_play]) best_play = self.test_ai_player_lv3.get_best_singles(self.game_state) assert best_play[0].name == 'A' _check_single(best_play.cards)