Implement bidding for Vbot, and testing

master
En Yi 2019-06-14 15:40:00 +01:00
parent c5f20fa281
commit 6958009277
3 changed files with 48 additions and 19 deletions

View File

@ -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

View File

@ -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()

View File

@ -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