예제 #1
0
    def _list_best_options(self):
        """
        Returns a list of the highest probability asks you can make, according to self.info
        Ties are broken in this method by the following criteria:
        1. Number of guarenteed cards in half suit
        If player A is guarenteed to have more cards in the half suit than player B, ask them

        This method does not account for the "danger" of asking certain players yet
        """
        best_asks = []
        highest_prob = 0
        most_hs_cards = 0
        for card in card_utils.gen_all_cards():
            for ID in self._get_opponents():
                if self._check_legal_ask(ID, card):
                    if self.info[ID][card] != NO:
                        best_asks = [(ID, card)]
                        highest_prob = self.info[ID][card]
                        most_hs_cards = self.hs_info[ID][
                            card_utils.find_half_suit(card)]
                    elif self.info[ID][card] == highest_prob:
                        if self.hs_info[ID][card_utils.find_half_suit(
                                card)] > most_hs_cards:
                            best_asks = [(ID, card)]
                            most_hs_cards = self.hs_info[ID][
                                card_utils.find_half_suit(card)]
                        elif self.hs_info[ID][card_utils.find_half_suit(
                                card)] == most_hs_cards:
                            best_asks.append((ID, card))
        return best_asks
예제 #2
0
 def check_call_correct(self, call, ID):
     """
     Checks if a call is correct
     :param call: a call list of tuples
     :param ID: ID of player calling
     :return: hs, team, success
     """
     success = True
     for ID, card in call:
         if card not in self.player_cards[ID]:
             success = False
     return [card_utils.find_half_suit(card), ID % 2, success]
예제 #3
0
 def _init_hs_info_start_game(ID, own_cards):
     """
     Returns the half suit info dictionary assuming its the start of a new game
     Uses data from the already intialized info dictionary
     """
     blank_hs = {hs: 0 for hs in card_utils.gen_all_halfsuits()}
     hs_info = {
         player_id: blank_hs.copy()
         for player_id in range(NUM_PLAYERS)
     }
     for card in own_cards:
         hs_info[ID][card_utils.find_half_suit(card)] += 1
     return hs_info
예제 #4
0
    def _check_legal_ask(self, ID_target, card):
        """
        Given a target player and a card to ask, check if the ask is legal
        Conditions for legality:
        1. You must have a card in the same half suit
        2. You must not have that card
        3. The person you ask must be on the opposite team

        ID_target: The ID of the person the self wants to ask
        card: the card that we are checking the legality of
        """
        if ID_target % 2 != self.ID % 2:
            if self.info[self.ID][card] == NO:
                for c in card_utils.find_cards(
                        card_utils.find_half_suit(card)):
                    if self.info[self.ID][c] == YES:
                        return True
        return False
예제 #5
0
    def update_transaction(self, ID_ask, ID_target, card, success):
        """
        Given a transaction, updates the player's info, public info, and half suit info

        :param ID_ask: ID of player asking for the card
        :param ID_target: player being asked
        :param card: card being asked
        :param success: true if card was taken from ID_target
        """
        if success:
            self.num_cards[ID_ask] += 1
            self.num_cards[ID_target] -= 1
            self.info[ID_ask][card] = YES
            self.info[ID_target][card] = NO
            self.public_info[ID_ask][card] = YES
            self.public_info[ID_target][card] = NO
            if self.hs_info[ID_ask][card_utils.find_half_suit(card)] == 0:
                self.hs_info[ID_ask][card_utils.find_half_suit(card)] = 1
            self.hs_info[ID_ask][card_utils.find_half_suit(card)] += 1
            if self.public_hs_info[ID_ask][card_utils.find_half_suit(
                    card)] == 0:
                self.public_hs_info[ID_ask][card_utils.find_half_suit(
                    card)] = 1
            self.public_hs_info[ID_ask][card_utils.find_half_suit(card)] += 1
            if self.hs_info[ID_target][card_utils.find_half_suit(card)] > 0:
                self.hs_info[ID_target][card_utils.find_half_suit(card)] -= 1
            if self.public_hs_info[ID_target][card_utils.find_half_suit(
                    card)] > 0:
                self.public_hs_info[ID_target][card_utils.find_half_suit(
                    card)] -= 1
        else:
            self.info[ID_ask][card] = NO
            self.info[ID_target][card] = NO
            self.public_info[ID_ask][card] = NO
            self.public_info[ID_target][card] = NO
            if self.hs_info[ID_ask][card_utils.find_half_suit(card)] == 0:
                self.hs_info[ID_ask][card_utils.find_half_suit(card)] = 1
            if self.public_hs_info[ID_ask][card_utils.find_half_suit(
                    card)] == 0:
                self.public_hs_info[ID_ask][card_utils.find_half_suit(
                    card)] = 1
        self._update_info(
            card_utils.find_cards(card_utils.find_half_suit(card)))
        self._update_public_info(
            card_utils.find_cards(card_utils.find_half_suit(card)))
예제 #6
0
    def _is_consistent(info_dict,
                       remaining_hs,
                       hs_info,
                       num_cards,
                       check_cards=tuple(card_utils.gen_all_cards())):
        """
        Checks if an info dictionary is consistent. If the info dictionary
        has a contradiction, returns false. Otherwise returns true.

        Info dictionaries must follow these rules:
        1. No two players can have YES for the same card
        2. If the half suit has not been called yet, at least 1 player
        must have at least the possibility of having any card
        in that half suit
        3. If a player has at least X cards in a half suit, they cannot have
        more than HS_SIZE-X cards being NO in that half suit
        4. If a player has X cards in their hand, they cannot have more than
        DECK_SIZE-X cards being NO
        :param info_dict: either a public info dict or player info dict
        :param remaining_hs: the remaining half suits in the game
        :param hs_info: the half suit info
        :param num_cards: number of each players cards
        :param check_cards: cards to check for consistency
        :return: True if consistent, false otherwise
        """
        # Calculate check_hs based on check_cards
        check_hs = set([])
        for c in check_cards:
            hs = card_utils.find_half_suit(c)
            if hs not in check_hs and hs in remaining_hs:
                check_hs.add(hs)
        # Rule 1
        for card in check_cards:
            players_yes = 0
            for ID in range(NUM_PLAYERS):
                if info_dict[ID][card] == YES:
                    players_yes += 1
            if players_yes > 1:
                return False
        # Rule 2
        for hs in check_hs:
            for card in card_utils.find_cards(hs):
                players_no = 0
                for ID in range(NUM_PLAYERS):
                    if info_dict[ID][card] == NO:
                        players_no += 1
                if players_no == NUM_PLAYERS:
                    return False
        # Rule 3
        for hs in check_hs:
            for ID in range(NUM_PLAYERS):
                hs_no_count = 0
                for card in card_utils.find_cards(hs):
                    if info_dict[ID][card] == NO:
                        hs_no_count += 1
                if hs_info[ID][hs] + hs_no_count > HS_SIZE:
                    return False
        # Rule 4
        for ID in range(NUM_PLAYERS):
            no_count = 0
            for card in card_utils.gen_all_cards():
                if info_dict[ID][card] == NO:
                    no_count += 1
            if num_cards[ID] + no_count > DECK_SIZE:
                return False
        return True