def legal_cards(self, played_cards): if not played_cards: return self.cards #first to play, everything is legal played_cards = Cards(played_cards) color = played_cards[0].color played_trumps = played_cards.filter_color(self.trump) highest = highest_card(played_cards) if highest.owner == None: raise KeyError("Played card doesn't have owner") winning = (highest.owner == self.partner) cards = self.cards.filter_color(color) if cards: #we can confess colour if color != self.trump: return cards #no trumps so no restrictions #must not undertrump higher = [t for t in cards if t>highest] if higher: return higher # We must overtrump return cards trumps = self.cards.get_trumps() if not trumps: return self.cards # Don't have any trumps so everything is legal if not played_trumps and not winning: return trumps # We aren't winning and we have trumps, so we must play one of those higher = [t for t in trumps if t>highest] if higher and not winning: return higher # We must overtrump c = self.cards.filter(lambda c: c.color!=self.trump) #Any card except trumps c.extend(higher) if c: return c return self.cards #we can't overtrump, but we only have trumps so we need to play them.
def will_win_this_round(self, played_cards): cards_played = played_cards """Returns whether we are absolutely certain to win this round, regardless of what we will play.""" if not cards_played: return False h = highest_card(cards_played) if h.owner != self.partner: return False if len(cards_played) == 3: return True #Only us left to play color = cards_played[0].color is_trumped = h.color == self.trump notyetplayed = list(range(4)) notyetplayed.remove(self.index) for c in cards_played: notyetplayed.remove(c.owner) # Since we are assuming that our partner is currently winning # And we are not last to play, there is exactly one other player that # needs to play a card p = notyetplayed[0] d = self.index_to_deck(p) # Possible cards in hand of the player if is_trumped: #winning card is trump if d.higher_then(h): return False # Person could overtrump else: return True if d.filter_color(self.trump): return False # Person could trump in if d.higher_then(h): return False return True
def play_card(self, rnum, played_cards): played_cards = Cards(played_cards) self.round = rnum legal = self.legal_cards(played_cards) if len(legal) == 1: self.pp("Only one legal card to play") return self.play_this_card(legal[0]) trumps = self.cards.get_trumps().sorted() non_trumps = self.cards.filter(self.is_not_trump).sorted() if not played_cards: self.pp("We are playing this round") if self.is_playing: self.pp("We are playing this game") high_trumps = trumps.filter(self.is_high) filt = Cards([c for c in high_trumps if self.glory_possibility(c)]) if filt: self.pp("We have trumps with a chance of glory") if KING in filt.values(): #king is high and there is glory possibility return self.play_this_card(filt.has(KING)) if NINE in filt.values(): return self.play_this_card(filt.has(NINE)) return self.play_this_card(filt.sorted()[0]) n = len(self.unknown_cards[0].get_trumps()) m = len(self.unknown_cards[2].get_trumps()) if n + m != 0: self.pp("The other team might still have trumps") if high_trumps: return self.play_this_card(high_trumps[0]) if len(trumps) > 1: filt = [c for c in trumps if not self.glory_possibility(c) and c.value!=NINE] if filt: return self.play_this_card(sorted(filt)[0]) return self.play_this_card(sorted(trumps)[0]) return self.play_this_card(self.pick_non_trump()) return self.play_this_card(self.pick_non_trump()) #We are not playing this game return self.play_this_card(self.pick_non_trump()) else: #someone else already played highest = highest_card(played_cards) winning = (highest.owner == self.partner) color = played_cards[0].color if color != self.trump and highest.value == TEN and played_cards[0].value == TEN: #a person came out with a 10, so he has the ace self.player_has_card(played_cards[0].owner, Card(ACE, color)) if color == self.trump and highest.value == NINE and played_cards[0].value == NINE: self.player_has_card(played_cards[0].owner, Card(JACK, color)) possibilities = self.cards.filter_color(color) played_trumps = played_cards.get_trumps() if len(possibilities) == 1: #only 1 possible card to play self.pp("Only one possible card to play") return self.play_this_card(possibilities[0]) if len(possibilities) == 0: self.pp("Can't confess color") if trumps: if winning: self.pp("Our mate is winning, don't trump in") if non_trumps: if self.is_high(highest): return self.play_this_card(self.sign_mate()) else: return self.play_this_card(self.trow_away_card()) else: return self.play_this_card(trumps[-1]) if len(trumps) == 1: self.pp("We have exactly one trump") c = trumps[0] if not played_trumps: self.pp("We have to trump in") return self.play_this_card(c) else: h = highest_card(played_trumps) if c>h: self.pp("We can defeat the highest played trump, so do it") return self.play_this_card(c) else: if non_trumps: self.pp("We can't over trump, so play another card") return self.play_this_card(self.trow_away_card()) else: return self.play_this_card(c) else: self.pp("We have more then one trump") if played_trumps: h = played_trumps.sorted()[-1] filt = trumps.higher_then(h) if filt: self.pp("We can over trump, do it with the lowest one") return self.play_this_card(filt[0]) else: self.pp("We can't over trump") poss = self.cards.filter(self.is_not_trump) if poss: return self.play_this_card(self.trow_away_card()) else: return self.play_this_card(trumps[0]) else: return self.play_this_card(trumps[0]) # we play our lowest trump else: self.pp("We have no trump and we can't confess color") if winning and self.is_high(highest): return self.play_this_card(self.sign_mate()) else: return self.play_this_card(self.trow_away_card()) else: self.pp("We have more than 1 card of the right color") if color == self.trump: filt = trumps.higher_then(highest) if filt: self.pp("We have to overtrump") if len(filt) == 1: return self.play_this_card(filt[0]) high_cards = filt.filter(self.is_high) if high_cards: c, glory = self.maxmin_glory(played_cards, deck=high_cards) return self.play_this_card(c) c, glory = self.maxmin_glory(played_cards, deck=filt, maximize=False) return self.play_this_card(c) if winning and self.is_high(highest): c, glory = self.maxmin_glory(played_cards) return self.play_this_card(c) c, glory = self.maxmin_glory(played_cards, deck=[a for a in trumps if a.value!=NINE], maximize=False) return self.play_this_card(c) if len(played_cards) == 3: #we are the last one to play a card if winning: self.pp("We are currently winning the round, and are last in line") c, glory = self.maxmin_glory(played_cards) if glory: self.pp("We can make glory! Do it") return self.play_this_card(c) self.remove_known_cards(played_cards) possibilities.sort() c = possibilities[-1] if c.value == TEN and highest.value != ACE: return self.play_this_card(c) if self.is_high(c): #we have the highest in hand return self.play_this_card(possibilities[-2]) #we play our highest card return self.play_this_card(c) else: self.pp("we are not winning this round, try to still win") filt = Cards([c for c in possibilities if c>highest]) if filt: self.pp("we can win with a card.") c, glory = self.maxmin_glory(played_cards, deck=filt) if glory: self.pp("And we can make glory! do it") return self.play_this_card(c) return self.play_this_card(filt.sorted()[0]) else: self.pp("we can't win, play a low card") c, glory = self.maxmin_glory(played_cards, maximize = False) return self.play_this_card(c) else: #we are not the last one to play in this round if winning: if self.is_high(highest) or (highest.color == self.trump and color != self.trump): self.pp("We are currently winning with the highest card") c, glory = self.maxmin_glory(played_cards) if glory: self.pp("There is a possibility for glory, try it") return self.play_this_card(c) poss = possibilities.sorted() if self.is_high(poss[-1]): return self.play_this_card(poss[-2]) return self.play_this_card(poss[-1]) filt = Cards([c for c in possibilities if c>highest]).sorted() if filt and self.is_high(filt[-1]): f = [c for c in filt if self.is_high(c)] c, glory = self.maxmin_glory(played_cards, deck=f) if glory: self.pp("Possibility for glory with high card, do it") return self.play_this_card(c) return self.play_this_card(f[-1]) self.pp("We are currently winning, but there is a higher card in play, duck") c, glory = self.maxmin_glory(played_cards, maximize=False) return self.play_this_card(c) filt = Cards([c for c in possibilities if self.is_high(c)]).sorted() if filt and filt[0] > highest: #this last check is because it might be trumped in self.pp("We have a high card, maximize glory and points!") c, glory = self.maxmin_glory(played_cards, deck=filt) if glory: return self.play_this_card(c) return self.play_this_card(filt[-1]) else: #TODO: Do a check for not wasting a TEN or ACE self.pp("we can't win, play a low card") c, glory = self.maxmin_glory(played_cards, maximize=False) return self.play_this_card(c) raise NotImplementedError("Ahhhh, shouldn't get here!")
def show_trick(self,cards, round): '''Here we analyze the played cards, and try to conclude some information on the hands of the players''' color = cards[0].color p = cards[0].owner glory = glory_calculation(cards,self.trump) def remove_all_in_color(index, color, exceptions=[]): if index == self.index: return d = self.index_to_deck(index) for cc in [a for a in d if (a.color == color and a.value not in exceptions)]: d.remove(cc) if p != self.index: #we did not start this round d = self.index_to_deck(p) if round == 1: if color != self.trump: #starting player didn't play a trump if Card(JACK, self.trump) in d: d.remove(Card(JACK, self.trump)) else: if cards[0].value == NINE: if Card(JACK, self.trump) in d: self.player_has_card(p, Card(JACK, self.trump)) if cards[0].value == KING: if Card(QUEEN, self.trump) in d: self.player_has_card(p, Card(QUEEN, self.trump)) #if not self.player_is_playing(p): #player starting didn't play if cards[0].value == TEN and color != self.trump: if Card(ACE, color) in d: self.player_has_card(p, Card(ACE, color)) if color == self.trump and cards[0].value == JACK: for i in [1,3]: if cards[i] == Card(NINE, self.trump) and glory < 25: remove_all_in_color(cards[i].owner, self.trump) if cards[i] == Card(QUEEN, self.trump): if glory: remove_all_in_color(cards[i].owner, self.trump, [NINE]) if p == self.index and highest_card(cards).owner == self.index: #we are playing and have won m = cards[2] # the card of your mate if m.color != color and m.color != self.trump: #mate didn't confess color and didn't trump if m.value in (SEVEN, EIGHT, NINE, ACE): #mate is signing if m.color not in self.mate_prefered_colors: self.mate_prefered_colors.append(m.color) self.pp("Mate signed card color") elif m.value in (QUEEN, KING, TEN): #mate is de-signing the color if m.color not in self.mate_prefered_colors: #if it was already signed, ignore this if len(self.mate_prefered_colors) == 0: self.mate_prefered_colors = list(range(4)) self.mate_prefered_colors.remove(self.trump) self.mate_prefered_colors.remove(m.color) if color == self.trump: #trump asked highest = cards[0] for (i,c) in enumerate(cards[1:]): if c.color == self.trump: if c > highest: highest = c else: #didn't overtrump, remove those possibilities if c.owner == self.index: continue d = self.index_to_deck(c.owner) for cc in [a for a in d if (a.color == self.trump and a > c)]: d.remove(cc) else: #couldn't confess color if c.owner == self.index: continue remove_all_in_color(c.owner, self.trump) else: #not a trump asked highest = cards[0] for (i, c) in enumerate(cards[1:]): if c.color == color: if c > highest: highest = c else: #couldn't confess color if c.owner == self.index: continue d = self.index_to_deck(c.owner) for cc in [a for a in d if (a.color == color)]: d.remove(cc) if highest.owner != self.index_to_mate(c.owner): if c.color != self.trump: #he didn't trump in if highest.color != self.trump: for cc in [a for a in d if (a.color == self.trump)]: d.remove(cc) else: for cc in [a for a in d if (a.color == self.trump and a > highest)]: d.remove(cc) highest = highest_card(cards) if highest.owner != cards[3].owner: #last person didn't win the round if highest.owner != cards[1].owner: #his mate also didn't if cards[3].color == color: #he confessed color if glory > 20: #at least 40 glory, it would always have been better to prevent it remove_all_in_color(cards[3].owner, color) if glory == 20 and color != self.trump: #he might have chosen not to play the TEN remove_all_in_color(cards[3].owner, color, [TEN]) if color != self.trump: a = Card(ACE, color) if Card(ACE, color) in self.mystery_cards: #we haven't seen the ACE yet if a not in cards and cards[0].value!=TEN: #it is not played in this round if self.trump not in Cards(cards).colors(): #not trumped in anywhere self.pp("No Ace played in this round. How weird") if cards[0].owner != self.index: d = self.index_to_deck(cards[0].owner) if a in d: d.remove(a) if cards[2].owner != self.index: d = self.index_to_deck(cards[2].owner) if a in d: d.remove(a) if cards[0] == a: #ACE has been played t = Card(TEN, color) if cards[1] == t: remove_all_in_color(cards[1].owner, color) if cards[3] == t: #last person played a TEN values = Cards(cards).filter_color(color).values() if QUEEN in values: if KING in values: remove_all_in_color(cards[3].owner, color, [JACK]) else: remove_all_in_color(cards[3].owner, color, [KING]) elif KING in values: remove_all_in_color(cards[3].owner, color, [QUEEN]) elif SEVEN in values and EIGHT in values: remove_all_in_color(cards[3].owner, color, [NINE]) elif SEVEN in values and NINE in values: remove_all_in_color(cards[3].owner, color, [EIGHT]) else: remove_all_in_color(cards[3].owner, color) self.remove_known_cards(cards)