社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

使用python识别直线、齐平和其他类别(从扑克中)

Sachin Sharma • 6 年前 • 1585 次点击  

我是Python的新手,从书本、论坛和开发人员那里学习。最近,我尝试在扑克程序中实现各种手排名类别。目标是计算概率,看看它是否符合理论扑克手概率?

Source: https://en.wikipedia.org/wiki/Poker_probability?oldformat=true

请在下面找到我迄今为止用来构建它的代码和逻辑。代码包含卡类和甲板类,它们一起实现使用的一组标准扑克牌,以及一个示例pytest测试函数test_xxx()。

到目前为止,我已经编写了hasonepair、hastwopairs、hasthreeofakind、hasfullhouse和hasfourofakind()函数,它工作得很好,但我正在努力实现直接、刷新和直接刷新。

有人能就如何处理直发、冲洗、皇家冲洗、直发病例提出建议或给出指导意见吗?此外,任何更新此代码的进一步建议都是很好的。


import random

SUITS = ["Clubs", "Diamonds", "Hearts", "Spades"]
RANKS = ["", "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"]

# here's two Python classes whose objects represent playing cards and decks thereof

class Card():
    """
    Represents a single playing card,
        whose rank internally is int _rank: 1..13 => "Ace".."King"
        and whose suit internally is int _suit 0..3 => "Clubs".."Spades"
    """

    def __init__(self, rank=1, suit=3): # this is the constructor!
        '''
        Initialize card with given int suit and int rank
        :param rank:
        :param suit:
        :return:
        '''
        self._rank = rank
        self._suit = suit

    def __str__(self): # this is the "stringifier"
        """
        Return the string name of this card:
        "Ace of Spades": translates int fields to strings
        :return:
        """

        # "Ace of Spades" is string for self._rank==1, self._suit==3

        toreturn = RANKS[self._rank] + " of " + SUITS[self._suit]

        return toreturn


class Deck():
    """
    Represents a deck of 52 standard playing cards,
        as a list of Card refs
    """

    def __init__(self): # constructor
        """
        Initialize deck: field _cards is list containing
            52 Card refs, initially
        :return: nothing
        """

        self._cards = []
        for rank in range(1, 14):
            for suit in range(4):
                c = Card(rank, suit) # create next Card with given value
                self._cards.append(c) # add it to this Deck

    def __str__(self):
        """
        "Stringified" deck: string of Card named,
        with \n for easier reading
        :return:
        """
        toreturn = ''

        # for index in range(len(self._cards)):
        #     self._cards[index]

        for c in self._cards:
            temp = str(c)  # temp is the stringified card
            toreturn = toreturn + temp + "\n"  # note \n at end

        return toreturn

    def shuffle(self):
        random.shuffle(self._cards)  # note random function to do this

    def dealCard(self):
        toreturn = self._cards.pop(0)  # get and remove top card from deck
        return toreturn

def buildDict(hand):
    dict = {}

    for card in hand:
        dict[card._rank] = dict.get(card._rank, 0) + 1


    return dict


def hasOnePair(dict):

    twocount = 0
    threecount = 0

    for v in dict.values():
        if v == 2:
            twocount += 1
        elif v == 3:
            threecount += 1

    if twocount==1 and threecount != 1:
        return True
    else:
        return False



def hasTwoPairs(dict):

    twocount1 = 0
    threecount1 = 0

    for v in dict.values():
        if v ==2:
            twocount1 += 1
        elif v == 3:
            threecount1 +=1

    if twocount1 == 2 and threecount1 != 1:
        return True
    else:
        return False



def hasThreeOfAKind(dict):


    twocount = 0
    threecount = 0

    for v in dict.values():
        if v == 2:
            twocount += 1
        elif v == 3:
            threecount += 1

    if twocount != 1 and threecount == 1:
        return True
    else:
        return False



def hasFullHouse(dict):

    twocount = 0
    threecount = 0

    for v in dict.values():
        if v == 2:
            twocount += 1
        elif v == 3:
            threecount += 1

    if twocount == 1 and threecount == 1:
        return True
    else:
        return False





def hasFourOfAKind(dict):

    fourcount = 0
    onecount = 0

    for v in dict.values():
        if v ==4:
            fourcount += 1
        elif v == 1:
            onecount +=1

    if fourcount == 1 and onecount == 1:
        return True
    else:
        return False


def hasStraight(hand):


    return False

def hasFlush(dict):


    return False

def hasStraightFlush(dict):

    return False

def hasRoyalFlush(dict):

    return False

def main():


    TRIALS = 1000  # int(input ("Input number of hands to test: "))

    hand = []  # list of Card in hand

    # accumulators for different counts

    onepairCount = 0
    twopairCount = 0
    threeCount = 0
    fourCount = 0
    fullHouseCount = 0
    StraightCount = 0



    for num in range(TRIALS):

        # create new Deck and shuffle
        d = Deck()
        d.shuffle()

        # initialize hand as empty list
        hand = []

        # deal top 5 cards of deck, adding to hand

        for count in range(5):
            hand.append(d.dealCard())


        # build the dictionary of card ranks in hand

        dict = buildDict(hand)



        # use dictionary to make hand checking easier

        if hasOnePair(dict):
            onepairCount += 1
        elif hasTwoPairs(dict):
            twopairCount += 1
        elif hasThreeOfAKind(dict):
            threeCount += 1
        elif hasFourOfAKind(dict):
            fourCount += 1
        elif hasFullHouse(dict):
            fullHouseCount += 1
        elif hasStraight(dict):
            StraightCount +=1

    # add more if needed...

    # print out results...

    print("Number of one pair hands is: ", onepairCount)
    print("% of hands: ", 100.0 * onepairCount / TRIALS)

    print("Number of two pair hands is: ", twopairCount)
    print("% of hands: ", 100.0 * twopairCount / TRIALS)


    print("Number of trips hand is: ", threeCount)
    print("% of hands: ", 100.0 * threeCount / TRIALS)

    print("Number of quads hand is: ", fourCount)
    print("% of hands: ", 100.0 * fourCount / TRIALS)

    print("Number of trips hand is: ", fullHouseCount)
    print("% of hands: ", 100.0 * fullHouseCount / TRIALS)

    print("Number of trips hand is: ", StraightCount)
    print("% of hands: ", 100.0 * StraightCount / TRIALS)



def card_example():

    card1 = Card()  # Card(1,3) => Ace of Clubs
    card2 = Card(12, 2) # Card (12,2) => Queen of Hearts

    card1._newfield = 47 # we can add new fields to any Python object!

    # three ways of printing a Card
    #

    print(card1.__str__())  # calling the methods against card
    print(str(card2)) # type-casting
    print(card2) # short-cut: passing obj ref to print does str() automagically

    print(card1._newfield) # see the new field value?

    print(card1._rank) # see the rank (1..13)
    print(card1._suit) # see the suit (0..3)

def deck_example():
    """
    Test Deck: create, print then shuffle, print again
    Then deal first two cards and print, along with bottom card
    """

    deck = Deck()
    print(str(deck)) # see entire deck before shuffling

    print("Now we shuffle:\n")

    deck.shuffle()
    print(str(deck)) # see entire deck after shuffling

    card1 = deck.dealCard()
    card2 = deck.dealCard()

    print("The first card dealt is", str(card1), "and the second is", str(card2))
    print("Bottom of deck is", deck._cards[-1])  # can't hide the implementation!

if __name__ == "__main__": # only run this if this .py is NOT imported
    # pass

    # card_example() # uncomment to test creating & calling Card methods

    # deck_example()  # uncomment to test Deck: create, print, shuffle, print

    main()  # uncomment to run general poker odds calculations

#
# -------------------------------------------------------------------------
#

#pytest follows...

def test_one_pair():
    testhand = [Card(2, 3), Card(1, 2),
                Card(3, 1), Card(13, 2),
                Card(2, 0)]

    dict = buildDict(testhand)

    assert hasOnePair(dict)  #hasTwoPairs

def test_two_pair():
    testhand = [Card(2, 3), Card(1, 2),
                Card(3, 1), Card(3, 2),
                Card(2, 0)]

    dict = buildDict(testhand)

    assert hasTwoPairs(dict)

def test_three_pair():
    testhand = [Card(1, 3), Card(1, 2),
                Card(1, 1), Card(13, 2),
                Card(2, 0)]

    dict = buildDict(testhand)

    assert hasThreeOfAKind(dict)

def has_Four_Of_A_Kind():
    testhand = [Card(1, 3), Card(1, 2),
                Card(1, 1), Card(1, 0),
                Card(2, 0)]

    dict = buildDict(testhand)

    assert hasFourOfAKind(dict)

def test_full_house():
    testhand = [Card(1, 3), Card(1, 2),
                Card(1, 1), Card(13, 2),
                Card(13, 2)]

    dict = buildDict(testhand)

    assert hasFullHouse(dict)

def test_Straight():
    testhand = [Card(11, 1), Card(10, 3),
                Card(9, 2), Card(8, 1),
                Card(7, 3)]

    dict = buildDict(testhand)

    assert hasStraight(dict)


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/36176
 
1585 次点击  
文章 [ 1 ]  |  最新文章 6 年前
Green Cloak Guy
Reply   •   1 楼
Green Cloak Guy    6 年前

直牌的条件是你的五张牌有相邻的等级,这样没有两张牌有相同的等级。您可以使用两种不同的检查来确认这一点:

  1. 直牌中没有两张牌具有相同的等级(因此,根据鸽子洞原则,必须存在最小和最大之间的所有等级

def hasStraight(hand):
    # account for both low-ace and high-ace
    ranks_low = sorted([card._rank for card in hand])
    ranks_high = sorted([(14 if card._rank == 1 else card._rank) for card in hand])

    return (
        (
            ranks_low[-1] - (len(hand) - 1) == ranks_low[0]
            or ranks_high[-1] - (len(hand) - 1) == ranks_high[0]
        )                                                        # condition 1
        and len(set(hand)) == len(hand)                          # condition 2
    )


冲洗的条件是所有卡片都是同一套。这很容易验证,只需 set true

def hasFlush(hand):
    suits_set = set(*[card._suit for card in hand])
    return len(suits_set) == 1

def hasStraightFlush(hand):
    return hasStraight(hand) and hasFlush(hand)

def hasRoyalFlush(hand):
    ranks = sorted([14 if card._rank == 1 else card._rank for card in hand])
    return (
        hasStraightFlush(hand)
        and ranks[0] == 10 and ranks[-1] == 14
    ) # royal flush starts at 10, ends at high-ace