示例#1
0
    def play_card(self, game, other_info={}, simulation_time_limit=1):
        for player_idx, suits in other_info.get("lacking_info", {}).items():
            for suit in suits:
                game.lacking_cards[player_idx][suit] = True

            self.say("Player-{} may lack of {} suit({}, {})", player_idx, suit,
                     game.lacking_cards[player_idx], other_info)

        self.say("Player-{}, the information of lacking_card is {}", \
            self.position, [(player_idx, k) for player_idx, info in enumerate(game.lacking_cards) for k, v in info.items() if v])

        hand_cards = [[] if player_idx != self.position else
                      game._player_hands[player_idx]
                      for player_idx in range(4)]

        remaining_cards = Deck().cards
        for card in self.seen_cards + hand_cards[self.position]:
            remaining_cards.remove(card)

        taken_cards = []
        for player_idx, cards in enumerate(game._cards_taken):
            taken_cards.append(card_to_bitmask(cards))

        init_trick = [[None, game.trick]]

        void_info = {}
        for player_idx, info in enumerate(game.lacking_cards):
            if player_idx != self.position:
                void_info[player_idx] = info

        must_have = self.transfer_cards

        selection_func = expert_choose
        self.say("proactive_mode: {}, selection_func={}, num_of_cpu={}",
                 self.proactive_mode, selection_func, self.num_of_cpu)

        played_card = run_one_step(
            game.trick_nr + 1, self.position, self.num_hand_cards,
            copy.deepcopy(init_trick), hand_cards, game.is_heart_broken,
            [2 if player.expose else 1
             for player in game.players], remaining_cards, taken_cards, None,
            selection_func, must_have, void_info)

        self.say("pick {} card", played_card)

        return played_card
class Round:
    def __init__(self, player1, player2, player3, player4):
        self.cpu1 = player1
        self.cpu2 = player2
        self.cpu3 = player3
        self.cpu4 = player4

        self.deck = Deck()
        self.deck.shuffle()

        self.games = BIDDINGS
        self.game_to_be_played = 'Pass'

        self.cpu1.coplayer = self.cpu3
        self.cpu2.coplayer = self.cpu4
        self.cpu3.coplayer = self.cpu1
        self.cpu4.coplayer = self.cpu2

        self.team1 = p.Team(self.cpu1, self.cpu3)
        self.team2 = p.Team(self.cpu2, self.cpu4)

        self.single_hand = [self.cpu1, self.cpu2, self.cpu3, self.cpu4]

    def valid_games(self, called):
        if called == 'Pass' or called not in self.games:
            pass
        else:
            i = self.games.index(called)
            self.games = self.games[:i]

    def set_pregame(self):
        self.cpu1.add_cards(self.deck[0:5])
        self.cpu2.add_cards(self.deck[5:10])
        self.cpu3.add_cards(self.deck[10:15])
        self.cpu4.add_cards(self.deck[15:20])
        self.deck.remove(self.deck[0:20])

    def pregame(self):
        self.set_pregame()

        c1 = self.cpu1.pregame(self.games)
        c2 = self.cpu2.pregame(self.games)
        c3 = self.cpu3.pregame(self.games)
        c4 = self.cpu4.pregame(self.games)

        if all([c == 'Pass' for c in [c1, c2, c3, c4]]):
            self.game_to_be_played = 'Pass'

        else:
            BREAKER = -1
            while True:
                c1 = self.cpu1.pregame(self.games)
                self.valid_games(c1)
                if c1 == 'Pass':
                    BREAKER += 1
                else:
                    BREAKER = 0
                if BREAKER == 3:
                    self.game_to_be_played = c2
                    break

                c2 = self.cpu2.pregame(self.games)
                self.valid_games(c2)
                if c2 == 'Pass':
                    BREAKER += 1
                else:
                    BREAKER = 0
                if BREAKER == 3:
                    self.game_to_be_played = c3
                    break
                c3 = self.cpu3.pregame(self.games)
                self.valid_games(c3)
                if c3 == 'Pass':
                    BREAKER += 1
                else:
                    BREAKER = 0
                if BREAKER == 3:
                    self.game_to_be_played = c4
                    break
                c4 = self.cpu4.pregame(self.games)
                self.valid_games(c4)
                if c4 == 'Pass':
                    BREAKER += 1
                else:
                    BREAKER = 0
                if BREAKER == 3:
                    self.game_to_be_played = c1
                    break

    def set_rest_of_cards(self):
        self.cpu1.add_cards(self.deck[0:3])
        self.cpu2.add_cards(self.deck[3:6])
        self.cpu3.add_cards(self.deck[6:9])
        self.cpu4.add_cards(self.deck[9:12])
        self.deck.remove(self.deck[0:12])

    def reorder(self, index):
        self.single_hand = self.single_hand[index:] + self.single_hand[:index]

    def take_cards(self):
        curr_type = p.ALL_GIVEN_CARDS_ON_TABLE[0].type
        if self.game_to_be_played == 'All Trumps':
            arr = []
            for c in p.ALL_GIVEN_CARDS_ON_TABLE[1:]:
                if c.type == curr_type:
                    arr.append(c)
            if len(arr) == 0:
                return 0
            else:
                res = [all_trumps_dic[c.value] for c in arr]
                max_value = max(res)
                if max_value < all_trumps_dic[p.ALL_GIVEN_CARDS_ON_TABLE[0].value]:
                    return 0
                else:
                    for i in range(len(arr)):
                        if all_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])

        elif self.game_to_be_played == 'No Trumps':
            arr = []
            for c in p.ALL_GIVEN_CARDS_ON_TABLE[1:]:
                if c.type == curr_type:
                    arr.append(c)
            if len(arr) == 0:
                return 0
            else:
                res = [no_trumps_dic[c.value] for c in arr]
                max_value = max(res)
                if max_value < no_trumps_dic[p.ALL_GIVEN_CARDS_ON_TABLE[0].value]:
                    return 0
                else:
                    for i in range(len(arr)):
                        if no_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])
        else:
            arr = []
            curr_type = self.game_to_be_played
            if p.ALL_GIVEN_CARDS_ON_TABLE[0].type == curr_type:
                for card in p.ALL_GIVEN_CARDS_ON_TABLE[1:]:
                    if card.type == curr_type and all_trumps_dic[card.value] > all_trumps_dic[p.ALL_GIVEN_CARDS_ON_TABLE[0].value]:
                        arr.append(card)
                if len(arr) == 0:
                    return 0
                else:
                    result = [all_trumps_dic[c.value] for c in arr]
                    max_value = max(result)
                    for i in range(len(arr)):
                        if all_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])
            elif p.ALL_GIVEN_CARDS_ON_TABLE[0].type != curr_type:
                for card in p.ALL_GIVEN_CARDS_ON_TABLE[1:]:
                    if card.type == curr_type:
                        arr.append(card)
                if len(arr) != 0:
                    result = [all_trumps_dic[c.value] for c in arr]
                    max_value = max(result)
                    for i in range(len(arr)):
                        if all_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])
                else:
                    result = [no_trumps_dic[c.value] for c in p.ALL_GIVEN_CARDS_ON_TABLE]
                    max_value = max(result)
                    for i in range(len(arr)):
                        if no_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])




    def game_on(self):
        self.pregame()
        print(self.game_to_be_played)
        self.set_rest_of_cards()

        print([str(x) for x in self.cpu1.cards])
        print([str(x) for x in self.cpu2.cards])
        print([str(x) for x in self.cpu3.cards])
        print([str(x) for x in self.cpu4.cards])

        cur_res1 = 0
        cur_res2 = 0
        while len(p.ALL_GIVEN_CARDS) < 32:
            if len(p.ALL_GIVEN_CARDS_ON_TABLE) == 0:
                if self.game_to_be_played == 'All Trumps':
                    print(self.single_hand[0].name)
                    self.single_hand[0].throw_card(
                        all_trumps_logic(self.single_hand[0], self.single_hand[2]))
                    print(self.single_hand[1].name)
                    self.single_hand[1].throw_card(
                        all_trumps_logic(self.single_hand[1], self.single_hand[3]))
                    print(self.single_hand[2].name)
                    self.single_hand[2].throw_card(
                        all_trumps_logic(self.single_hand[2], self.single_hand[0]))
                    print(self.single_hand[3].name)
                    self.single_hand[3].throw_card(
                        all_trumps_logic(self.single_hand[3], self.single_hand[1]))
                    print("\n")

                elif self.game_to_be_played == 'No Trumps':
                    print(self.single_hand[0].name)
                    self.single_hand[0].throw_card(
                        no_trumps_logic(self.single_hand[0], self.single_hand[2]))
                    print(self.single_hand[1].name)
                    self.single_hand[1].throw_card(
                        no_trumps_logic(self.single_hand[1], self.single_hand[3]))
                    print(self.single_hand[2].name)
                    self.single_hand[2].throw_card(
                        no_trumps_logic(self.single_hand[2], self.single_hand[0]))
                    print(self.single_hand[3].name)
                    self.single_hand[3].throw_card(
                        no_trumps_logic(self.single_hand[3], self.single_hand[1]))
                    print("\n")

                elif self.game_to_be_played in CARD_TYPES:
                    self.single_hand[0].throw_card(
                        game_type_logic(self.game_to_be_played, self.single_hand[0], self.single_hand[2]))
                    print(game_type_logic(self.game_to_be_played, self.single_hand[0], self.single_hand[2]))
                    self.single_hand[1].throw_card(
                        game_type_logic(self.game_to_be_played, self.single_hand[1], self.single_hand[3]))
                    print(game_type_logic(self.game_to_be_played, self.single_hand[1], self.single_hand[3]))
                    self.single_hand[2].throw_card(
                        game_type_logic(self.game_to_be_played, self.single_hand[2], self.single_hand[0]))
                    print('---------------------')
                    print(game_type_logic(self.game_to_be_played, self.single_hand[2], self.single_hand[0]))
                    self.single_hand[3].throw_card(
                        game_type_logic(self.game_to_be_played, self.single_hand[3], self.single_hand[1]))
                    print(game_type_logic(self.game_to_be_played, self.single_hand[3], self.single_hand[1]))

                else:
                    break

            winner = self.take_cards()
            if winner == 0 or winner == 2:
                self.team1.take_hand(p.ALL_GIVEN_CARDS_ON_TABLE)
                self.reorder(winner)
                cur_res1 += self.team1.cards_to_points(self.game_to_be_played)

                del p.ALL_GIVEN_CARDS_ON_TABLE[:]
            else:
                self.team2.take_hand(p.ALL_GIVEN_CARDS_ON_TABLE)
                self.reorder(winner)
                cur_res2 += self.team2.cards_to_points(self.game_to_be_played)

                del p.ALL_GIVEN_CARDS_ON_TABLE[:]
            sleep(2)
    def play_card(self,
                  game,
                  other_info={},
                  simulation_time_limit=TIMEOUT_SECOND):
        stime = time.time()

        game.are_hearts_broken()

        for player_idx, suits in other_info.get("lacking_info", {}).items():
            for suit in suits:
                game.lacking_cards[player_idx][suit] = True

            self.say("Player-{} may lack of {} suit({}, {})", player_idx, suit,
                     game.lacking_cards[player_idx], other_info)

        self.say("Player-{}, the information of lacking_card is {}",
                 self.position,
                 [(player_idx, k)
                  for player_idx, info in enumerate(game.lacking_cards)
                  for k, v in info.items() if v])

        hand_cards = [[] if player_idx != self.position else
                      game._player_hands[player_idx]
                      for player_idx in range(4)]

        remaining_cards = Deck().cards
        for card in self.seen_cards + hand_cards[self.position]:
            remaining_cards.remove(card)

        taken_cards = []
        for player_idx, cards in enumerate(game._cards_taken):
            taken_cards.append(card_to_bitmask(cards))

        init_trick = [[None, game.trick[:]]]

        void_info = {}
        for player_idx, info in enumerate(game.lacking_cards):
            if player_idx != self.position:
                void_info[player_idx] = info

        must_have = self.transfer_cards

        played_card = None

        selection_func = [expert_choose, greedy_choose]
        self.say("proactive_mode: {}, selection_func={}, num_of_cpu={}, is_heart_broken={}, expose_heart_ace={}", \
            self.proactive_mode, selection_func, self.num_of_cpu, game.is_heart_broken, game.expose_heart_ace)

        row = run_simulation(1, game.trick_nr + 1, self.position,
                             self.num_hand_cards, init_trick, hand_cards,
                             game.is_heart_broken, game.expose_heart_ace,
                             remaining_cards, taken_cards, played_card,
                             selection_func, must_have, void_info, None,
                             TIMEOUT_SECOND)

        results = defaultdict(list)
        #for row in partial_results:
        for card, info in row.items():
            results[card].extend(info)

        #pool.close()

        min_score = sys.maxsize
        for card, info in results.items():
            total_size, total_score, total_num = 0, 0, 0

            for score, self_shoot_the_moon in info:
                total_score += score
                total_num += 1 if self_shoot_the_moon else 0
                total_size += 1

            mean_score = total_score / len(info)

            if mean_score < min_score:
                played_card = card
                min_score = mean_score

            ma, mi = -sys.maxsize, sys.maxsize
            for score, _ in info:
                if score > ma:
                    ma = score
                if score < mi:
                    mi = score

            self.say("simulate {} card with {:4d} times, and get {:.3f} score ({:.4f} ~ {:.4f}), num_moon={}, {:.2f}%", \
                card, total_size, mean_score, ma, mi, total_num, 100.0*total_num/total_size)

        self.say("pick {} card, cost {:.8} seconds", played_card,
                 time.time() - stime)

        return played_card