def report_play(self, *k, **kw): super(ConsoleAgent, self).report_play(*k, **kw) player = kw['player'] card = kw['card'] self.discarded[card] += 1 target = kw.get('target', None) discard = kw.get('discard', None) if discard: self.discarded[discard] += 1 if target: if not self.observer.players[target].handmaiden: if card == Cards.PRIEST: other_card = kw.get('other_card', None) if other_card: print('%s has card %s' % (self.observer.players[target], Cards.name(other_card))) elif card == Cards.BARON: loser = kw.get('loser', None) if loser is not None: other_card = kw.get('other_card', None) if other_card: print('Winning card was %s' % Cards.name(other_card)) elif card == Cards.PRINCE: new_card = kw.get('new_card', None) if new_card: print('%s draws new card %s' % (self.observer.players[target], Cards.name(new_card))) elif card == Cards.KING: other_card = kw.get('other_card', None) if other_card: print('%s now has card %s' % (self.observer.players[target], Cards.name(other_card)))
def report_play(self, *k, **kw): super(LowballAgent, self).report_play(*k, **kw) card = kw['card'] player = kw['player'] target = kw.get('target', None) if target and not self.observer.players[target].handmaiden: if player == self.player: if card == Cards.PRIEST: Log.print('ai: %s has card %s' % (self.observer.players[target], Cards.name(kw['other_card']))) elif card == Cards.KING: Log.print('ai: %s now has card %s' % (self.name, Cards.name(kw['other_card']))) elif target == self.player: if card == Cards.BARON and kw.get('loser', None) == self.player: Log.print('ai: Winning card was %s' % Cards.name(kw['other_card'])) elif card == Cards.PRINCE and kw['discard'] != Cards.PRINCESS: Log.print('ai: %s draws card %s' % (self.name, Cards.name(kw['new_card']))) elif card == Cards.KING: Log.print('ai: %s now has card %s' % (self.name, Cards.name(kw['other_card'])))
def do_round(self, start_player): self.deck.reset() for info in self.agent_info: card = self.deck.draw() Log.print("dealer: Dealing %s to %s" % (Cards.name(card), info.agent)) info.cards = [card] info.out = False info.handmaiden = False info.agent.start_round(card) current = start_player Log.print("dealer: Round starts with %s" % self.agents[current].name) while self.deck.remaining() > 1: info = self.agent_info[current] if not info.out: card = self.deck.draw() Log.print("dealer: Dealing %s to %s" % (Cards.name(card), info.agent)) info.cards.append(card) info.agent.report_draw(card) play = info.agent.get_play() if not self._validate_play(play, current): Log.print("dealer: Invalid play %s" % play) continue self._process_play(play, current) players_in = len([info for info in self.agent_info if not info.out]) if players_in == 1: break current = (current + 1) % len(self.agents) time.sleep(1) cards = [None if info.out else info.cards[0] for info in self.agent_info] Log.print("report:") Log.print("report: Round is over") Log.print("report: Final cards:") for (i, card) in enumerate(cards): if card is not None: Log.print("report: %s: %s" % (self.agents[i], Cards.name(card))) lst = [i for i in range(len(cards))] lst = sorted(lst, key=lambda x: cards[x] or 0) winner = None if cards[lst[-1]] == cards[lst[-2]]: Log.print("report: Tie: No winner") else: winner = lst[-1] Log.print("report: Winner: %s" % self.agents[winner]) self.agent_info[winner].score += 1 for agent in self.agents: agent.end_round(cards, winner) return winner
def get_play(self): Log.print('ai: %s play options: %s %s' % (self.name, Cards.name(self.cards[0]), Cards.name(self.cards[1]))) self.observer.print_state('ai') ret = self._get_required_play() if not ret: cards = sorted(self.cards) card = cards[0] other_card = cards[1] ret = {'card': card} if card == Cards.GUARD: (player, card, certainty) = self._most_likely(exclude_card=Cards.GUARD) if other_card == Cards.HANDMAIDEN and certainty < 1: ret['card'] = Cards.HANDMAIDEN else: ret['target'] = player.number ret['challenge'] = card elif card == Cards.PRIEST: (player, card, certainty) = self._least_likely() if other_card == Cards.HANDMAIDEN: ret['card'] = Cards.HANDMAIDEN else: ret['target'] = player.number elif card == Cards.BARON: (player, certainty) = self._most_likely_less_than(other_card) if other_card == Cards.HANDMAIDEN and certainty < 1: ret['card'] = Cards.HANDMAIDEN else: ret['target'] = player.number elif card in (Cards.PRINCE, Cards.KING): (player, value) = self._highest_expected_value() ret['target'] = player.number return ret
def _least_likely(self, exclude_card=None): lst = [] for player in self.observer.players: if player.number != self.player and not player.out: (card, certainty) = player.cards.most_likely(exclude_card) lst.append((player, card, certainty)) random.shuffle(lst) lst = sorted(lst, key=lambda x: x[0].score, reverse=True) lst = sorted(lst, key=lambda x: x[2]) lst = sorted(lst, key=lambda x: x[0].handmaiden) Log.print('ai: Hand probabilities:') for l in lst: Log.print('ai: %s: %s (%i%% chance) %s' % (l[0].name, Cards.name(l[1]), l[2] * 100, '(HANDMAIDEN)' if l[0].handmaiden else '')) winner = lst[0] Log.print('ai: %s has least certain hand (%i%% chance of card %s)' % (winner[0].name, winner[2] * 100, Cards.name(winner[1]))) return winner
def _report_play(self, *k, **kw): player = kw["player"] card = kw["card"] target = kw.get("target", None) discard = kw.get("discard", None) Log.print("report: ") if target is not None: Log.print("report: %s plays card %s on %s" % (self.agents[player], Cards.name(card), self.agents[target])) else: Log.print("report: %s plays card %s" % (self.agents[player], Cards.name(card))) if target is not None: if self.agent_info[target].handmaiden: Log.print("report: %s is unaffected due to HANDMAIDEN" % self.agents[target]) else: if card == Cards.GUARD: challenge = kw["challenge"] Log.print("report: %s is accused of having card %s" % (self.agents[target], Cards.name(challenge))) if discard: Log.print("report: %s discards card %s" % (self.agents[target], Cards.name(discard))) Log.print("report: %s is out" % self.agents[target]) else: Log.print("report: %s does not have card %s" % (self.agents[target], Cards.name(challenge))) elif card == Cards.BARON: loser = kw.get("loser", None) if loser is not None: Log.print( "report: %s loses challenge, discards card %s" % (self.agents[loser], Cards.name(discard)) ) Log.print("report: %s is out" % self.agents[loser]) elif card == Cards.PRINCE: Log.print("report: %s discards card %s" % (self.agents[target], Cards.name(discard))) if discard == Cards.PRINCESS: Log.print("report: %s is out" % self.agents[target]) if card == Cards.PRINCESS: Log.print("report: %s is out" % self.agents[player])
def get_play(self): Log.print( 'ai: %s play options: %s %s' % (self.name, Cards.name(self.cards[0]), Cards.name(self.cards[1]))) self.observer.print_state('ai') ret = self._get_required_play() if not ret: cards = sorted(self.cards) card = cards[0] other_card = cards[1] ret = {'card': card} if card == Cards.GUARD: (player, card, certainty) = self._most_likely(exclude_card=Cards.GUARD) if other_card == Cards.HANDMAIDEN and certainty < 1: ret['card'] = Cards.HANDMAIDEN else: ret['target'] = player.number ret['challenge'] = card elif card == Cards.PRIEST: (player, card, certainty) = self._least_likely() if other_card == Cards.HANDMAIDEN: ret['card'] = Cards.HANDMAIDEN else: ret['target'] = player.number elif card == Cards.BARON: (player, certainty) = self._most_likely_less_than(other_card) if other_card == Cards.HANDMAIDEN and certainty < 1: ret['card'] = Cards.HANDMAIDEN else: ret['target'] = player.number elif card in (Cards.PRINCE, Cards.KING): (player, value) = self._highest_expected_value() ret['target'] = player.number return ret
def _report_play(self, *k, **kw): player = kw['player'] card = kw['card'] target = kw.get('target', None) discard = kw.get('discard', None) Log.print('report: ') if target is not None: Log.print( 'report: %s plays card %s on %s' % (self.agents[player], Cards.name(card), self.agents[target])) else: Log.print('report: %s plays card %s' % (self.agents[player], Cards.name(card))) if target is not None: if self.agent_info[target].handmaiden: Log.print('report: %s is unaffected due to HANDMAIDEN' % self.agents[target]) else: if card == Cards.GUARD: challenge = kw['challenge'] Log.print('report: %s is accused of having card %s' % (self.agents[target], Cards.name(challenge))) if discard: Log.print('report: %s discards card %s' % (self.agents[target], Cards.name(discard))) Log.print('report: %s is out' % self.agents[target]) else: Log.print('report: %s does not have card %s' % (self.agents[target], Cards.name(challenge))) elif card == Cards.BARON: loser = kw.get('loser', None) if loser is not None: Log.print( 'report: %s loses challenge, discards card %s' % (self.agents[loser], Cards.name(discard))) Log.print('report: %s is out' % self.agents[loser]) elif card == Cards.PRINCE: Log.print('report: %s discards card %s' % (self.agents[target], Cards.name(discard))) if discard == Cards.PRINCESS: Log.print('report: %s is out' % self.agents[target]) if card == Cards.PRINCESS: Log.print('report: %s is out' % self.agents[player])
def _most_likely(self, exclude_card=None): lst = [] for player in self.observer.players: if player.number != self.player and not player.out: (card, certainty) = player.cards.most_likely(exclude_card) lst.append((player, card, certainty)) random.shuffle(lst) lst = sorted(lst, key=lambda x: x[0].score, reverse=True) lst = sorted(lst, key=lambda x: x[2], reverse=True) lst = sorted(lst, key=lambda x: x[0].handmaiden) Log.print('ai: Hand probabilities:') for l in lst: Log.print('ai: %s: %s (%i%% chance) %s' % (l[0].name, Cards.name(l[1]), l[2] * 100, '(HANDMAIDEN)' if l[0].handmaiden else '')) winner = lst[0] Log.print('ai: %s has most certain hand (%i%% chance of card %s)' % (winner[0].name, winner[2] * 100, Cards.name(winner[1]))) return winner
def _most_likely_less_than(self, card): lst = [] for player in self.observer.players: if player.number != self.player and not player.out: certainty = player.cards.chance_less_than(card) lst.append((player, certainty)) random.shuffle(lst) lst = sorted(lst, key=lambda x: x[0].score, reverse=True) lst = sorted(lst, key=lambda x: x[1], reverse=True) lst = sorted(lst, key=lambda x: x[0].handmaiden) Log.print('ai: Probabilities that hand is less than %s:' % Cards.name(card)) for l in lst: Log.print('ai: %s: %i%% %s' % (l[0].name, l[1] * 100, '(HANDMAIDEN)' if l[0].handmaiden else '')) winner = lst[0] Log.print('ai: %s has best chance (%i%%)' % (winner[0].name, winner[1] * 100)) return winner
def report_draw(self, card): super(LowballAgent, self).report_draw(card) Log.print('ai: %s draws card %s' % (self.name, Cards.name(card)))
def start_round(self, card): super(LowballAgent, self).start_round(card) Log.print('ai: %s starts with card %s' % (self.name, Cards.name(card)))
def get_play(self): card = None self.cards = sorted(self.cards) play = {} print() s = ' '.join(['%s(%i)' % (player.name, player.score) for player in self.observer.players if not player.out]) print('Players still in round: %s' % s) s = ' '.join('%s(%i)' % (Cards.name(card), self.discarded[card]) for card in range(Cards.NUM_CARDS) if self.discarded[card] > 0) print('Discarded cards: %s' % s) while card is None: print('Available cards are [%i] %s [%i] %s' % (self.cards[0], Cards.name(self.cards[0]), self.cards[1], Cards.name(self.cards[1]))) print('Enter selection: ', end='') sys.stdout.flush() line = sys.stdin.readline().strip() if line.startswith('enable'): Log.enable(line.split(' ')[1]) continue elif line.startswith('disable'): Log.disable(line.split(' ')[1]) continue try: c = int(line) if c in self.cards: card = c except ValueError: pass if card is None: print(' Invalid selection') elif card in (Cards.PRINCE, Cards.KING) and Cards.COUNTESS in self.cards: print(' Must discard COUNTESS') card = None play['card'] = card if card in (Cards.GUARD, Cards.PRIEST, Cards.BARON, Cards.PRINCE, Cards.KING): players = [] for player in self.observer.players: if player.out: continue if player.number == self.player and card != Cards.PRINCE: continue players.append(player) target = None while target is None: print() s = ' '.join(['[%i] %s' % (player.number + 1, player.name) for player in players]) print('Players: %s' % s) print('Enter target player: ', end='') sys.stdout.flush() try: t = int(sys.stdin.readline()) - 1 if t in range(len(self.observer.players)) and self.observer.players[t] in players: target = t except IndexError: pass except ValueError: pass if target is None: print(' Invalid selection') play['target'] = target if card == Cards.GUARD: challenge = None while challenge is None: print() s = ' '.join(['[%i] %s' % (card, Cards.name(card)) for card in range(Cards.GUARD, Cards.NUM_CARDS)]) print('Cards: %s' % s) print('Enter challenge card: ', end='') sys.stdout.flush() try: c = int(sys.stdin.readline()) if c in range(Cards.GUARD, Cards.NUM_CARDS): challenge = c except ValueError: pass if challenge is None: print(' Invalid selection') play['challenge'] = challenge return play
def report_draw(self, card): super(ConsoleAgent, self).report_draw(card) print('%s draws card %s' % (self.name, Cards.name(card)))
def start_round(self, card): super(ConsoleAgent, self).start_round(card) print() print('%s starts with card %s' % (self.name, Cards.name(card))) self.discarded = [0 for i in range(Cards.NUM_CARDS)]
def do_round(self, start_player): self.deck.reset() for info in self.agent_info: card = self.deck.draw() Log.print('dealer: Dealing %s to %s' % (Cards.name(card), info.agent)) info.cards = [card] info.out = False info.handmaiden = False info.agent.start_round(card) current = start_player Log.print('dealer: Round starts with %s' % self.agents[current].name) while self.deck.remaining() > 1: info = self.agent_info[current] if not info.out: card = self.deck.draw() Log.print('dealer: Dealing %s to %s' % (Cards.name(card), info.agent)) info.cards.append(card) info.agent.report_draw(card) play = info.agent.get_play() if not self._validate_play(play, current): Log.print('dealer: Invalid play %s' % play) continue self._process_play(play, current) players_in = len( [info for info in self.agent_info if not info.out]) if players_in == 1: break current = (current + 1) % len(self.agents) time.sleep(1) cards = [ None if info.out else info.cards[0] for info in self.agent_info ] Log.print('report:') Log.print('report: Round is over') Log.print('report: Final cards:') for (i, card) in enumerate(cards): if card is not None: Log.print('report: %s: %s' % (self.agents[i], Cards.name(card))) lst = [i for i in range(len(cards))] lst = sorted(lst, key=lambda x: cards[x] or 0) winner = None if cards[lst[-1]] == cards[lst[-2]]: Log.print('report: Tie: No winner') else: winner = lst[-1] Log.print('report: Winner: %s' % self.agents[winner]) self.agent_info[winner].score += 1 for agent in self.agents: agent.end_round(cards, winner) return winner
def get_play(self): card = None self.cards = sorted(self.cards) play = {} print() s = ' '.join([ '%s(%i)' % (player.name, player.score) for player in self.observer.players if not player.out ]) print('Players still in round: %s' % s) s = ' '.join('%s(%i)' % (Cards.name(card), self.discarded[card]) for card in range(Cards.NUM_CARDS) if self.discarded[card] > 0) print('Discarded cards: %s' % s) while card is None: print('Available cards are [%i] %s [%i] %s' % (self.cards[0], Cards.name(self.cards[0]), self.cards[1], Cards.name(self.cards[1]))) print('Enter selection: ', end='') sys.stdout.flush() line = sys.stdin.readline().strip() if line.startswith('enable'): Log.enable(line.split(' ')[1]) continue elif line.startswith('disable'): Log.disable(line.split(' ')[1]) continue try: c = int(line) if c in self.cards: card = c except ValueError: pass if card is None: print(' Invalid selection') elif card in (Cards.PRINCE, Cards.KING) and Cards.COUNTESS in self.cards: print(' Must discard COUNTESS') card = None play['card'] = card if card in (Cards.GUARD, Cards.PRIEST, Cards.BARON, Cards.PRINCE, Cards.KING): players = [] for player in self.observer.players: if player.out: continue if player.number == self.player and card != Cards.PRINCE: continue players.append(player) target = None while target is None: print() s = ' '.join([ '[%i] %s' % (player.number + 1, player.name) for player in players ]) print('Players: %s' % s) print('Enter target player: ', end='') sys.stdout.flush() try: t = int(sys.stdin.readline()) - 1 if t in range(len(self.observer.players) ) and self.observer.players[t] in players: target = t except IndexError: pass except ValueError: pass if target is None: print(' Invalid selection') play['target'] = target if card == Cards.GUARD: challenge = None while challenge is None: print() s = ' '.join([ '[%i] %s' % (card, Cards.name(card)) for card in range(Cards.GUARD, Cards.NUM_CARDS) ]) print('Cards: %s' % s) print('Enter challenge card: ', end='') sys.stdout.flush() try: c = int(sys.stdin.readline()) if c in range(Cards.GUARD, Cards.NUM_CARDS): challenge = c except ValueError: pass if challenge is None: print(' Invalid selection') play['challenge'] = challenge return play
def _process_play(self, play, player): report = {} report_player = {} report_target = {} card = play['card'] report['card'] = card report['player'] = player player_info = self.agent_info[player] player_info.handmaiden = False player_info.cards.remove(card) target = play.get('target', None) if target is not None: report['target'] = target target_info = self.agent_info[target] if not target_info.handmaiden: if card == Cards.GUARD: challenge = play['challenge'] report['challenge'] = challenge if challenge in target_info.cards: report['discard'] = challenge target_info.cards.remove(challenge) target_info.out = True elif card == Cards.PRIEST: report_player['other_card'] = target_info.cards[0] elif card == Cards.BARON: player_card = player_info.cards[0] target_card = target_info.cards[0] if target_card > player_card: report['loser'] = player report['discard'] = player_card report_player['other_card'] = target_card player_info.cards.remove(player_card) player_info.out = True elif target_card < player_card: report['loser'] = target report['discard'] = target_card report_target['other_card'] = player_card target_info.cards.remove(target_card) target_info.out = True elif card == Cards.PRINCE: discard = target_info.cards[0] report['discard'] = discard target_info.cards.remove(discard) if discard == Cards.PRINCESS: target_info.out = True else: new_card = self.deck.draw() Log.print('dealer: Dealing %s to %s' % (Cards.name(card), self.agents[target].name)) report_target['new_card'] = new_card target_info.cards.append(new_card) elif card == Cards.KING: report_player['other_card'] = target_info.cards[0] report_target['other_card'] = player_info.cards[0] target_info.cards, player_info.cards = player_info.cards, target_info.cards if card == Cards.HANDMAIDEN: player_info.handmaiden = True elif card == Cards.PRINCESS: player_info.out = True self._report_play(**report) for i in range(len(self.agents)): report_agent = {} report_agent.update(report) if i == player: report_agent.update(report_player) if target is not None and i == target: report_agent.update(report_target) self.agents[i].report_play(**report_agent)
def _process_play(self, play, player): report = {} report_player = {} report_target = {} card = play["card"] report["card"] = card report["player"] = player player_info = self.agent_info[player] player_info.handmaiden = False player_info.cards.remove(card) target = play.get("target", None) if target is not None: report["target"] = target target_info = self.agent_info[target] if not target_info.handmaiden: if card == Cards.GUARD: challenge = play["challenge"] report["challenge"] = challenge if challenge in target_info.cards: report["discard"] = challenge target_info.cards.remove(challenge) target_info.out = True elif card == Cards.PRIEST: report_player["other_card"] = target_info.cards[0] elif card == Cards.BARON: player_card = player_info.cards[0] target_card = target_info.cards[0] if target_card > player_card: report["loser"] = player report["discard"] = player_card report_player["other_card"] = target_card player_info.cards.remove(player_card) player_info.out = True elif target_card < player_card: report["loser"] = target report["discard"] = target_card report_target["other_card"] = player_card target_info.cards.remove(target_card) target_info.out = True elif card == Cards.PRINCE: discard = target_info.cards[0] report["discard"] = discard target_info.cards.remove(discard) if discard == Cards.PRINCESS: target_info.out = True else: new_card = self.deck.draw() Log.print("dealer: Dealing %s to %s" % (Cards.name(card), self.agents[target].name)) report_target["new_card"] = new_card target_info.cards.append(new_card) elif card == Cards.KING: report_player["other_card"] = target_info.cards[0] report_target["other_card"] = player_info.cards[0] target_info.cards, player_info.cards = player_info.cards, target_info.cards if card == Cards.HANDMAIDEN: player_info.handmaiden = True elif card == Cards.PRINCESS: player_info.out = True self._report_play(**report) for i in range(len(self.agents)): report_agent = {} report_agent.update(report) if i == player: report_agent.update(report_player) if target is not None and i == target: report_agent.update(report_target) self.agents[i].report_play(**report_agent)