if __name__ == '__main__':
from poker_hand_import import print_hand,shuffle_deck,test,summarize,card_name,short_name,print_short_hand
#A couple lists describing the cards of a hand
# The ranks are listed so the highest card will be easy to identify
suits = ['Clubs','Diamonds','Hearts','Spades']
ranks = ['Ace', 'King', 'Queen', 'Jack', 'Ten', 'Nine', 'Eight',
'Seven', 'Six', 'Five', 'Four', 'Three', 'Two']
types = ['Straight Flush','Four of a Kind','Full House','Flush',
'Straight','Three of a Kind','Two Pair','Pair','Nothing']
# The Student Work for this assignment is Below This Line
# Here are some functions to help categorize a hand
def count_ranks(hand):
'''Returns sequence 2,3,4,5,6,7,8,9,Ten,Jack,Queen,King,Ace'''
'''Returns the number of twos, threes, etc. in a hand'''
counts = [0]*13 # initialize counts for all 13 ranks
for card in hand:
counts[card[0]] += 1
return counts
def longest_suit(hand):
'''Returns the longest subset of a hand in the same suit
Five cards in one suit counts as a Flush'''
suit_sets = [[],[],[],[]] # four empty lists
for card in hand:
suit_sets[card[1]].append(card)
max_length = max([len(list) for list in suit_sets])
for list in suit_sets:
if len(list) == max_length:
answer = list
return answer
def contains_straight(counts):
'''identifies whether the hand is a straight
if so, returns the rank of the high card in the straight,
otherwise simply returns False'''
hand = sorted(counts)
sub = 1
temp = None
tmp = 0
for index in range(1, len(hand)):
if hand[index][0] - hand[index - 1][0] != sub:
if hand[index][0] - hand[index - 1][0] == 9 and hand[index - 1][0] == 0:
tmp = 1
continue
temp = 1
break
if not temp:
if tmp == 1:
return hand[1][0]
return hand[0][0]
return False
def evaluate_hand(hand):
'''Categorizes a hand of cards
Returns a tuple, containing these two features:
The kind of hand (an element listed in _types_ above
The numeric rank of card to further describe the hand, which may be
a tuple representing two ranks for Full House or Two Pair
a rank that appears four times in Four of a Kind
a rank that appears three times in Three of a Kind
a rank of a Pair (when there is only one pair)
a rank at the top of a Straight, Flush, or Other'''
type = types[8]
rank = sorted(hand)[0][0]
if contains_straight(hand) and len(longest_suit(hand)) == 5:
type = types[0]
rank = contains_straight(hand)
elif contains_straight(hand) and len(longest_suit(hand)) < 5:
type = types[4]
rank = contains_straight(hand)
elif not contains_straight(hand):
if len(longest_suit(hand)) == 5:
type = types[3]
rank = sorted(hand)[0][0]
else:
counts = count_ranks(hand)
same_cards_num = max(counts)
if same_cards_num == 4:
type = types[1]
rank = counts.index([count for count in counts if count == 4][0])
elif same_cards_num == 3:
if 2 in counts:
type = types[2]
threes_rank = counts.index([count for count in counts if count == 3][0])
twos_rank = counts.index([count for count in counts if count == 2][0])
rank = (threes_rank, twos_rank)
else:
type = types[5]
rank = counts.index([count for count in counts if count == 3][0])
else:
if counts.count(2) == 2:
twos_index = []
type = types[6]
for index in range(len(counts)):
if counts[index] == 2:
twos_index.append(index)
rank = (twos_index[0], twos_index[1])
elif counts.count(2) == 1:
type = types[7]
rank = counts.index([count for count in counts if count == 2][0])
return type, rank
def better_hand(hand1,hand2):
'''Determines which of two hands is better than the other
Returns None if they are of equal value'''
kind1,rank1 = evaluate_hand(hand1)
kind2,rank2 = evaluate_hand(hand2)
better_hand_str = ''
if types.index(kind1) < types.index(kind2):
return hand1
elif types.index(kind1) > types.index(kind2):
return hand2
else:
if type(rank1)== tuple and type(rank2) == tuple:
if rank1[0] == rank2[0]:
if rank1[1] > rank2[1]:
return hand1
else:
return better_hand_with_same_kind_and_rank(hand1,hand2,kind1)
elif rank1[0] > rank2[0]:
return hand1
else:
return hand2
else:
if rank1 < rank2:
return hand1
elif rank1 > rank2:
return hand2
else:
return better_hand_with_same_kind_and_rank(hand1,hand2,kind1)
return []
def better_hand_with_same_kind_and_rank(hand1, hand2, kind):
hand_1 = sorted(hand1)
hand_2 = sorted(hand2)
for index in range(0, len(hand_1)):
if hand_1[index][0] > hand_2[index][0]:
return hand_2
elif hand_1[index][0] < hand_2[index][0]:
return hand_1
else:
if index == len(hand_1)-1:
return hand_1
if __name__ == '__main__':
for i in range(1):
test()
# Poker Hand Evaluator
# Given a set of cards representing a poker hand,
# identifies the nature of that hand.
import random
from poker_hand_work import evaluate_hand,better_hand
# A couple lists describing the cards of a hand
# The ranks are listed so the highest card will be easy to identify
suits = ['Clubs','Diamonds','Hearts','Spades']
ranks = ['Ace', 'King', 'Queen', 'Jack', 'Ten', 'Nine', 'Eight',
'Seven', 'Six', 'Five', 'Four', 'Three', 'Two']
types = ['Straight Flush','Four of a Kind','Full House','Flush',
'Straight','Three of a Kind','Two Pair','Pair','Nothing']
# Some descriptive items
def card_name(card):
'''Returns the name of a card, given its coded rank and suit'''
return ranks[card[0]] + ' of ' + suits[card[1]]
def print_hand(hand):
'''Prints the long names of the cards in a hand'''
if hand is None:
print('No winning hand')
return
for card in sorted(hand):
print(card_name(card),end=' ')
print()
def short_name(card):
'''Identifies a card by a very brief name'''
return 'AKQJT98765432'[card[0]] + 'CDHS'[card[1]]
def print_short_hand(hand):
'''Prints the short names of the cards in a hand'''
for card in sorted(hand):
print(short_name(card),end=' ')
def summarize(hand):
if hand is None:
print('No winning hand')
return
hand_type,rank = evaluate_hand(sorted(hand))
print_short_hand(hand)
print('--',hand_type,end=' ')
if hand_type == 'Full House':
print(f'{ranks[rank[0]]}s over {ranks[rank[1]]}s')
elif hand_type == 'Two Pair':
print(f'{ranks[rank[0]]}s and {ranks[rank[1]]}s')
elif hand_type in ['Four of a Kind','Three of a Kind','Pair']:
print(ranks[rank])
else:
print(f'{ranks[rank]} high')
# Randomly generate hands of rare types
def random_flush():
'''Creates a flush, that may or may not be a straight'''
suit = random.randint(0,3)
hand = []
for rank in random.sample(range(13),5):
hand.append( (rank,suit) )
return sorted(hand)
def random_straight():
'''Creates a straight, that may or may not be a flush'''
suit = random.randint(0,3)
other = random.randint(0,3)
first = random.randint(-1,8)
if first == -1: # Create Ace-low straight
first = 8
hand = [ (0,other) ]
else:
hand = [ (first,other) ]
for i in range(1,5):
hand.append( (first+i,suit) )
return sorted(hand)
def shuffle_deck():
'''Returns a complete deck of cards, shuffled; each card is a tuple'''
deck = []
for suit in range(4):
for rank in range(13):
deck.append( (rank, suit) )
random.shuffle(deck)
return deck
# Here a few tests to start with:
def test():
deck = shuffle_deck()
for j in range(0,40,10):
summarize(deck[j:j+5])
summarize(deck[j+5:j+10])
print_hand(better_hand(sorted(deck[j:j+5]),sorted(deck[j+5:j+10])))
hand1 = random_straight()
hand2 = random_straight()
summarize(hand1)
summarize(hand2)
print_hand(better_hand(hand1,hand2))
hand1 = random_flush()
hand2 = random_flush()
summarize(hand1)
summarize(hand2)
print_hand(better_hand(hand1,hand2))
运行结果: