diff --git a/ai_comp/ai.py b/ai_comp/ai.py index 56359c1..14a9e16 100644 --- a/ai_comp/ai.py +++ b/ai_comp/ai.py @@ -175,7 +175,7 @@ class VivianAI(RandomAI): suit_values.append(sum([num for suit, num in zip(card_suits, card_nums) if suit == i+1])) min_val = min(suit_values) - weakest_suit = [i + 1 for i, val in enumerate(suit_values) if suit_values == min_val] + weakest_suit = [i + 1 for i, val in enumerate(suit_values) if val == min_val] if len(weakest_suit) > 1: weakest_suit = random.choice(weakest_suit) else: @@ -184,9 +184,9 @@ class VivianAI(RandomAI): all_nums = [i+2 for i in range(13)] weak_nums = [num for suit, num in zip(card_suits, card_nums) if suit == weakest_suit] [all_nums.remove(num) for num in weak_nums] - return weakest_suit*100 + max(weak_nums) + return weakest_suit*100 + max(all_nums) - def make_an_play(self, sub_state): + def make_a_play(self, sub_state): """ :param sub_state: @@ -200,7 +200,54 @@ class VivianAI(RandomAI): else: valid_plays = self.get_valid_plays(False) - card_viability = [0] * len(valid_plays) + n_cards = len(valid_plays) + card_viability = [1] * n_cards + card_nums = [cards.get_card_number(play) for play in valid_plays] + card_suits = [cards.get_card_suit(play) for play in valid_plays] + high_cards = [max(card_set) if card_set else 0 for card_set in self.unplayed_cards] + + suit_counts = [0] * 4 + for i in range(4): + suit_counts[i] = card_suits.count(i+1) + + non_empty_suits = [i+1 for i, count in enumerate(suit_counts) if count] + suit_counts = [count for count in suit_counts if count] + + min_suit_count = min(suit_counts) + low_suits = [suit for suit, counts in zip(non_empty_suits, suit_counts) if counts == min_suit_count] + + for i in range(n_cards): + card_viability[i] += any([card_suits[i] == s for s in low_suits]) / min_suit_count + + # Leading-specific viability + if sub_state == 0: + for i in range(n_cards): + card_viability[i] += any([valid_plays[i] == card for card in high_cards]) * 1.2 + else: + played_cards = [card.value if card else None for card in self.table_status["played cards"]] + played_nums = [cards.get_card_number(card) if card else 0 for card in played_cards] + played_suits = [cards.get_card_suit(card) if card else 0 for card in played_cards] + + trumped = any([suit == self.table_status['trump suit'] for suit in played_suits]) + max_played_num = max(played_nums) + max_trump_played = [num for suit, num in zip(played_suits, played_nums) + if suit == self.table_status['trump suit']] + if max_trump_played: + max_trump_played = max(max_trump_played) + else: + max_trump_played = 1 + + for i in range(n_cards): + if trumped and card_suits[i] != self.table_status['trump suit']: + card_viability[i] *= card_nums[i]/7 + card_viability[i] += (card_nums[i] < max_played_num) / card_nums[i] + if card_suits[i] == self.table_status['trump suit'] and\ + card_nums[i]>max_trump_played : + card_viability[i] *= 2 / card_nums[i] + + best_viability = max(card_viability) + best_cards = [play for viability, play in zip(card_viability, valid_plays) if viability == best_viability] + return random.choice(best_cards) def update_memory(self): played_cards = [card.value for card in self.table_status["played cards"]] diff --git a/main.py b/main.py index b018873..ca883dd 100644 --- a/main.py +++ b/main.py @@ -101,6 +101,9 @@ if __name__ == '__main__': with open('last_game_rng.rng', 'wb') as f: pickle.dump(rng_state, f) + #with open('seeds/Vbot_good_hand2.rng', 'rb') as f: + # rng_state = pickle.load(f) + #random.setstate(rng_state) main_view = GameScreen(900, 600, clear_colour=(255, 0, 0), autoplay=True, view_all_cards=VIEW_ALL_CARDS) diff --git a/seeds/Vbot_good_hand.rng b/seeds/Vbot_good_hand.rng new file mode 100644 index 0000000..ad47a7e Binary files /dev/null and b/seeds/Vbot_good_hand.rng differ diff --git a/seeds/Vbot_good_hand2.rng b/seeds/Vbot_good_hand2.rng new file mode 100644 index 0000000..c1c5fef Binary files /dev/null and b/seeds/Vbot_good_hand2.rng differ diff --git a/table.py b/table.py index 1c88b01..c88ec6c 100644 --- a/table.py +++ b/table.py @@ -599,16 +599,16 @@ class Table: card_nums = [card.number() for card in self.table_status["played cards"]] follow_suits = [suit == leading_card.suit() for suit in card_suits] trumps = [suit == self.table_status['trump suit'] for suit in card_suits] - trump_played = any(trumps) + #trump_played = any(trumps) # Break trump if the trump suit is played - if not self.table_status['trump broken']: - if trump_played: - self.table_status['trump broken'] = True - self.write_message("Trump Broken!", delay_time=1) + #if not self.table_status['trump broken']: + # if trump_played: + # self.table_status['trump broken'] = True + # self.write_message("Trump Broken!", delay_time=1) # Determine which players to check for winner, and determine winner - valid_nums = [card_nums[i] * ((follow_suits[i] and not trump_played) or trumps[i]) + valid_nums = [card_nums[i] * ((follow_suits[i] and not self.table_status['trump broken']) or trumps[i]) for i in range(NUM_OF_PLAYERS)] winning_player = valid_nums.index(max(valid_nums)) self.write_message("Player {0:d} wins!\n".format(winning_player), delay_time=1) @@ -636,6 +636,14 @@ class Table: self.update_table.emit() return + # Break trump if the trump suit is played + if not self.table_status['trump broken']: + trump_played = card.suit() == self.table_status['trump suit'] + if trump_played: + self.table_status['trump broken'] = True + self.write_message("Trump Broken!", delay_time=1.5) + + if not self.table_status['partner reveal']: if card.value == self.table_status['partner']: self.table_status['partner reveal'] = True