ZBLOG

Good Luck To You!

炸金花代码教程

总结


最后提及很有趣的一点。虽然 豹子 > 顺金,但是豹子出现的概率却略大于顺金;同样,金花 > 顺子,但是金花出现的概率要比顺子大。


附python3代码:


# -*- coding: utf-8 -*-

import random

import matplotlib.pyplot as plot

import numpy


color_book = {1: "♠", 2: "♥", 3: "♣", 4: "♦"}

num_book = {"J": 11, 11: "J", "Q": 12, 12: "Q", "K": 13, 13: "K", "A": 14, 14: "A"}

type_book = {100: "豹子", 101: "顺金", 102: "金花", 103: "顺子", 104: "对子",

             14: "散A", 13: "散K", 12: "散Q", 11: "散J", 10: "散10", 9: "散9", 8: "散8", 7: "散7", 6: "散6", 5: "散5"}

lvl_book = [100, 101, 102, 103, 104, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5]

card_book = list()

'''单张牌'''

class Card:

    def __init__(self, num, color = 1):

        self.num = num

        self.color = color

'''手牌'''

class Hand:

    def __init__(self, cardList):

        self.hand = sorted(cardList, key=lambda x: x.num, reverse=True)

    def parseType(self) -> int:

        #100. 豹子

        if self.hand[0].num == self.hand[1].num and self.hand[0].num == self.hand[2].num:

            return 100


        # 金花 & 顺金

        elif self.hand[0].color == self.hand[1].color and self.hand[0].color == self.hand[2].color:

            # 101. 顺金

            if  (self.hand[2].num + 1 == self.hand[1].num and self.hand[1].num + 1 == self.hand[0].num \

                     or self.hand[2].num == 2 and self.hand[1].num == 3 and self.hand[0].num == 14):

            # 因为 A 是以数字 14 存储的,因此 A23 顺要额外考虑

                return 101

            # 102. 金花

            else:

                return 102

        # 103 顺子

        # 因为上个 if 已经除去了顺金部分,因此只要是公差为1的等差数列则一定是顺子

        elif self.hand[2].num + 1 == self.hand[1].num and self.hand[1].num + 1 == self.hand[0].num \

                     or self.hand[2].num == 2 and self.hand[1].num == 3 and self.hand[0].num == 14:

            return 103

        # 104. 对子, 对子要额外记录一下对子和单牌,以便比较大小

        elif self.hand[2].num == self.hand[1].num or self.hand[1].num == self.hand[0].num:

            if self.hand[2].num == self.hand[1].num:

                self.pair, self.single = self.hand[2].num, self.hand[0].num

            else:

                self.pair, self.single = self.hand[0].num, self.hand[2].num

            return 104

        # 散牌

        else:

            return self.hand[0].num

'''初始化牌堆'''

def initCard():

    # 1 表示 A

    # 13 表示 K

    for i in range(2, 15):

        for j in range(1, 5):

            card_book.append(Card(i, j))

'''打印手牌'''

def printHand(handCard: Hand):

    for h in handCard.hand:

        print(h.num, end='') if 1 < h.num <= 10 else print(num_book[h.num], end='')

        print(color_book[h.color], end=' ')

    print(type_book[handCard.parseType()])

    

'''比较辅助函数'''

def cmpCard(h1: Hand, h2: Hand):

    for i in range(len(h1.hand)):

        if h1.hand[i].num != h2.hand[i].num:

            if h1.hand[i].num > h2.hand[i].num:

                return 0

            else:

                return 2

    return 1


'''比较手牌函数'''  

def cmpHand(h1: Hand, h2: Hand):

    lvl1 = h1.parseType()

    lvl2 = h2.parseType()

    #printHand(h1)

    #printHand(h2)

    # 先比较牌种

    if lvl_book.index(lvl1) < lvl_book.index(lvl2):

        return 0

    elif lvl_book.index(lvl1) > lvl_book.index(lvl2):

        return 2

    # 对子,要先比对子

    elif lvl1 == 104:

        if h1.pair == h2.pair:

            return cmpCard(Hand([Card(h1.single)]), Hand([Card(h2.single)]))

        else:

            return cmpCard(Hand([Card(h1.pair)]), Hand([Card(h2.pair)]))


    # 其余情况,挨个比就行

    else:

        return cmpCard(h1, h2)

    

'''作图函数'''

def plotRects(x_list, y_list):

    rects = plot.bar(range(len(y_list)), y_list, color=[numpy.random.random(3) for i in range(len(y_list))])


    plot.ylabel("概率(%)")

    plot.xticks([i for i in range(len(x_list))], x_list)

    for rect in rects:

        height = rect.get_height()

        plot.text(rect.get_x() + rect.get_width() / 2, height, "{:.3f}%".format(height), ha='center', va='bottom')

    plot.rcParams['font.sans-serif'] = ['Arial Unicode MS']

    plot.rcParams['axes.unicode_minus'] = False

    plot.show()


'''获得全部牌型的概率'''

def getPr(cap: int):

    cnt = dict()

    tot = int(cap)

    for i in range(tot):

        hand1 = Hand(random.sample(card_book, 3))

        type = hand1.parseType()

        cnt[hand1.parseType()] = 1 if type not in cnt else cnt[hand1.parseType()] + 1


    cnt = dict(sorted(cnt.items(), key=lambda x: x[1]))

    '''分组画图'''

    sub1 = dict([(key, cnt[key]) for key in range(100, 105)])

    sub2 = dict([(key, cnt[key]) for key in range(5, 15)])

    name_list1 = [type_book[k] for k in sub1.keys()]

    val_list1 = [v / tot * 100 for v in sub1.values()]

    name_list2 = [type_book[k] for k in sub2.keys()]

    val_list2 = [v / tot * 100 for v in sub2.values()]

    plotRects(name_list1, val_list1)

    plotRects(name_list2, val_list2)


'''获得全部牌型的胜率''' 

def getWinning(cap: int):

    result = {}

    tot = int(cap)

    for i in range(tot):

        hand = random.sample(card_book, 6)

        hand1 = Hand(hand[:3])

        hand2 = Hand(hand[-3:])

        type = hand1.parseType()                            

        if type in result.keys():

            # print(type, cmpHand(hand1, hand2))

            result[type][cmpHand(hand1, hand2)] += 1

        else:

            result[type] = [0] * 3

            result[type][cmpHand(hand1, hand2)] = 1


    '''分组画图'''

    sub1 = dict([(key, result[key]) for key in range(100, 105)])

    sub2 = dict([(key, result[key]) for key in range(5, 15)])


    name_list1 = [type_book[k] for k in sub1.keys()]

    val_list1 = [v[0] / sum(v) * 100 for v in sub1.values()]

    name_list2 = [type_book[k] for k in sub2.keys()]

    val_list2 = [v[0] / sum(v) * 100 for v in sub2.values()]

    plotRects(name_list1, val_list1)

    plotRects(name_list2, val_list2)

if __name__ == '__main__':

    initCard()

    #getPr(1e7)

    getWinning(1e7)

复制代码

QQ图片20230428231237.jpg

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«    2024年11月    »
123
45678910
11121314151617
18192021222324
252627282930
搜索

Powered By Z-BlogPHP 1.7.2

Copyright Your WebSite.Some Rights Reserved.