diff --git a/ai_comp/ai.py b/ai_comp/ai.py index d318641..d4d3d3c 100644 --- a/ai_comp/ai.py +++ b/ai_comp/ai.py @@ -60,6 +60,10 @@ class RandomAI(BaseAI): return False def make_a_bid(self): + """ + + :return: int - the bid + """ if self.player: current_round_bid = self.table_status["bid"] // 10 current_suit_bid = self.table_status["bid"] % 10 @@ -73,6 +77,10 @@ class RandomAI(BaseAI): return self.table_status["bid"]+1 def call_partner(self): + """ + + :return: int - the card value + """ player_cards = self.player.get_deck_values() other_cards = [] for i in range(4): @@ -83,6 +91,11 @@ class RandomAI(BaseAI): return random.choice(other_cards) def make_a_play(self, sub_state): + """ + + :param sub_state: + :return: int - card value + """ if sub_state == 0: valid_plays = self.get_valid_plays(True) else: @@ -99,21 +112,35 @@ class VivianAI(RandomAI): self.weigh1 = 0.15 self.weigh2 = 0.002 + self.bid_weigh = 0.3 + def request_reshuffle(self): return True def make_a_bid(self): - if self.player: - current_round_bid = self.table_status["bid"] // 10 - current_suit_bid = self.table_status["bid"] % 10 - bid_threshold = int(current_round_bid*1.5 + current_suit_bid*0.5) - gen_bid = random.randint(0, bid_threshold) - print(gen_bid) - if gen_bid <= 1: - if current_suit_bid == 5: - return (current_round_bid+1)*10 + 1 - else: - return self.table_status["bid"]+1 + # TODO: execute estimate_wins only once + # Be careful when getting max_bid as it is 0-index but suits are 1-index + est_wins = self.estimate_wins() + max_est = max(est_wins) + max_bid = [math.ceil(est)-3 for est in est_wins] + favourable_suit = [i+1 for i, est in enumerate(est_wins) if est == max_est] + if len(favourable_suit) > 1: + favourable_suit = random.choice(favourable_suit) + else: + favourable_suit = favourable_suit[0] + + bid_num = self.table_status["bid"] // 10 + bid_suit = self.table_status["bid"] % 10 + if bid_suit == favourable_suit: + if bid_num < max_bid[favourable_suit]: + return 10 + self.table_status["bid"] + else: + loss_reward = self.bid_weigh*((8-bid_num)-(max_bid[bid_suit-1]+1)) + max_bid[favourable_suit-1] += int(loss_reward) + next_bid_num = bid_num + 1 * (favourable_suit < bid_suit) + if next_bid_num <= max_bid[favourable_suit-1]: + return next_bid_num*10 + favourable_suit + return 0 def estimate_wins(self): player_cards = self.player.get_deck_values() @@ -122,22 +149,24 @@ class VivianAI(RandomAI): n_cards = [] for i in range(4): - n_cards.append(card_suits.count(i)) + n_cards.append(card_suits.count(i+1)) bids = [0] * 5 trump_points = [num-10 if num >=10 else 0.001 for num in card_nums] - non_trump_points = [self.calc_win_points(num, n_cards[suit]) if num >= 10 else 0.001 + non_trump_points = [self.calc_win_points(num, n_cards[suit-1]) if num > 10 else 0.001 for (num, suit) in zip(card_nums, card_suits)] for trump_call in range(5): for suit in range(4): - valid_cards = [crd_suit == suit for crd_suit in card_suits] + valid_cards = [crd_suit == suit+1 for crd_suit in card_suits] if suit == trump_call: points = sum([pts for valid, pts in zip(valid_cards, trump_points) if valid]) - bids[trump_call] = points*n_cards[suit] + bids[trump_call] += points*n_cards[suit] * self.weigh1 else: points = sum([pts for valid, pts in zip(valid_cards, non_trump_points) if valid]) - bids[trump_call] = points*math.log(n_cards[suit]+1) + bids[trump_call] += points*math.log(n_cards[suit]+1) * self.weigh2 + + return bids def calc_win_points(self, card_num, n_cards): """ @@ -148,7 +177,7 @@ class VivianAI(RandomAI): :return: float score """ - num = min(0, card_num-10) + num = max(0, card_num-10) if not n_cards: return 0 diff --git a/main.py b/main.py index 22cca6a..b018873 100644 --- a/main.py +++ b/main.py @@ -103,6 +103,6 @@ if __name__ == '__main__': main_view = GameScreen(900, 600, clear_colour=(255, 0, 0), - autoplay=AUTOPLAY, view_all_cards=VIEW_ALL_CARDS) + autoplay=True, view_all_cards=VIEW_ALL_CARDS) main_view.run() \ No newline at end of file diff --git a/table.py b/table.py index 5fd12b2..fa38881 100644 --- a/table.py +++ b/table.py @@ -172,7 +172,7 @@ class Table: self.player_stats[i].append(surf) if autoplay: - self.players[0].add_ai(ai.RandomAI(self.table_status)) + self.players[0].add_ai(ai.VivianAI(self.table_status)) # Announcer positioning and surface creation announcer_margins = 5