纸牌游戏,比较两手hand的大小

题目要求:随机生成两手牌,并比较两手牌的大小,每手牌五张,扑克牌游戏

 

poker_hand_work.py

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_import.py

# 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))

 

 

运行结果:

纸牌游戏,比较两手hand的大小_第1张图片

纸牌游戏,比较两手hand的大小_第2张图片

你可能感兴趣的:(纸牌游戏,比较两手hand的大小)