3-Card Poker
Imagine a game, similar to many poker games, in which each player is dealt 3 cards, and the player with the higher value hand wins the draw. We play this game with a 40-card deck: 4 cards
of each value 0-9, and for simplicity, unsuited.
Hand rank is as follows (highest to lowest):
- Three of a kind: All three cards have the same value.
- One pair: Two cards of the same value.
- High card: The highest value card in your hand.
Cards are valued (highest to lowest)9, 8,… 0.
If two players have the same ranked hand, then the rank made of the highest value wins, for example, a pair of 9’s beats a pair of 2’s, and a high card 9 beats a high card 2. If, however, both
players have a pair of 8’s, then the player with the higher value third card wins. For the high card case, if the second cards also tie, then the third card is considered, and if this card is also tied,
then the hand results in a draw.
Consider the following five dealt hands:
from collections import Counter
suites = {
'C' : "Club",
'D' : "Diamond",
'H' : "Heart",
'S' : "Spade",
}
values = {
'2' : 2,
'3' : 3,
'4' : 4,
'5' : 5,
'6' : 6,
'7' : 7,
'8' : 8,
'9' : 9,
'10' : 0,
'A' : 1,
}
class InvalidCard(Exception): # change to “hand has more than 3 cards”
pass
class Card(object):
def __init__(self, card='AC'):
if type(card) != str or len(card) != 2:
raise InvalidCard
self.value = values[card[0]]
self.suite = suites[card[1]]
self.card = card
def __unicode__(self):
return "suite: %s value:%s" % (self.suite, self.value)
class InvalidHand(Exception): # change to “hand has more than 3 cards”
pass
class Hand(object):
def __init__(self, cards = []):
if type(cards) != list or len(cards) != 5 or \
not all(type(c) == Card for c in cards):
raise InvalidHand
self.cards = cards
self.get_rank()
def print_values(self):
return "{} {} {} {}".format(self.card_values(),
self.cards_by_hand,
"%2d" % self.rank,
self.combination)
def values(self):
return sorted([c.value for c in self.cards])
def values_desc(self):
return sorted([c.value for c in self.cards], reverse = True)
def card_values(self):
return [c.card for c in self.cards]
def suites(self):
return [c.suite for c in self.cards]
def get_rank(self):
values = self.values()
counter_values = Counter(self.values())
counter_suites = Counter(self.suites())
self.cards_by_hand = self.values_desc()
if len(counter_suites.keys()) == 1 and set(values) == set(range(10, 15)):
self.rank = 1
elif len(counter_values.keys()) == 3:
if 3 in counter_values.values():
self.rank = 7
self.combination = "Three Of A Kind"
if not (self.cards_by_hand[0] == self.cards_by_hand[2]) :
if not(self.cards_by_hand[1] == self.cards_by_hand[2]):
self.cards_by_hand = self.cards_by_hand[2:] + self.cards_by_hand[:2]
else:
self.cards_by_hand = self.cards_by_hand[1:4] + self.cards_by_hand[:1] + self.cards_by_hand[4:]
elif len(counter_values.keys()) == 4:
self.rank = 9
self.combination = "Pair"
if self.cards_by_hand[1] == self.cards_by_hand[2]:
self.cards_by_hand = self.cards_by_hand[1:3] + self.cards_by_hand[:1] + self.cards_by_hand[3:]
elif self.cards_by_hand[2] == self.cards_by_hand[3]:
self.cards_by_hand = self.cards_by_hand[2:4] + self.cards_by_hand[:2] + self.cards_by_hand[4:]
elif self.cards_by_hand[3] == self.cards_by_hand[4]:
self.cards_by_hand = self.cards_by_hand[3:] + self.cards_by_hand[:3]
else:
self.rank = 10
self.combination = "High Card"
class InvalidGame(Exception):
pass
class Game(object):
def __init__(self, hands = [], game_string = ""):
if game_string:
card_strings = game_string.split()
cards = [Card(string) for string in card_strings]
hands = [Hand(cards[:5]), Hand(cards[5:])]
elif type(hands) != list or len(hands) != 2 \
or not all(type(h) == Hand for h in hands):
raise InvalidGame
self.hands = hands
def compare_hands(self, hands = []):
if not hands:
hands = self.hands
winner = None
if hands[0].rank != hands[1].rank:
winner = 0 if hands[0].rank < hands[1].rank else 1
else:
winner = 0 if hands[0].cards_by_hand > hands[1].cards_by_hand else 1
print ("%s\n%s\nwinner: %s\n" %(hands[0].print_values(), hands[1].print_values(), str(winner)))
return winner
def construct_game(string):
game = Game(game_string = string)
return game.compare_hands()
def main():
wins_player_A = 0
with open("poker.txt", "r") as f:
games = f.read().split("\n")
for game in games:
if game:
wins_player_A += ((construct_game(game) + 1 ) % 2)
print(wins_player_A)
if __name__ == "__main__":
main()