Limnoria/others/poker.py
2004-10-15 03:35:06 +00:00

130 lines
3.8 KiB
Python

###
# Copyright (c) 2004, Jeremiah Fincher
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions, and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions, and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author of this software nor the name of
# contributors to this software may be used to endorse or promote products
# derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###
# Constants.
S = 's'
C = 'c'
H = 'h'
D = 'd'
class Rank(int):
def __str__(self):
if 2 <= self <= 10:
return str(self)
elif self == 11:
return 'J'
elif self == 12:
return 'Q'
elif self == 13:
return 'K'
elif self == 14:
return 'A'
elif self == 1:
return 'A'
A = Rank(14)
K = Rank(13)
Q = Rank(12)
J = Rank(11)
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __str__(self):
return '%s%s' % (self.rank, self.suit)
__repr__ = __str__
def __cmp__(self, other):
cmp(self.rank, other.rank)
class Hand(object):
def __init__(self, cards):
self.cards = cards
def cmpVal(self):
self.cards.sort()
self.cards.reverse() # High before low.
first = 0
if self.isFlush() and self.isStraight():
first = 8
elif self.isFourOfAKind():
first = 7
elif self.isFullHouse():
first = 6
elif self.isFlush():
first = 5
elif self.isStraight():
first = 4
elif self.isThreeOfAKind():
first = 3
elif self.isTwoPair():
first = 2
elif self.isPair():
first = 1
return (first, self.cards)
# These assume self.cards is sorted.
def isFlush(self):
return all(lambda s: s == self.cards[0].suit, self.cards)
def isStraight(self):
diffs = [x-y for (x, y) in window(self.cards, 2)]
return all(lambda x: x == 1, diffs)
def _isSomeOfAKind(self, i):
def eq(x, y):
return x == y
for cards in window(self.cards, i):
if all(None, map(eq, window(cards, 2))):
return True
return False
def isFourOfAKind(self):
return _isSomeOfAKind(4)
def isThreeOfAKind(self):
return _isSomeOfAKind(3)
def isPair(self):
return _isSomeOfAKind(2)
def isFullHouse(self):
pass
def __cmp__(self, other):
cmp(self.cmpVal(), other.cmpVal())
deck = []
for suit in [S, H, C, D]:
for rank in [A, K, Q, J] + range(2, 11):
deck.append(Card(rank, suit))