def check_for_valid_plays(self, card, leading): """ Check if the card played is valid :param card: int :param leading: bool :return: """ if not self.check_card_in(card): return False card_suit = cards.get_card_suit(card) if leading: if not self._table_status['trump broken'] and \ card_suit == self._table_status['trump suit']: if any([ not cards.get_card_suit(crd) == self._table_status['trump suit'] for crd in self.get_deck_values() ]): return False else: leading_card_suit = self._table_status['played cards'][ self._table_status["leading player"]].suit() if not card_suit == leading_card_suit and \ any([cards.get_card_suit(crd) == leading_card_suit for crd in self.get_deck_values()]): return False return True
def estimate_wins(self): player_cards = self.player.get_deck_values() card_suits = [cards.get_card_suit(crd) for crd in player_cards] card_nums = [cards.get_card_number(crd) for crd in player_cards] n_cards = [] for i in range(4): 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 - 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 + 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] * 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) * self.weigh2 return bids
def update_memory(self): played_cards = [ card.value for card in self.table_status["played cards"] ] for val in played_cards: suit = cards.get_card_suit(val) num = cards.get_card_number(val) self.unplayed_cards[suit - 1].remove(num)
def get_valid_plays(self, leading): all_plays = self.player.get_deck_values() possible_plays = None if leading: if not self.table_status['trump broken']: possible_plays = [ card for card in all_plays if not cards.get_card_suit(card) == self.table_status['trump suit'] ] else: leading_suit = self.table_status['played cards'][ self.table_status["leading player"]].suit() possible_plays = [ card for card in all_plays if cards.get_card_suit(card) == leading_suit ] if not possible_plays: return all_plays return possible_plays
def call_partner(self): """ :return: int - the card value """ player_cards = self.player.get_deck_values() card_suits = [cards.get_card_suit(crd) for crd in player_cards] card_nums = [cards.get_card_number(crd) for crd in player_cards] trump_suit = self.table_status["bid"] % 10 trump_nums = [ num for suit, num in zip(card_suits, card_nums) if suit == trump_suit ] if 14 not in trump_nums: return trump_suit * 100 + 14 if 13 not in trump_nums: return trump_suit * 100 + 13 if 12 not in trump_nums: return trump_suit * 100 + 12 suit_values = [] for i in range(4): 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 val == min_val ] if len(weakest_suit) > 1: weakest_suit = random.choice(weakest_suit) else: weakest_suit = weakest_suit[0] 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(all_nums)
def make_a_play(self, sub_state): """ :param sub_state: :return: int - card value """ # TODO: Recall last round and update memory # Get valid plays if sub_state == 0: card_values = self.get_valid_plays(True) else: card_values = self.get_valid_plays(False) n_cards = len(card_values) card_viability = [1] * n_cards card_nums = [cards.get_card_number(play) for play in card_values] card_suits = [cards.get_card_suit(play) for play in card_values] high_cards = [ max(card_set) + (i + 1) * 100 if card_set else 0 for i, card_set in enumerate(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 * self.low_suit_factor # Leading-specific viability if sub_state == 0: for i in range(n_cards): card_viability[i] += any( [card_values[i] == card for card in high_cards]) * self.high_card_factor else: # Get the played cards 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 ] leading_card = self.table_status["played cards"][ self.table_status["leading player"]] leading_suit = leading_card.suit() # Find the highest number played, max_played_num = max([ num for num, suit in zip(played_nums, played_suits) if suit == leading_suit ]) 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 = 0 for i in range(n_cards): # Favour highest cards card_viability[i] += (card_suits[i] == leading_suit and card_values[i] == high_cards[leading_suit-1]) \ * self.high_card_factor # Favour low cards if trumped if max_trump_played > 0: card_viability[i] -= card_nums[i] / 7 * ( card_suits[i] != self.table_status['trump suit']) # Favour low cards if cannot higher if max(card_nums) < max_played_num: card_viability[i] += 1 / card_nums[i] # Favour low trump cards which wins if trumping is possible if card_suits[i] == self.table_status['trump suit'] and\ card_nums[i] > max_trump_played: card_viability[ i] += 1 / card_nums[i] * self.trumping_factor if self.table_status["partner reveal"]: # Not implemented as original pass best_viability = max(card_viability) best_cards = [ play for viability, play in zip(card_viability, card_values) if viability == best_viability ] return random.choice(best_cards)