示例#1
0
 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)
示例#2
0
    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)
示例#3
0
 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)
示例#4
0
    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))
示例#5
0
    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'])))
示例#6
0
    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
示例#7
0
def test_from_string_not_card(card):
    rose_7 = Card(suit=Suit.ROSE, value=7)
    assert card != from_string_to_card(str(rose_7))
示例#8
0
def test_from_string_to_card(card, card_string):
    assert card == from_string_to_card(card_string)
示例#9
0
    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]
示例#10
0
    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