From 84b90a23ff0945f42e98f4732a1985d8f8e93df6 Mon Sep 17 00:00:00 2001 From: Brian Sherson Date: Sun, 8 Sep 2013 10:15:04 -0700 Subject: Fixing bug in core module --- poker.py | 370 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 202 insertions(+), 168 deletions(-) (limited to 'poker.py') diff --git a/poker.py b/poker.py index a4b8918..9255548 100644 --- a/poker.py +++ b/poker.py @@ -1,184 +1,218 @@ #!/usr/bin/python -import re, os, random, string, itertools +import re +import os +import random +import string +import itertools + +spade = '\xe2\x99\xa0' +heart = '\xe2\x99\xa5' +diamond = '\xe2\x99\xa6' +club = '\xe2\x99\xa3' +faces = ["A"]+range(2, 11)+list("JQKA") +suits = [(spade, 1), (club, 1), (heart, 4), (diamond, 4)] +handsmapping = ["High card", "One pair", "Two pair", "Three of a kind", "Straight", "Flush", "Full house", "Four of a kind", "Straight flush", "Royal flush"] -spade='\xe2\x99\xa0' -heart='\xe2\x99\xa5' -diamond='\xe2\x99\xa6' -club='\xe2\x99\xa3' -faces=["A"]+range(2,11)+list("JQKA") -suits=[(spade, 1), (club, 1), (heart, 4), (diamond, 4)] -handsmapping=["High card", "One pair", "Two pair", "Three of a kind", "Straight", "Flush", "Full house", "Four of a kind", "Straight flush", "Royal flush"] class Game(object): - def __init__(self): - self.deck=deck=list(itertools.product(xrange(1,14), xrange(4))) - random.shuffle(deck) - random.shuffle(deck) - random.shuffle(deck) - random.shuffle(deck) - random.shuffle(deck) - self.status=0 - self.players=[] - self.hands={} - self.waiting=None + def __init__(self): + self.deck = deck = list(itertools.product(xrange(1, 14), xrange(4))) + random.shuffle(deck) + random.shuffle(deck) + random.shuffle(deck) + random.shuffle(deck) + random.shuffle(deck) + self.status = 0 + self.players = [] + self.hands = {} + self.waiting = None + + class Poker(object): - def __init__(self): - self.games={} - def onRecv(self, IRC, line, data): - if data==None: return - (origin, ident, host, cmd, target, params, extinfo)=data - #print data - if len(target) and target[0]=="#" and cmd=="PRIVMSG": - channel=IRC.channel(target) - user=IRC.user(origin) - matches=re.findall("^!poker (\\S+)(?:\\s+(.*))?$",extinfo) - if matches: - cmd, param=matches[0] - if cmd=="newgame": - if all([m not in channel.modes.keys() or user not in channel.modes[m] for m in "qao"]): - channel.msg("%s: You are not operator."%origin) - elif channel in self.games.keys(): - channel.msg("%s: There is already a game going on in this channel."%origin) - else: - self.games[channel]=Game() - channel.msg("A new poker game has started. Type \x02!poker sit\x02 to join.") - elif cmd=="sit": - if channel not in self.games.keys(): - channel.msg("%s: There is no game going on in this channel."%origin) - elif self.games[channel].status!=0: - channel.msg("%s: Cannot join the game at this time."%origin) - elif user in self.games[channel].players: - channel.msg("%s: You are already in the game."%origin) - elif len(self.games[channel].players)>=8: - channel.msg("%s: This game is full."%origin) - else: - self.games[channel].players.append(user) - channel.msg("%s: Welcome to the game."%origin) - elif cmd=="deal": - if all([m not in channel.modes.keys() or user not in channel.modes[m] for m in "qao"]): - channel.msg("%s: You are not operator."%origin) - elif channel not in self.games.keys(): - channel.msg("%s: There is no game going on in this channel."%origin) - elif len(self.games[channel].players)==0: - channel.msg("%s: Nobody has sat yet."%origin) - elif self.games[channel].status>0: - channel.msg("%s: The cards have already been dealt."%origin) - else: - channel.me("deals poker hands to %s"%(string.join([user.nick for user in self.games[channel].players],", "))) - P=len(self.games[channel].players) - for user in self.games[channel].players: - hand=list(self.games[channel].deck[0:5*P:P]) - del self.games[channel].deck[0:5*P:P] - self.games[channel].hands[user]=hand - user.notice("Your poker hand is: %s"%(string.join(["\x03%d,0\x02%s%s\x0f"%(suits[s][1], faces[f], suits[s][0]) for (f,s) in hand],", "))) - self.games[channel].status=1 - self.games[channel].waiting=self.games[channel].players[0] - channel.msg("The cards have been dealt.") - channel.msg("%s: Do you wish to draw any cards? Type \x02!poker draw n1,n2,...\x02, where n1,n2,... is a list of cards \x02by index\x02 you wish to draw (0 for first card, 1 for second, etc...). Empty list means you wish to keep all cards."%self.games[channel].waiting.nick) - elif cmd=="draw": - if channel not in self.games.keys(): - channel.msg("%s: There is no game going on in this channel."%origin) - elif user not in self.games[channel].players: - channel.msg("%s: You are not in this game."%origin) - elif self.games[channel].status!=1: - channel.msg("%s: We are not exchanging cards yet."%origin) - elif self.games[channel].waiting!=user: - channel.msg("%s: It is not your turn to draw cards yet."%origin) - else: - if param and any([card not in "01234" for card in param.split(",")]): - channel.msg("%s: I could not understand your request."%origin) - else: - if param=="": - channel.msg("%s is keeping all cards."%origin) - discards=[] - else: - discards=[] - #print "Param",param - for cardid in param.split(","): - card=self.games[channel].hands[user][int(cardid)] - #print "Discarding ",card - if card not in discards: discards.append(card) - for card in discards: self.games[channel].hands[user].remove(card) - channel.msg("%s is exchanging %d card%s."%(origin, len(discards), "s" if len(discards)>1 else "")) - self.games[channel].hands[user].extend(self.games[channel].deck[:len(discards)]) - del self.games[channel].deck[:len(discards)] - self.games[channel].deck.extend(discards) - user.notice("Your new poker hand is: %s"%(string.join(["\x03%d,0\x02%s%s\x0f"%(suits[s][1], faces[f], suits[s][0]) for (f,s) in self.games[channel].hands[user]],", "))) - k=self.games[channel].players.index(user) - if k2: - channel.msg("The winners are %s, and %s. A %d-way tie. Well played, gentlemen!"%(string.join(winners[:-1], ", "), winners[-1], len(winners))) - elif len(winners)==2: - channel.msg("The winners are %s and %s. A tie. Well played, gentlemen!"%tuple(winners)) - else: - channel.msg("The winner is %s. Well played, gentlemen!"%winners[0]) - del self.games[channel] - #matches=re.findall("^!shuffle(?:\\s+([\\d]+))?$",extinfo) - #if matches: - #if matches[0]: shuffles=int(matches[0]) - #else: shuffles=1 - #if shuffles>1000: - #channel.msg("Get real, %s!"%origin) - #return - #for s in xrange(shuffles): random.shuffle(deck) - #channel.me("shuffles the deck %d time%s."%(shuffles, "s" if shuffles>1 else "")) + def __init__(self): + self.games = {} + + def onRecv(self, IRC, line, data): + if data is None: + return + (origin, ident, host, cmd, target, params, extinfo) = data + #print data + if len(target) and target[0] == "#" and cmd == "PRIVMSG": + channel = IRC.channel(target) + user = IRC.user(origin) + matches = re.findall("^!poker (\\S+)(?:\\s+(.*))?$", extinfo) + if matches: + cmd, param = matches[0] + if cmd == "newgame": + if all([m not in channel.modes.keys() or user not in channel.modes[m] for m in "qao"]): + channel.msg("%s: You are not operator."%origin) + elif channel in self.games.keys(): + channel.msg("%s: There is already a game going on in this channel."%origin) + else: + self.games[channel] = Game() + channel.msg("A new poker game has started. Type \x02!poker sit\x02 to join.") + elif cmd == "sit": + if channel not in self.games.keys(): + channel.msg("%s: There is no game going on in this channel."%origin) + elif self.games[channel].status != 0: + channel.msg("%s: Cannot join the game at this time." % + origin) + elif user in self.games[channel].players: + channel.msg("%s: You are already in the game."%origin) + elif len(self.games[channel].players) >= 8: + channel.msg("%s: This game is full."%origin) + else: + self.games[channel].players.append(user) + channel.msg("%s: Welcome to the game."%origin) + elif cmd == "deal": + if all([m not in channel.modes.keys() or user not in channel.modes[m] for m in "qao"]): + channel.msg("%s: You are not operator."%origin) + elif channel not in self.games.keys(): + channel.msg("%s: There is no game going on in this channel."%origin) + elif len(self.games[channel].players) == 0: + channel.msg("%s: Nobody has sat yet."%origin) + elif self.games[channel].status > 0: + channel.msg("%s: The cards have already been dealt." % + origin) + else: + channel.me("deals poker hands to %s"%(string.join([user.nick for user in self.games[channel].players], ", "))) + P = len(self.games[channel].players) + for user in self.games[channel].players: + hand = list(self.games[channel].deck[0:5*P:P]) + del self.games[channel].deck[0:5*P:P] + self.games[channel].hands[user] = hand + user.notice("Your poker hand is: %s"%(string.join(["\x03%d,0\x02%s%s\x0f"%(suits[s][1], faces[f], suits[s][0]) for (f, s) in hand], ", "))) + self.games[channel].status = 1 + self.games[channel].waiting = self.games[ + channel].players[0] + channel.msg("The cards have been dealt.") + channel.msg("%s: Do you wish to draw any cards? Type \x02!poker draw n1,n2,...\x02, where n1,n2,... is a list of cards \x02by index\x02 you wish to draw (0 for first card, 1 for second, etc...). Empty list means you wish to keep all cards."%self.games[channel].waiting.nick) + elif cmd == "draw": + if channel not in self.games.keys(): + channel.msg("%s: There is no game going on in this channel."%origin) + elif user not in self.games[channel].players: + channel.msg("%s: You are not in this game."%origin) + elif self.games[channel].status != 1: + channel.msg("%s: We are not exchanging cards yet." % + origin) + elif self.games[channel].waiting != user: + channel.msg("%s: It is not your turn to draw cards yet."%origin) + else: + if param and any([card not in "01234" for card in param.split(",")]): + channel.msg("%s: I could not understand your request."%origin) + else: + if param == "": + channel.msg("%s is keeping all cards."%origin) + discards = [] + else: + discards = [] + #print "Param",param + for cardid in param.split(","): + card = self.games[channel].hands[user][int(cardid)] + #print "Discarding ",card + if card not in discards: + discards.append(card) + for card in discards: + self.games[channel].hands[user].remove(card) + channel.msg("%s is exchanging %d card%s."%(origin, len(discards), "s" if len(discards) > 1 else "")) + self.games[channel].hands[user].extend(self.games[channel].deck[:len(discards)]) + del self.games[channel].deck[:len(discards)] + self.games[channel].deck.extend(discards) + user.notice("Your new poker hand is: %s"%(string.join(["\x03%d,0\x02%s%s\x0f"%(suits[s][1], faces[f], suits[s][0]) for (f, s) in self.games[channel].hands[user]], ", "))) + k = self.games[channel].players.index(user) + if k < len(self.games[channel].players)-1: + self.games[channel].waiting = self.games[channel].players[k+1] + channel.msg("%s: Do you wish to draw any cards? Type \x02!poker draw n1,n2,...\x02, where n1,n2,... is a list of cards \x02by index\x02 you wish to draw (0 for first card, 1 for second, etc...). Empty list means you wish to keep all cards."%self.games[channel].waiting.nick) + else: + self.games[channel].waiting = None + channel.msg("Exchanges done! Waiting for dealer to type \x02!poker show\x02.") + self.games[channel].status = 2 + elif cmd == "show": + if all([m not in channel.modes.keys() or user not in channel.modes[m] for m in "qao"]): + channel.msg("%s: Access denied."%origin) + elif channel not in self.games.keys(): + channel.msg("%s: There is no game going on in this channel."%origin) + elif self.games[channel].status != 2: + channel.msg("%s: We are not ready to show cards." % + origin) + else: + results = [] + for user in self.games[channel].players: + hand = self.games[channel].hands[user] + t = evalhand(hand) + channel.msg("%s\xe2\x80\x99s poker hand is: %s. A \x02%s\x02."%(user.nick, string.join(["\x03%d,0\x02%s%s\x0f"%(suits[s][1], faces[f], suits[s][0]) for (f, s) in hand], ", "), handsmapping[t[0]])) + results.append((t, user)) + results.sort(reverse=True) + top = results[0][0] + winners = [user.nick for (t, user) + in results if t == top] + if len(winners) > 2: + channel.msg("The winners are %s, and %s. A %d-way tie. Well played, gentlemen!"%(string.join(winners[:-1], ", "), winners[-1], len(winners))) + elif len(winners) == 2: + channel.msg("The winners are %s and %s. A tie. Well played, gentlemen!"%tuple(winners)) + else: + channel.msg("The winner is %s. Well played, gentlemen!"%winners[0]) + del self.games[channel] + #matches=re.findall("^!shuffle(?:\\s+([\\d]+))?$",extinfo) + #if matches: + #if matches[0]: shuffles=int(matches[0]) + #else: shuffles=1 + #if shuffles>1000: + #channel.msg("Get real, %s!"%origin) + #return + #for s in xrange(shuffles): random.shuffle(deck) + #channel.me("shuffles the deck %d time%s."%(shuffles, "s" if shuffles>1 else "")) + def evalhand(hand): - facevalues=[face for (face,suit) in hand] - facevalues.sort(reverse=True) - suits=[suit for (face,suit) in hand] + facevalues = [face for (face, suit) in hand] + facevalues.sort(reverse=True) + suits = [suit for (face, suit) in hand] - duplicities=[(facevalues.count(k),k) for k in xrange(1,14)] - duplicities.sort(reverse=True) - counts=[count for (count,k) in duplicities] - faces=[k for (count,k) in duplicities] - ### Check for flush - if suits==[0]*5: flush=True - elif suits==[1]*5: flush=True - elif suits==[2]*5: flush=True - elif suits==[3]*5: flush=True - else: flush=False + duplicities = [(facevalues.count(k), k) for k in xrange(1, 14)] + duplicities.sort(reverse=True) + counts = [count for (count, k) in duplicities] + faces = [k for (count, k) in duplicities] + ### Check for flush + if suits == [0]*5: + flush = True + elif suits == [1]*5: + flush = True + elif suits == [2]*5: + flush = True + elif suits == [3]*5: + flush = True + else: + flush = False - ### Check for straight - if (max(counts)==1 and max(facevalues)-min(facevalues)==4) or counts==[1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]: straight=True - else: straight=False + ### Check for straight + if (max(counts) == 1 and max(facevalues)-min(facevalues) == 4) or counts == [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]: + straight = True + else: + straight = False - if flush and not straight: return (5,)+tuple(faces) - elif straight and not flush: return (4,)+tuple(faces) - elif flush and counts==[1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]: return (9,)+tuple(faces) - elif flush and straight: return (8,)+tuple(faces) + if flush and not straight: + return (5,)+tuple(faces) + elif straight and not flush: + return (4,)+tuple(faces) + elif flush and counts == [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]: + return (9,)+tuple(faces) + elif flush and straight: + return (8,)+tuple(faces) - if 3 in counts and 2 in counts: return (6,)+tuple(faces) + if 3 in counts and 2 in counts: + return (6,)+tuple(faces) - if 4 in counts: return (7,)+tuple(faces) + if 4 in counts: + return (7,)+tuple(faces) - if 3 in counts: return (3,)+tuple(faces) + if 3 in counts: + return (3,)+tuple(faces) - if counts.count(2)==2: return (2,)+tuple(faces) + if counts.count(2) == 2: + return (2,)+tuple(faces) - if 2 in counts: return (1,)+tuple(faces) + if 2 in counts: + return (1,)+tuple(faces) - return (0,)+tuple(faces) + return (0,)+tuple(faces) -- cgit v1.2.3