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 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_with_hand_cards(self, state, hand_cards): """ Returns the cards on the hand of the player which he/she is allowed to play in the current state according to the rules :param hand_cards: :param state: :return: """ table_cards = [ from_string_to_card(entry['card']) for entry in state['table'] ] trumpf = Trumpf[state['trumpf']] return allowed_cards(hand_cards=hand_cards, table_cards=table_cards, trumpf=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 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 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 current_color_cards = [ x[1] for x in cards_by_suit if x[0] == current_stich_color ][0] 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 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)
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 self.have_to_serve(eligible, round_color): 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 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