def bock_distance(self, card, card_counter, state): stronger = card_counter.filter_not_dead_cards_of_same_suit( card, lambda x: x.value > card.value) stronger = [x for x in stronger if x not in card_counter.get_hand()] table_cards = [from_string_to_card(x['card']) for x in state['table']] stronger = [x for x in stronger if x not in table_cards] return len(stronger)
def analyse_table(table): table_list = [] for played_card in table: player_id = played_card['player_id'] card = from_string_to_card(played_card['card']) table_list.append((player_id, card)) return table_list
def want_stich(self, cards_by_suit, card_counter, player_acting_behind, state): we_can_make_all_stich = True we_lose_stich_if_we_dont = False for suit, suit_cards in cards_by_suit: for card in suit_cards: if not self.is_bock(card, card_counter) and \ card_counter.has_card_likelihood(card_counter.opponent_1_id, card, state) > 0 or \ card_counter.has_card_likelihood(card_counter.opponent_2_id, card, state) > 0: we_can_make_all_stich = False color = from_string_to_card(state['table'][0]['card']).suit if not player_acting_behind: if len([x[1] for x in split_cards_by_suit(card_counter.unknown_cards()) if x[0] == color]) == 0 and \ len([x[1] for x in cards_by_suit if x[0] == color]) > 1: we_lose_stich_if_we_dont = True elif card_counter.has_suit_likelihood(card_counter.opponent_1_id, color, state) == 1: if len([x[1] for x in split_cards_by_suit(card_counter.unknown_cards()) if x[0] == color]) == 1 and \ len([x[1] for x in cards_by_suit if x[0] == color]) > 1: we_lose_stich_if_we_dont = True if card_counter.round_leader(state) == card_counter.partner_id and ( not player_acting_behind or \ card_counter.has_cards_likelihood(card_counter.opponent_1_id, self.cards_beating_current_stich(card_counter.unknown_cards(), card_counter, state), state) == 0): partner_is_not_certain_to_win = False else: partner_is_not_certain_to_win = True return (we_can_make_all_stich or we_lose_stich_if_we_dont or partner_is_not_certain_to_win)
def allowed_cards(self, state): table_cards = [ from_string_to_card(entry['card']) for entry in state['table'] ] trumpf = Trumpf[state['trumpf']] return allowed_cards(hand_cards=self.cards, table_cards=table_cards, trumpf=trumpf)
def choose_card(self, state=None): allowed = False self.input_handler_game_network.update_state_choose_card(game_state=state, cards=self.cards, player_id=self.id) predictions, prediction_indexes = self.act(self.input_handler_game_network.state) card = self.max_of_allowed_cards(state=state, predictions=predictions) self.current_memory['action'] = prediction_indexes[0] self.current_memory['hand_cards'] = self.cards[:] self.current_memory['table_cards'] = [from_string_to_card(entry['card']) for entry in state['table']] self.current_memory['trumpf'] = Trumpf[state['trumpf']] while not allowed: allowed = yield card if allowed: yield None else: logger.info('not allowed card!')
def get_stich_card(self, cards_by_suit, card_counter, state): if len(state['table']) > 0: current_stich_color = from_string_to_card( state['table'][0]['card']).suit tmp_list = [ x[1] for x in cards_by_suit if (x[0] == current_stich_color or x[0] == self.suit) ] current_color_cards = [ item for sublist in tmp_list for item in sublist ] cards = self.cards_beating_current_stich(current_color_cards, card_counter, state) stich_cards = [] if len(state['table']) == 3: stich_cards.extend(cards) if len(cards) > 0 and len(state['table']) < 3: for card in cards: stronger = self.stronger_cards_unknown(card, card_counter) if len(stronger) != 0: # may use has_cards_likelihood (plural) if card_counter.has_cards_likelihood( card_counter.opponent_1_id, stronger, state) == 0: if len(state['table'] ) > 0 or card_counter.has_cards_likelihood( card_counter.opponent_2_id, stronger, state) == 0: stich_cards.append(card) else: stich_cards.append(card) if len(stich_cards) > 0: s_cards = self.sort_by_rank(stich_cards) for card in s_cards: if card.value == 10: return card return s_cards[0] return None
def cards_beating_current_stich(self, available_cards, card_counter, state): curr_pos = len(state['table']) if curr_pos != 0: for card_played in state['table']: if card_played['player_id'] == card_counter.round_leader( state): current_stich_winner = from_string_to_card( card_played['card']) break cards_beating_winner = self.stronger_cards_remaining( current_stich_winner, card_counter) beating_cards = [] for card in available_cards: if card in cards_beating_winner: beating_cards.append(card) else: beating_cards = available_cards return sorted( beating_cards, key=lambda card: card.get_score(get_trumpf(state['trumpf'])))
def update_flags(self, player_id, card, state): current_stich_color = None if len(state['table']) > 0: current_stich_color = from_string_to_card( state['table'][0]['card']).suit mode = get_mode(state['trumpf']) if len(self.current_stich) == 4: if player_id == self.partner_id and self.round_leader( state) != self.my_id and self.round_leader( state) != self.partner_id: #neither of us wins, A2 played last card -> A2 doesn't have anything beating current stich for stronger_card in mode.stronger_cards_remaining( self.current_stich[self.round_leader(state)], self): self.flags[player_id].append( DoesntHaveCardFlag(stronger_card)) if len(self.current_stich) == 1: if mode.trumpf_name().name not in [x.name for x in Suit]: if player_id == self.partner_id and not mode.is_bock( card, self): for suit in Suit: self.flags[player_id].append( DoesntHaveCardFlag( mode.get_current_bock(suit, self))) if not self.had_stich_previously(player_id): if not (self.current_round() == 0 and state['geschoben'] and (mode.trumpf_name().name in [x.name for x in Suit])): self.flags[player_id].append(PreviouslyHadStichFlag()) if self.round_leader(state) == self.partner_id: if mode.trumpf_name().name in [x.name for x in Suit]: if self.current_round() == 0: if state['geschoben']: if card.suit == mode.trumpf_name().name: for stronger_card in mode.stronger_cards_remaining( card, self): if stronger_card.value != 11: self.flags[player_id].append( DoesntHaveCardFlag(stronger_card)) if card == mode.get_current_bock( card.suit, self) and card.suit != mode.trumpf_name().name: for suit_cards in split_cards_by_suit( self.unknown_cards()): if suit_cards[0].name == mode.trumpf_name().name: for trumpf_card in suit_cards[1]: self.flags[(self.my_id + 1) % 4].append( DoesntHaveCardFlag(trumpf_card)) self.flags[(self.my_id + 3) % 4].append( DoesntHaveCardFlag(trumpf_card)) if len(self.current_stich) > 1: if card.suit != current_stich_color: if (mode.trumpf_name().name in [x.name for x in Suit] and card.suit != mode.trumpf_name().name ) or mode.trumpf_name().name not in [x.name for x in Suit]: self.flags[player_id].append( FailedToServeSuitFlag(current_stich_color)) self.flags[player_id].append(SuitVerworfenFlag(card.suit))
def get_card_to_play(self, available_cards, card_counter, state, role): current_position = len(state['table']) cards_by_suit = split_cards_by_suit(available_cards) bocks = list( filter(lambda x: self.is_bock(x, card_counter), available_cards)) beating_current_stich = self.cards_beating_current_stich( available_cards, card_counter, state) if current_position == 0: if len(bocks) > 0: return bocks[0] elif not card_counter.had_stich_previously( card_counter.partner_id): return self.get_passing_card(cards_by_suit, card_counter, state) else: return self.get_value_card(cards_by_suit, card_counter, state) elif current_position == 1: stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is None: return self.get_tossable_card(available_cards, card_counter, state) return stich_card elif current_position == 2: if role == 'Trumpf': if not card_counter.had_stich_previously(card_counter.my_id): stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is None: return self.get_tossable_card(available_cards, card_counter, state) return stich_card else: if not self.want_stich(cards_by_suit, card_counter, True, state): return self.get_tossable_card(available_cards, card_counter, state) else: stich_card = self.get_stich_card( cards_by_suit, card_counter, state) if stich_card is None: return self.get_tossable_card( available_cards, card_counter, state) return stich_card elif role == 'Off': if self.want_stich(cards_by_suit, card_counter, True, state): stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is None: return self.get_tossable_card(available_cards, card_counter, state) return stich_card elif role == 'Partner': if card_counter.current_round( ) == 0 and card_counter.round_leader( state) == card_counter.partner_id: a2card = card_counter.current_stich[ card_counter.partner_id] if self.is_nth_nut(1, a2card, card_counter): round_color = from_string_to_card( state['table'][0]['card']).suit for card in [ x[1] for x in cards_by_suit if x[0] == round_color ][0]: if self.is_nth_nut(2, card, card_counter): play_2nd_nut = True for card2 in [ x[1] for x in cards_by_suit if x[0] == round_color ][0]: if self.is_nth_nut(3, card2, card_counter): play_2nd_nut = False if play_2nd_nut: return card if self.want_stich(cards_by_suit, card_counter, True, state): stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is not None: return stich_card return self.get_tossable_card(available_cards, card_counter, state) elif current_position == 3: if self.want_stich(cards_by_suit, card_counter, False, state): stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is not None: return stich_card return self.get_tossable_card(available_cards, card_counter, state) return None
def get_card_to_play(self, available_cards, card_counter, state, role): current_position = len(state['table']) cards_by_suit = split_cards_by_suit(available_cards) sorted_trumpf_cards = self.sort_by_rank( [x[1] for x in cards_by_suit if x[0] == self.suit][0]) non_trumpf_bocks = [] bocks = [] for card in available_cards: if self.is_non_trumpf_bock( card, card_counter) and card.suit != self.suit: non_trumpf_bocks.append(card) if self.is_bock(card, card_counter): bocks.append(card) opponents_out_of_trumpf = card_counter.has_suit_likelihood(card_counter.opponent_1_id, self.suit, state) == 0 \ and card_counter.has_suit_likelihood(card_counter.opponent_2_id, self.suit, state) == 0 if current_position == 0: if role == 'Trumpf' or role == 'Off': pulling_trumpfs = (not opponents_out_of_trumpf and len(sorted_trumpf_cards) > 0) if pulling_trumpfs: return sorted_trumpf_cards[0] elif len(non_trumpf_bocks) > 0 and opponents_out_of_trumpf: return non_trumpf_bocks[0] else: if not opponents_out_of_trumpf and len( sorted_trumpf_cards) == 0: return self.get_tossable_card(available_cards, card_counter, state) if not card_counter.had_stich_previously( card_counter.partner_id): return self.get_passing_card(cards_by_suit, card_counter, state) else: return self.get_value_card(cards_by_suit, card_counter, state) elif role == 'Partner': if not card_counter.had_stich_previously( card_counter.partner_id): sorted_trumpf_cards = list( filter(lambda card: card.value != 11, sorted_trumpf_cards)) if len(sorted_trumpf_cards) != 0: return sorted_trumpf_cards[0] else: return self.get_passing_card(cards_by_suit, card_counter, state) else: pulling_trumpfs = not opponents_out_of_trumpf and len( sorted_trumpf_cards) > 0 if pulling_trumpfs: return sorted_trumpf_cards[0] elif len(non_trumpf_bocks) > 0: return non_trumpf_bocks[0] else: self.get_value_card(cards_by_suit, card_counter, state) elif current_position == 1: stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is None: return self.get_tossable_card(available_cards, card_counter, state) return stich_card elif current_position == 2: if role == 'Trumpf': if not card_counter.had_stich_previously(card_counter.my_id): ret = self.get_stich_card(cards_by_suit, card_counter, state) if ret is not None: return ret else: return self.get_tossable_card(available_cards, card_counter, state) else: if not self.want_stich(cards_by_suit, card_counter, True, state): return self.get_tossable_card(available_cards, card_counter, state) else: return self.get_stich_card(cards_by_suit, card_counter, state) elif role == 'Off': if self.want_stich(cards_by_suit, card_counter, True, state): stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is not None: return stich_card return self.get_tossable_card(available_cards, card_counter, state) elif role == 'Partner': if card_counter.current_round( ) == 0 and card_counter.round_leader( state) == card_counter.partner_id: a2card = card_counter.current_stich[ card_counter.partner_id] if self.is_nth_nut(1, a2card, card_counter): round_color = from_string_to_card( state['table'][0]['card']).suit for card in [ x[1] for x in cards_by_suit if x[0] == round_color ][0]: if self.is_nth_nut(2, card, card_counter): play_2nd_nut = True for card2 in [ x[1] for x in cards_by_suit if x[0] == round_color ][0]: if self.is_nth_nut(3, card2, card_counter): play_2nd_nut = False if play_2nd_nut: return card if self.want_stich(cards_by_suit, card_counter, True, state): stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is not None: return stich_card return self.get_tossable_card(available_cards, card_counter, state) elif current_position == 3: if self.want_stich(cards_by_suit, card_counter, False, state): stich_card = self.get_stich_card(cards_by_suit, card_counter, state) if stich_card is not None: return stich_card return self.get_tossable_card(available_cards, card_counter, state) return None
def get_tossable_card(self, available_cards, card_counter, state): cards_by_suit = split_cards_by_suit(available_cards) eligible = self.available_suits(available_cards) round_color = None if len(state['table']) != 0: round_color = from_string_to_card(state['table'][0]['card']).suit if len(state['table']) > 0 and self.have_to_serve( eligible, round_color) and ( round_color != self.suit or not self.has_only_jack_of_trumpf(available_cards)): weak_cards = self.sort_by_rank( [x[1] for x in cards_by_suit if x[0] == round_color][0]) beatable = card_counter.has_cards_likelihood( card_counter.opponent_1_id, self.cards_beating_current_stich(card_counter.unknown_cards(), card_counter, state), state) != 0 if card_counter.round_leader( state) == card_counter.partner_id and (len( state['table']) == 3 or not beatable): for card in weak_cards: if card.value == 10: return card return weak_cards[len(weak_cards) - 1] else: suit_to_toss = self.get_suit_to_toss(available_cards, card_counter, state) weak_suit = None if suit_to_toss is not None: weak_suit = [ x[1] for x in cards_by_suit if x[0] == suit_to_toss ] else: unknown_by_suit = split_cards_by_suit( card_counter.unknown_cards()) count = 10 for suit, suit_cards in unknown_by_suit: if len(suit_cards) < count: if len([x[1] for x in cards_by_suit if x[0] == suit]) == 0: continue count = len(suit_cards) weak_suit = [ x[1] for x in cards_by_suit if x[0] == suit ] weak_cards = self.sort_by_rank(weak_suit[0]) if len(weak_cards) == 0: return None beatable = card_counter.has_cards_likelihood( card_counter.opponent_1_id, self.cards_beating_current_stich(card_counter.unknown_cards(), card_counter, state), state) != 0 if card_counter.round_leader( state) == card_counter.partner_id and (len( state['table']) == 3 or not beatable): for card in weak_cards: if card.value == 10: return card return weak_cards[len(weak_cards) - 1] else: return weak_cards[len(weak_cards) - 1]
def test_from_string_not_card(card): rose_7 = Card(suit=Suit.ROSE, value=7) assert card != from_string_to_card(str(rose_7))
def test_from_string_to_card(card, card_string): assert card == from_string_to_card(card_string)