c = "" while True: try: c = read_raw_data(msg) cn = pe.string2card(c) break except: print c, " isn't a card!" return c ############################################ print "deck = %s\n" % pe.card2string(pe.deck()) print "---------------------------------------" n_players_ = read_data("N players> ") big_blind_ = read_data("Big Blind> ") print "---------------------------------------" print "cards> 2, ... , 9, T, J, Q, K, A" print "ranks> %s" % ranks_ player_hand_ = [] for i in range(1, 3): player_hand_.append(read_card("Player card %d> " % (i))) pockets_ = [player_hand_] print player_hand_
game="omaha", pockets=[["tc", "ac", "ks", "kc"], ["th", "ah", "qs", "qc"], ["8c", "6h", "js", "jc"]], dead=[], board=["7h", "3s", "2c", "7s", "7d"], ) print "winners omaha8 = %s\n" % pokereval.winners( game="omaha8", pockets=[["tc", "ac", "ks", "kc"], ["th", "ah", "qs", "qc"], ["8c", "6h", "js", "jc"]], dead=[], board=["7h", "3s", "2c", "7s", "7d"], ) hand = ["Ac", "As", "Td", "7s", "7h", "3s", "2c"] best_hand = pokereval.best_hand("hi", hand) print "best hand from %s = %s" % (hand, pokereval.best_hand("hi", hand)) print "best hand from %s = (%s) %s " % (hand, best_hand[0], [pokereval.card2string(i) for i in best_hand[1:]]) print "" hand = ["Ah", "Ts", "Kh", "Qs", "Js"] best_hand = pokereval.best_hand("hi", hand) print "best hand from %s = %s" % (hand, pokereval.best_hand("hi", hand)) print "best hand from %s = (%s) %s " % (hand, best_hand[0], [pokereval.card2string(i) for i in best_hand[1:]]) print "" hand = ["2h", "Kh", "Qh", "Jh", "Th"] best_hand = pokereval.best_hand("hi", hand) print "best hand from %s = %s" % (hand, pokereval.best_hand("hi", hand)) print "best hand from %s = (%s) %s " % (hand, best_hand[0], [pokereval.card2string(i) for i in best_hand[1:]]) print "" hand = ["2s", "3s", "Jd", "Ks", "As", "4d", "5h", "7d", "9c"]
pockets=[["tc", "ac", "ks", "kc"], ["th", "ah", "qs", "qc"], ["8c", "6h", "js", "jc"]], dead=[], board=["7h", "3s", "2c", "7s", "7d"]) print "winners omaha8 = %s\n" % pokereval.winners( game="omaha8", pockets=[["tc", "ac", "ks", "kc"], ["th", "ah", "qs", "qc"], ["8c", "6h", "js", "jc"]], dead=[], board=["7h", "3s", "2c", "7s", "7d"]) hand = ["Ac", "As", "Td", "7s", "7h", "3s", "2c"] best_hand = pokereval.best_hand("hi", hand) print "best hand from %s = %s" % (hand, pokereval.best_hand("hi", hand)) print "best hand from %s = (%s) %s " % ( hand, best_hand[0], [pokereval.card2string(i) for i in best_hand[1:]]) print "" hand = ["Ah", "Ts", "Kh", "Qs", "Js"] best_hand = pokereval.best_hand("hi", hand) print "best hand from %s = %s" % (hand, pokereval.best_hand("hi", hand)) print "best hand from %s = (%s) %s " % ( hand, best_hand[0], [pokereval.card2string(i) for i in best_hand[1:]]) print "" hand = ["2h", "Kh", "Qh", "Jh", "Th"] best_hand = pokereval.best_hand("hi", hand) print "best hand from %s = %s" % (hand, pokereval.best_hand("hi", hand)) print "best hand from %s = (%s) %s " % ( hand, best_hand[0], [pokereval.card2string(i) for i in best_hand[1:]])
if p_temp != None: pocket.append([p_temp,card_at_pos(p[1],screen)]) break #Determine number of other players num_other_players = 0 for p in op_card_pos: if is_op_at(p,screen): num_other_players += 1 print num_other_players,board,pocket, win = None if len(pocket) == 1 and len(pocket[0]) == 2 and pocket[0][0] != None and pocket[0][1] != None: #Set up a fresh deck fresh_deck = pokereval.deck() for i in range(0,len(fresh_deck)): fresh_deck[i] = pokereval.card2string(fresh_deck[i]) #Remove known cards from deck deck = list(fresh_deck) for i in pocket[0]: if i in deck: deck.remove(i) for i in board: if i in deck: deck.remove(i) #The important bit, calculates number of wins/losses for random sample win = 0 loss = 0 for i in range(0,5000): tmp_deck = list(deck) tmp_pocket = list(pocket) tmp_board = list(board)
class Table(object): def __init__(self, protocol, avatar, table_info): self.protocol = protocol self.id = table_info.get('id', 0) self.seat = table_info.get('player_seated', -1) self.seats = [0] * table_info.get('seats', 10) if self.seat != -1: self.seats[self.seat] = avatar.serial assert avatar.seat == self.seat, "as %s, ss %s" % (avatar.seat, self.seat) self.name = table_info.get('name', 'unnamed') self.betting_structure = table_info['betting_structure'] blinds, buy_ins, limit = table_info['betting_structure'].split('_') min_buy_in, max_buy_in = buy_ins.split('-') small, big = blinds.split('-') self.max_buy_in = int(max_buy_in) * 100 self.min_buy_in = int(min_buy_in) * 100 self.big_blind = int(big) * 100 self.small_blind = int(small) * 100 self.players = {avatar.serial: avatar} self.avatar = avatar self._serial_and_game_id = dict(serial=avatar.serial, game_id=self.id) self._eval = PokerEval() self.reset() self._game_state = GAME_STATE_NULL def reset(self): """reseting game states for a new hand""" self.board_cards = [] self.position = -1 self._reset_players() def getBoardCards(self): """return a list of board games""" return list(map(lambda x: x & 63, self.board_cards)) def getAvatarInfo(self): """return a string of usefull information about the avatar""" return ", ".join(self._get_avatar_info()) def isInPosition(self, serial): """returs true if player with serial is in position""" return serial in self.in_game and self.position == self.in_game.index( serial) def logIt(self, astr, prefix=" [D] "): """a little helper function to log output""" self.protocol.logIt(astr, prefix=prefix) def updateSeats(self, seats): """update seat information""" for index, (old, new) in enumerate(zip(self.seats, seats)): if old == 0 and new != 0: self.addPlayer(index, new) elif old != 0 and new == 0: self.removePlayer(index) elif old != new: self.removePlayer(index) self.addPlayer(index, new) self.logIt("warning idx %s, old %s, new %s" % (index, old, new)) def addPlayer(self, index, serial): """Add player to this table""" self.seats[index] = serial # Request more information about this player if serial == self.avatar.serial: self.players[index] = self.avatar else: self.protocol.sendPacket( networkpackets.PacketPokerGetUserInfo(serial=serial)) def removePlayer(self, index): """remove player from this table""" serial = self.seats[index] self.seats[index] = 0 if serial in self.players: del self.players[serial] def updatePlayer(self, player_info): """update general palyer information (we requested them in addPlayer)""" player = self._get_or_create_player(**player_info) player.update(player_info) def updatePlayerChips(self, serial, chips, bet): """update players chips""" player = self._get_or_create_player(serial=serial) return player.updateChips(chips, bet) def updatePlayerCards(self, serial, cards): """update players cards""" player = self._get_player(serial) player.updateCards(cards) def rebuy(self, serial, amount): """update money state of player because a rebuy happend""" player = self._get_player(serial) player.rebuy(amount) def _reset_players(self): """reset player states""" for player in self.players.values(): player.reset() def highestBetNotFold(self): """returns the highest bet of all players that are not fold""" return max([0] + [ p._bet for p in self.players.values() if p.serial in self.in_game and p.notFold() ]) def inSmallBlindPosition(self): """returns True if the player in position is in small_blind position""" return len(self.in_game) > 0 and ((self.dealer + 1) % len(self.in_game)) == self.position def bigBlind(self): """returns the big_blind of the current table""" return self.big_blind or 0 def doBuyIn(self): """actually request a buy_in""" self.protocol.sendPacket( networkpackets.PacketPokerBuyIn(amount=self.max_buy_in, **self._serial_and_game_id)) self.protocol.sendPacket( networkpackets.PacketPokerAutoBlindAnte( **self._serial_and_game_id)) def doRebuy(self, amount): """actually request a rebuy""" self.protocol.sendPacket( networkpackets.PacketPokerRebuy(amount=amount, **self._serial_and_game_id)) def doSit(self): """actually request a sit""" self.protocol.sendPacket( networkpackets.PacketPokerSit(**self._serial_and_game_id)) def doSitOut(self): """actually request a sitout""" self.protocol.sendPacket( networkpackets.PacketPokerSitOut(**self._serial_and_game_id)) def doQuit(self): """actually request a table quit""" self.protocol.sendPacket( networkpackets.PacketPokerTableQuit(**self._serial_and_game_id)) def doFold(self): """actually request a fold""" self.protocol.sendPacket( networkpackets.PacketPokerFold(**self._serial_and_game_id)) def doCheck(self): """actually request a check""" self.protocol.sendPacket( networkpackets.PacketPokerCheck(**self._serial_and_game_id)) def doCall(self): """actually request a call""" self.protocol.sendPacket( networkpackets.PacketPokerCall(**self._serial_and_game_id)) def doAllIn(self): """actually raise all chips""" self.doRaise(self.avatar.getChips()) def doRaise(self, amount): """ actually request a raise by a given amount. WARNING: If the amount you requested is too low, the raise will be accepted but the minimum amount to raise will be used instead. You will be informend about the amount that is used to raise. """ self.protocol.sendPacket( networkpackets.PacketPokerRaise(amount=amount, **self._serial_and_game_id)) def explain(self, packet, state): """packets that might be interesting for the game will be handled here""" def handlePacketPokerBuyInLimits(packet): self.max_buy_in = packet.max self.min_buy_in = packet.min def handlePacketPokerSeats(packet): return self.updateSeats(packet.seats) def handlePacketPokerPlayerInfo(packet): self.updatePlayer(packet.__dict__) def handlePacketPokerPlayerChips(packet): return self.updatePlayerChips(packet.serial, chips=packet.money, bet=packet.bet) def handlePacketPokerPlayerArrive(packet): self.updatePlayer(packet.__dict__) def handlePacketPokerPlayerLeave(packet): self.removePlayer(packet.seat) def handlePacketPokerSit(packet): self._get_player(packet.serial).sit() def handlePacketPokerSitOut(packet): self._get_player(packet.serial).sitOut() def handlePacketPokerRebuy(packet): assert self.id == packet.game_id self.rebuy(packet.serial, packet.amount) def handlePacketPokerInGame(packet): assert self.id == packet.game_id self.in_game = packet.players def handlePacketPokerPosition(packet): assert self.id == packet.game_id self.position = packet.position def handlePacketPokerStart(packet): assert self.id == packet.game_id self.reset() self.hand_serial = packet.hand_serial def handlePacketPokerDealer(packet): assert self.id == packet.game_id # assert self.dealer == packet.previous_dealer self.dealer = packet.dealer def handlePacketPokerPlayerCards(packet): self.updatePlayerCards(packet.serial, packet.cards) if packet.serial == self.avatar.serial: self.logIt("You got %r" % self._cards_to_string(packet.cards)) def handlePacketPokerBoardCards(packet): self.board_cards = packet.cards def handlePacketPokerRaise(packet): self._get_player(packet.serial).bet(packet.amount) def handlePacketPokerCall(packet): player = self._get_player(packet.serial) highestbet = self.highestBetNotFold() bigb = self.bigBlind( ) if self._game_state == GAME_STATE_PRE_FLOP and not self.inSmallBlindPosition( ) else 0 # import rpdb2; rpdb2.start_embedded_debugger("haha") self.logIt("%r, %r" % (highestbet, bigb)) amount = min(max(highestbet, bigb) - player._bet, player.money) player.bet(amount) def handlePacketPokerState(packet): self._game_state = packet.string def handlePacketPokerBlind(packet): self._get_player(packet.serial).bet(packet.amount) try: handle = locals()["handle" + packet.__class__.__name__] return handle(packet) except KeyError: # self.logIt(" explain cant handle : %r" % packet.__class__.__name__) return True except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() self.logIt(packet.__class__.__name__, prefix=" EEE handle failed: ") for exline in traceback.format_exception(exc_type, exc_value, exc_traceback): for line in exline.split('\n'): self.logIt(str(line), prefix=" EEE ") def _cards_to_string(self, cards): """return a string for cards in a human readable way""" return repr(self._eval.card2string(map(lambda x: x & 63, cards)))\ #.lower().replace("h", u"\u2761").replace("s", u"\u2660").replace("c", u"\u2663").replace("d", u"\u2662") def _get_or_create_player(self, serial, seat=None, **player_info): """returns the player with the serial, the player will be created if it does not exist yet""" # serial = player_info['serial'] # seat = player_info['seat'] if seat and self.seats[seat] != 0 and serial != self.seats[seat]: self.logIt("%s is allready on seat %s, cleared" % (self.seats[seat], seat)) del self.players[self.seats[seat]] self.seats[seat] = serial if serial not in self.players: self.players[serial] = Player(serial=serial, seat=seat, **player_info) return self.players[serial] def _get_player(self, serial): """returns the player, raises an IndexError if it does not exist""" return self.players[serial] def _log_players(self): """ log player informations """ self.logIt("Players:") for player in self.players.itervalues(): self.logIt(player._player_info()) self.logIt("") def getDebugLines(self): """returns a list of debug lines (yellow box)""" return self._get_table_info() + self._get_avatar_info( ) + self._get_player_info() @catcher def _get_table_info(self): """returns a list of table informations""" highestbet = self.highestBetNotFold(), bigb = self.bigBlind( ) if self._game_state == GAME_STATE_PRE_FLOP and not self.inSmallBlindPosition( ) else 0 return [ "blinds: small:%r big:%r" % (self.small_blind, self.big_blind), "buy_ins: min:%r max:%r" % (self.min_buy_in, self.max_buy_in), "bs: %r" % self.betting_structure, "highestbet = %r" % highestbet, "bigb = %r" % bigb, ] @catcher def _get_player_info(self): """returns a list with player informations for all players""" return [player._player_info() for player in self.players.values()] @catcher def _get_avatar_info(self): """returns informations of the avatar that is currently logged in""" retvals = [] if self.avatar.cards: retvals.append("hand: " + self._cards_to_string(self.avatar.cards)) if self.board_cards: retvals.append("board: " + self._cards_to_string(self.board_cards)) if self.avatar.cards: best_hand = self._eval.best_hand( "hi", self.avatar.getCards() + self.getBoardCards()) desc = best_hand.pop(0) retvals.append("%s: %s" % (desc, self._cards_to_string(best_hand))) return retvals
class Table(object): def __init__(self, protocol, avatar, table_info): self.protocol = protocol self.id = table_info.get('id', 0) self.seat = table_info.get('player_seated', -1) self.seats = [0] * table_info.get('seats', 10) if self.seat != -1: self.seats[self.seat] = avatar.serial assert avatar.seat == self.seat, "as %s, ss %s" % (avatar.seat, self.seat) self.name = table_info.get('name', 'unnamed') self.betting_structure = table_info['betting_structure'] blinds, buy_ins, limit = table_info['betting_structure'].split('_') min_buy_in, max_buy_in = buy_ins.split('-') small, big = blinds.split('-') self.max_buy_in = int(max_buy_in)*100 self.min_buy_in = int(min_buy_in)*100 self.big_blind = int(big)*100 self.small_blind = int(small)*100 self.players = {avatar.serial: avatar} self.avatar = avatar self._serial_and_game_id = dict(serial=avatar.serial, game_id=self.id) self._eval = PokerEval() self.reset() self._game_state = GAME_STATE_NULL def reset(self): """reseting game states for a new hand""" self.board_cards = [] self.position = -1 self._reset_players() def getBoardCards(self): """return a list of board games""" return list(map(lambda x:x&63, self.board_cards)) def getAvatarInfo(self): """return a string of usefull information about the avatar""" return ", ".join(self._get_avatar_info()) def isInPosition(self, serial): """returs true if player with serial is in position""" return serial in self.in_game and self.position == self.in_game.index(serial) def logIt(self, astr, prefix=" [D] "): """a little helper function to log output""" self.protocol.logIt(astr, prefix=prefix) def updateSeats(self, seats): """update seat information""" for index, (old, new) in enumerate(zip(self.seats, seats)): if old == 0 and new != 0: self.addPlayer(index, new) elif old != 0 and new == 0: self.removePlayer(index) elif old != new: self.removePlayer(index) self.addPlayer(index, new) self.logIt("warning idx %s, old %s, new %s" % (index, old, new)) def addPlayer(self, index, serial): """Add player to this table""" self.seats[index] = serial # Request more information about this player if serial == self.avatar.serial: self.players[index] = self.avatar else: self.protocol.sendPacket(networkpackets.PacketPokerGetUserInfo(serial=serial)) def removePlayer(self, index): """remove player from this table""" serial = self.seats[index] self.seats[index]=0 if serial in self.players: del self.players[serial] def updatePlayer(self, player_info): """update general palyer information (we requested them in addPlayer)""" player = self._get_or_create_player(**player_info) player.update(player_info) def updatePlayerChips(self, serial, chips, bet): """update players chips""" player = self._get_or_create_player(serial=serial) return player.updateChips(chips, bet) def updatePlayerCards(self, serial, cards): """update players cards""" player = self._get_player(serial) player.updateCards(cards) def rebuy(self, serial, amount): """update money state of player because a rebuy happend""" player = self._get_player(serial) player.rebuy(amount) def _reset_players(self): """reset player states""" for player in self.players.values(): player.reset() def highestBetNotFold(self): """returns the highest bet of all players that are not fold""" return max([0]+[p._bet for p in self.players.values() if p.serial in self.in_game and p.notFold()]) def inSmallBlindPosition(self): """returns True if the player in position is in small_blind position""" return len(self.in_game) > 0 and ((self.dealer + 1) % len(self.in_game)) == self.position def bigBlind(self): """returns the big_blind of the current table""" return self.big_blind or 0 def doBuyIn(self): """actually request a buy_in""" self.protocol.sendPacket(networkpackets.PacketPokerBuyIn(amount=self.max_buy_in, **self._serial_and_game_id)) self.protocol.sendPacket(networkpackets.PacketPokerAutoBlindAnte(**self._serial_and_game_id)) def doRebuy(self, amount): """actually request a rebuy""" self.protocol.sendPacket(networkpackets.PacketPokerRebuy(amount=amount, **self._serial_and_game_id)) def doSit(self): """actually request a sit""" self.protocol.sendPacket(networkpackets.PacketPokerSit(**self._serial_and_game_id)) def doSitOut(self): """actually request a sitout""" self.protocol.sendPacket(networkpackets.PacketPokerSitOut(**self._serial_and_game_id)) def doQuit(self): """actually request a table quit""" self.protocol.sendPacket(networkpackets.PacketPokerTableQuit(**self._serial_and_game_id)) def doFold(self): """actually request a fold""" self.protocol.sendPacket(networkpackets.PacketPokerFold(**self._serial_and_game_id)) def doCheck(self): """actually request a check""" self.protocol.sendPacket(networkpackets.PacketPokerCheck(**self._serial_and_game_id)) def doCall(self): """actually request a call""" self.protocol.sendPacket(networkpackets.PacketPokerCall(**self._serial_and_game_id)) def doAllIn(self): """actually raise all chips""" self.doRaise(self.avatar.getChips()) def doRaise(self, amount): """ actually request a raise by a given amount. WARNING: If the amount you requested is too low, the raise will be accepted but the minimum amount to raise will be used instead. You will be informend about the amount that is used to raise. """ self.protocol.sendPacket(networkpackets.PacketPokerRaise(amount=amount, **self._serial_and_game_id)) def explain(self, packet, state): """packets that might be interesting for the game will be handled here""" def handlePacketPokerBuyInLimits(packet): self.max_buy_in = packet.max self.min_buy_in = packet.min def handlePacketPokerSeats(packet): return self.updateSeats(packet.seats) def handlePacketPokerPlayerInfo(packet): self.updatePlayer(packet.__dict__) def handlePacketPokerPlayerChips(packet): return self.updatePlayerChips(packet.serial, chips=packet.money, bet=packet.bet) def handlePacketPokerPlayerArrive(packet): self.updatePlayer(packet.__dict__) def handlePacketPokerPlayerLeave(packet): self.removePlayer(packet.seat) def handlePacketPokerSit(packet): self._get_player(packet.serial).sit() def handlePacketPokerSitOut(packet): self._get_player(packet.serial).sitOut() def handlePacketPokerRebuy(packet): assert self.id == packet.game_id self.rebuy(packet.serial, packet.amount) def handlePacketPokerInGame(packet): assert self.id == packet.game_id self.in_game = packet.players def handlePacketPokerPosition(packet): assert self.id == packet.game_id self.position = packet.position def handlePacketPokerStart(packet): assert self.id == packet.game_id self.reset() self.hand_serial = packet.hand_serial def handlePacketPokerDealer(packet): assert self.id == packet.game_id # assert self.dealer == packet.previous_dealer self.dealer = packet.dealer def handlePacketPokerPlayerCards(packet): self.updatePlayerCards(packet.serial, packet.cards) if packet.serial == self.avatar.serial: self.logIt("You got %r" % self._cards_to_string(packet.cards)) def handlePacketPokerBoardCards(packet): self.board_cards = packet.cards def handlePacketPokerRaise(packet): self._get_player(packet.serial).bet(packet.amount) def handlePacketPokerCall(packet): player = self._get_player(packet.serial) highestbet = self.highestBetNotFold() bigb =self.bigBlind() if self._game_state == GAME_STATE_PRE_FLOP and not self.inSmallBlindPosition() else 0 # import rpdb2; rpdb2.start_embedded_debugger("haha") self.logIt("%r, %r" % (highestbet,bigb)) amount = min( max(highestbet,bigb) - player._bet, player.money ) player.bet(amount) def handlePacketPokerState(packet): self._game_state = packet.string def handlePacketPokerBlind(packet): self._get_player(packet.serial).bet(packet.amount) try: handle = locals()["handle"+packet.__class__.__name__] return handle(packet) except KeyError: # self.logIt(" explain cant handle : %r" % packet.__class__.__name__) return True except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() self.logIt(packet.__class__.__name__, prefix=" EEE handle failed: ") for exline in traceback.format_exception(exc_type, exc_value, exc_traceback): for line in exline.split('\n'): self.logIt(str(line), prefix=" EEE ") def _cards_to_string(self, cards): """return a string for cards in a human readable way""" return repr(self._eval.card2string(map(lambda x: x & 63, cards)))\ #.lower().replace("h", u"\u2761").replace("s", u"\u2660").replace("c", u"\u2663").replace("d", u"\u2662") def _get_or_create_player(self, serial, seat=None, **player_info): """returns the player with the serial, the player will be created if it does not exist yet""" # serial = player_info['serial'] # seat = player_info['seat'] if seat and self.seats[seat] != 0 and serial != self.seats[seat]: self.logIt("%s is allready on seat %s, cleared" % (self.seats[seat], seat)) del self.players[self.seats[seat]] self.seats[seat] = serial if serial not in self.players: self.players[serial] = Player(serial=serial, seat=seat, **player_info) return self.players[serial] def _get_player(self, serial): """returns the player, raises an IndexError if it does not exist""" return self.players[serial] def _log_players(self): """ log player informations """ self.logIt("Players:") for player in self.players.itervalues(): self.logIt(player._player_info()) self.logIt("") def getDebugLines(self): """returns a list of debug lines (yellow box)""" return self._get_table_info() + self._get_avatar_info() + self._get_player_info() @catcher def _get_table_info(self): """returns a list of table informations""" highestbet = self.highestBetNotFold(), bigb =self.bigBlind() if self._game_state == GAME_STATE_PRE_FLOP and not self.inSmallBlindPosition() else 0 return ["blinds: small:%r big:%r" % (self.small_blind, self.big_blind), "buy_ins: min:%r max:%r" % (self.min_buy_in, self.max_buy_in), "bs: %r" % self.betting_structure, "highestbet = %r" % highestbet, "bigb = %r" % bigb,] @catcher def _get_player_info(self): """returns a list with player informations for all players""" return [player._player_info() for player in self.players.values()] @catcher def _get_avatar_info(self): """returns informations of the avatar that is currently logged in""" retvals = [] if self.avatar.cards: retvals.append("hand: " + self._cards_to_string(self.avatar.cards)) if self.board_cards: retvals.append("board: " + self._cards_to_string(self.board_cards)) if self.avatar.cards: best_hand = self._eval.best_hand("hi", self.avatar.getCards() + self.getBoardCards()) desc = best_hand.pop(0) retvals.append("%s: %s" % (desc, self._cards_to_string(best_hand))) return retvals