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 select(crds): # -> idxSet, zid assert type(crds) is HandCards, "TypeError: not HandCards" assert 0 < len(crds) <= 5, "IndexError: overrange" keyMap = {'Z': 0, 'X': 1, 'C': 2, 'V': 3, 'B': 4} keyStr = "ZXCVB" keyStr = keyStr[0:len(crds)] # fix length to n print('use [%s] to select:' % keyStr) idxSet = set() selC, actLst = [], [] while True: k = getkey(blocking=True) # block version kn = keys.name(k) if len(kn) == 1 and kn in keyMap: if kn in idxSet: # already in set idxSet ^= {keyMap[kn]} # xor, flip else: idxSet |= {keyMap[kn]} # or, update selC = Cards([crds[i] for i in idxSet]) actLst = match(selC) print(selC, actLst) elif kn in {'ENTER', 'SPACE'} and len(actLst) > 0: if len(actLst) > 1: return idxSet, actLst[choose(actLst)] else: return idxSet, actLst[0] elif kn == "ESC": idxSet = set() else: pass
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
class Player(object): def __init__(self): self.id = None self.cards = Cards() def pick(self, card): self.cards.append(card) def readyPlay(self): pass def play(self, last_round): print("hand: %s \n" % self.cards) inputs = input("your turn, enter letter to play or enter p to pass:"******"p": return PLAY_PASS inputs = upper(inputs) check_ret, v = self.check(inputs) if check_ret is True: cards = Cards(inputs, v[0], v[1]) self.removeCards(cards) return cards inputs = input(v) def check(self, inputs): if not self.cards.isContain(Cards(inputs)): return False, "played not exist card! your turn:" v = cardStringsValue(inputs) if v[1] <= 0: return False, "invalid card type! your turn:" return True, v def removeCards(self, cards): self.cards.remove(cards) def isEmpty(self): return not bool(len(self.cards.strings))
def check(self, inputs): if not self.cards.isContain(Cards(inputs)): return False, "played not exist card! your turn:" v = cardStringsValue(inputs) if v[1] <= 0: return False, "invalid card type! your turn:" return True, v
def draw( player: 'Player', deck: Deck, num: int=1 ) -> typing.Tuple['Player', Deck]: if num not in range(1, len(deck) + 1): return player, deck return ( Player(player.name(), hand=player.hand() + Cards(deck[:num])), Deck(deck[num:]))
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 play(self, last_round): print("hand: %s \n" % self.cards) inputs = input("your turn, enter letter to play or enter p to pass:"******"p": return PLAY_PASS inputs = upper(inputs) check_ret, v = self.check(inputs) if check_ret is True: cards = Cards(inputs, v[0], v[1]) self.removeCards(cards) return cards inputs = input(v)
def read_cards(database, query_tuple): """ read card data """ conn = sqlite3.connect(database) cursor = conn.cursor() if query_tuple == "all": cursor.execute("SELECT DISTINCT posid, statid FROM cards") all_cards = cursor.fetchall() else: all_cards = query_tuple cards = Cards() for t in all_cards: cursor.execute("""SELECT time FROM cards WHERE posid = ? AND statid = ? ORDER BY time ASC""", t) results = cursor.fetchall() results = [time[0] for time in results] card = Card(results, t) cards.add(card) cursor.close() conn.close() return cards
def play(self, last_round): print("AI", self.hc) if last_round in (PLAY_FIRST, PLAY_PASS): p = self.initiativePlay() else: p = self.passivePlay(last_round) if p == PLAY_PASS: print("PASS") return p v = cardStringsValue(p) ret = Cards(p, v[0], v[1]) self.hc.remove(ret) print("play", ret) return ret
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 read_cards(database, query_tuple): """ read card data """ conn = sqlite3.connect(database) cursor = conn.cursor() if query_tuple == "all": cursor.execute("SELECT DISTINCT posid, statid FROM cards") all_cards = cursor.fetchall() else: all_cards = query_tuple cards = Cards() for t in all_cards: cursor.execute( """SELECT time FROM cards WHERE posid = ? AND statid = ? ORDER BY time ASC""", t) results = cursor.fetchall() results = [time[0] for time in results] card = Card(results, t) cards.add(card) cursor.close() conn.close() return cards
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_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 _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 selectR(crds): # -> idxSet, zid assert type(crds) is HandCards, "TypeError: not HandCards" assert 0 < len(crds) <= 5, "IndexError: overrange" bag = list(range(1, 2**len(crds))) while True: if len(bag) > 0: r = randint(0, len(bag) - 1) # as index else: raise RuntimeError("no choice in bag") selPat = [bag[r] & (2**i) > 0 for i in range(5)] # binary exp idxSet = [] selC = [] for i in range(5): if selPat[i]: selC.append(crds[i]) idxSet.append(i) actLst = match(Cards(selC)) if len(actLst) >= 1: return set(idxSet), choice(actLst) else: del bag[r] # remove this val
disc = drawC.pickup(idxSet) print("drawWD(): drawC, disc ->", drawC, disc) self.discPile.join(disc) # drop one card self.hand.join(drawC) # drawC >> hand def action(self): # exec, deal and draw print("player(%s) action" % self.name) self.deal() self.draw() # self.drawD(deck) # note: let upper object contorl turn if __name__ == "__main__": deck = Cards([13, 12, 11, 10, 9, 8, 7, 6]) deck = Deck([0, 1, 1, 1, 1, 1, 1, 1, 1]) disP = Cards() p = Player("s", deck, disP, [1, 2, 3]) print(p) p.deal() print("after deal()", p) print("draw(1) from deck") p.draw(1) print("p,deck= ", p, deck) p._clearHand() print("draw(2) from deck") p.draw(2) print("p,deck= ", p, deck)
class Robot(Person): """机器人""" def __init__(self, name, credits=100): super().__init__(name, credits) self.is_real = False self.output_name = name self.cards_blocks = None def reset_profile(self): self.cards = Cards() self.identity = None self.landlord_score = None self.cards_blocks = None def deal_landlord_score(self, last_landlord_score): if self.landlord_score is None: self.landlord_score = min(self.cards.cal_confidence(), 3) if self.landlord_score > last_landlord_score: MessagePoster.post_hint(hint_type='person_gave_landlord_score', output_name=self.output_name, landlord_score=str(self.landlord_score)) return self.landlord_score else: MessagePoster.post_hint( hint_type='person_abandon_giving_landlord_score', output_name=self.output_name) return def deal_cards_with_last_cards(self, last_cards, last_person_identity): ## 不管10以上的同伙的牌 if self.identity == last_person_identity and last_cards.size >= Card( 'J').size: MessagePoster.post_hint(hint_type='person_abandon_dealing_cards', output_name=self.output_name) return for undealed_cards in self.cards_blocks[::-1]: if undealed_cards > last_cards: self.cards_blocks.remove(undealed_cards) self.cards -= undealed_cards MessagePoster.post_hint(hint_type='person_dealed_cards', output_name=self.output_name, unprinted_cards=str(undealed_cards)) return undealed_cards else: MessagePoster.post_hint(hint_type='person_abandon_dealing_cards', output_name=self.output_name) return def deal_cards_without_last_cards(self): undealed_cards = self.cards_blocks.pop() self.cards -= undealed_cards MessagePoster.post_hint(hint_type='person_dealed_cards', unprinted_cards=str(undealed_cards), output_name=self.output_name) return undealed_cards def deal_cards(self, last_cards, last_person_identity): if self.cards_blocks is None: self.cards_blocks = self.cards.separate() # for cards_block in self.cards_blocks: # print(f'{str(cards_block)}, {cards_block.species}, {cards_block.chain_length}, {cards_block.size}') if last_cards is not None: undealed_cards = self.deal_cards_with_last_cards( last_cards, last_person_identity) else: undealed_cards = self.deal_cards_without_last_cards() return undealed_cards
def reset_profile(self): self.cards = Cards() self.identity = None self.landlord_score = None
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 reset(self): self.cards = [] for card in range(Cards.GUARD, Cards.NUM_CARDS): self.cards.extend([card for i in range(Cards.start_count(card))]) random.shuffle(self.cards)
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 _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)
# game object, use ring to keep game running from card import Deck, Cards from player import Player from ring import Ring from time import sleep deck = Deck() disP = Cards() p1 = Player("A", deck, disP) p2 = Player("B", deck, disP) players = Ring([p1, p2]) turn = 0 while True: turn = turn + 1 print("turn#%d " % turn, end='') players.now().action() players.goNext() sleep(1)
def __init__(self, name, credits): self.name = name self.credits = credits self.cards = Cards() self.identity = None self.landlord_score = None
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 __init__(self): self.id = None self.cards = Cards()
# load asset npc kiri = pygame.image.load('assets/kiri.png') kanan = pygame.image.load('assets/kanan.png') atas = pygame.image.load('assets/atas.png') kiri2 = pygame.image.load('assets/kiri.png') kanan2 = pygame.image.load('assets/kanan.png') atas2 = pygame.image.load('assets/atas.png') # width, height npc kiri = pygame.transform.scale(kiri, (90, 120)) kanan = pygame.transform.scale(kanan, (90, 120)) atas = pygame.transform.scale(atas, (120, 90)) kiri2 = pygame.transform.scale(kiri, (90, 120)) kanan2 = pygame.transform.scale(kanan, (90, 120)) atas2 = pygame.transform.scale(atas, (120, 90)) cards = Cards(pygame, screen) cards.load('assets/PNGs/new/') submit_button = Button(pygame, screen, 'assets/submit.png', 1050, 600) start_button = Button(pygame, screen, 'assets/start.png', 831, 465) draw_button = Button(pygame, screen, 'assets/draw.png', 950, 600) skip_button = Button(pygame, screen, 'assets/skip.png', 950, 600) submit_button.scale(94,40) draw_button.scale(90,40) skip_button.scale(56,40) select_color = 0 while(True): if game_status == None:
def report_draw(self, card): super(ConsoleAgent, self).report_draw(card) print('%s draws card %s' % (self.name, Cards.name(card)))
def deal_cards(self, last_cards, last_person_identity=None): ## 先给玩家看自己手中的牌 MessagePoster.post_hint(hint_type='player_show_cards', unshowed_cards=str(self.cards)) ## 让用户一直出牌, 直到牌大过上家或者放弃出牌 while True: raw_order = MessageGetter.get_order(order_type='deal_cards') ## 退出游戏 if isinstance(raw_order, GameExiter): return GameExiter() ## 如果玩家要不起/不要, 则返回None if raw_order == 'p': ## 有牌权出牌不能跳过 if last_cards is not None: MessagePoster.post_hint( hint_type='person_abandon_dealing_cards', output_name=self.output_name) return else: MessagePoster.post_hint( hint_type= 'player_can_not_skip_deal_cards_without_last_cards') continue undealed_cards = Cards([Card(pattern) for pattern in raw_order]) ## 牌的验证 ## 牌的子集验证 if not undealed_cards in self.cards: MessagePoster.post_hint( hint_type='invaild_cards_pattern_or_too_many_cards') continue meta_data = undealed_cards.cal_meta_data() ## 牌的元数据验证(实际是有效性验证) if meta_data is None: MessagePoster.post_hint(hint_type='invaild_cards_species') continue ## 出牌 ## 如果是有牌权出牌, 可以直接出 if last_cards is None: MessagePoster.post_hint(hint_type='person_dealed_cards', output_name=self.output_name, unprinted_cards=str(undealed_cards)) self.cards -= undealed_cards return undealed_cards ## 牌型相符且牌比上家大(考虑到炸弹类型) elif undealed_cards > last_cards: MessagePoster.post_hint(hint_type='person_dealed_cards', output_name=self.output_name, unprinted_cards=str(undealed_cards)) self.cards -= undealed_cards return undealed_cards ## 牌型不符或牌型一样但没有上家大 else: MessagePoster.post_hint(hint_type='cards_size_too_small') continue
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 report_draw(self, card): super(LowballAgent, self).report_draw(card) Log.print('ai: %s draws card %s' % (self.name, Cards.name(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