summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--poker.py370
1 files changed, 202 insertions, 168 deletions
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 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 __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)