Use python to develop a small game called Golden Flower. Be careful not to get addicted to it~~ (complete source code attached)

Explosive (Fraud) Golden Flower, also called Three Cards, is a folk multiplayer card game widely spread across the country. The game uses a deck of playing cards excluding kings and kings, with a total of 52 cards of 4 suits. Each player draws 3 cards from them and compares the cards. The order of various card types is as follows (the smaller the probability of appearing in the full arrangement combination, the greater the card type score reward): 1. Straight Flush: three cards of the same suit with consecutive points, such as Heart 2, Heart 3, and Heart 4; 2. Leopard: three cards with the same number, such as AAA, 222; 3. Straight: three cards with consecutive numbers, such as 2 hearts, 3 spades, and 4 diamonds; 4. Golden Flower: three cards of the same suit. Cards, such as 2 of hearts, 5 of hearts, 8 of hearts; 5. Pair: two cards with the same number, such as 2 of hearts, 2 of spades; 6. Single card: 2~10 < J < Q < K < A. The following probabilities are taken from Baidu Encyclopedia:

picture

Note: The game rules described in this article are different from the actual ones, and are mainly designed based on the comparison of different card types.

1. Realization of game process

picture

1. Prepare playing cards

Before starting the game, you need to generate a deck of playing cards that meet the requirements. As all poker players know, playing cards have the following four suits, and each suit has 13 cards such as A, 2~10, J, Q, and K.

suit = ["黑桃", "红心", "方块", "梅花"]
num = [str(i) for i in range(2, 11)] + ["J", "Q", "K", "A"]

In order to facilitate the subsequent calculation of points, each one is first 单张assigned a corresponding point.

score_map = {}  # 单张点数映射表
for s in suit:
    count = 2
    for n in num:
        score_map[f"{s}{n}"] = count
        count += 1

Poker points preview is as follows:

score_map = {'Spade 2': 2, 'Spade 3': 3, 'Spade 4': 4, 'Spade 5': 5, 'Spade 6': 6, 'Spade 7': 7 , '8 of spades': 8, '9 of spades': 9, '10 of spades': 10, 'J of spades': 11, 'Q of spades': 12, 'K of spades': 13, ' Ace of Spades': 14, 'Two of Hearts': 2, ... }

2. Players enter

Players are distinguished by names such as p1, p2, etc. We first invite 5 players to enter.

players = [f"p{i}" for i in range(1, 6)]

3. Licensing

Pass the list of players and playing cards as parameters to the dealer. The card dealer draws from the playing cards without replacement, randomly draws 3 cards for each player, and writes down the player's name and its corresponding deck.

def get_pk_lst(pls, pks):
    result = []
    for p in pls:
        pk = sample(pks, 3)
        for _pk in pk:
            pks.remove(_pk)
        result.append({"name": p, "poker": pk})
    return result

pokers = list(score_map.keys())  # 去掉大小王的一幅扑克
poker_grp = get_pk_lst(players, pokers)  # 发牌

The license preview is as follows:

result = [{'name': 'p1', 'poker': ['Diamond 5', 'Club 3', 'Diamond A']}, {'name': 'p2', 'poker': ['Black Peach 4', 'Diamond 8', 'Spade J']}, {'name': 'p3', 'poker': ['Heart 10', 'Heart K', 'Diamond 7']}, {' name': 'p4', 'poker': ['Diamond 4', 'Club 6', 'Diamond J']}, {'name': 'p5', 'poker': ['Heart 5', 'Clubs' 10', 'Ace of Spades']}]

4. Determine card types and calculate scores

Before calculating the points, press the previous mapping dictionary to  pk_lst convert the three playing cards in it into the corresponding points.

n_lst = list(map(lambda x: score_map[x], pk_lst))  # 点数映射

Next, intercept the text of the suit part, use the set to remove duplicates and determine whether it is a three-card flush.

same_suit = len(set([pk[:2] for pk in pk_lst])) == 1  # 是否同花色

Then sort the points and compare them with the sequence list generated based on the maximum value of the points to determine whether they are consecutive points. Note that A23 is considered a straight, just like QKA.

continuity = sorted(n_lst) == [i for i in range(min(n_lst), max(n_lst) + 1)] or set(n_lst) == {14, 2, 3}  # 是否连续

Don't forget to consider how pairs and leopards are checked.

check = len(set(n_lst))  # 重复情况

Then let’s officially start judging card types and calculating scores! The first is a single card , non-flush, non-straight, and three cards with different points. Scores are added up to 3 single points.

if not same_suit and not continuity and check == 3:
    return sum(n_lst), "单张"

The second is a pair , which is not of the same suit. There are one and only two cards with the same number of points. The portion of the score that forms the pair will be rewarded 2x.

if not same_suit and check == 2:
    w = [i for i in n_lst if n_lst.count(i) == 2][0]
    single = [i for i in n_lst if i != w][0]
    return w*2*2 + single, "对子"

A golden flower , a flush rather than a straight, gives a 9x bonus.

if same_suit and not continuity:
    return sum(n_lst)*9, "金花"

A straight , where the points are in a row rather than a flush, gives an 81x bonus.

if continuity and not same_suit:
    return sum(n_lst)*81, "顺子"

Leopard , that is, if the three cards have the same number, it shouldn't be a 666.

if check == 1:
    return sum(n_lst)*666, "豹子"

Flush , same suit and consecutive points, absolutely, God of Gamblers has a skill that does 999 damage.

if continuity and same_suit:
    return sum(n_lst)*999, "同花顺"

5. Decide the outcome

A group of players, card drawing, score calculation, and card type records are as follows:

pk_grp = [{'name': 'p1', 'poker': ['Diamond 5', 'Club 3', 'Diamond A'], 'score': 22, 'type': 'Single'}, { 'name': 'p2', 'poker': ['4 of spades', '8 of diamonds', 'J of spades'], 'score': 23, 'type': 'single'}, {'name ': 'p3', 'poker': ['Heart 10', 'Heart K', 'Diamond 7'], 'score': 30, 'type': 'Single'}, {'name': 'p4 ', 'poker': ['Diamond 4', 'Club 6', 'Diamond J'], 'score': 21, 'type': 'Single'}, {'name': 'p5', 'poker ': ['5 of Hearts', '10 of Clubs', 'Ace of Spades'], 'score': 29, 'type': 'Single Card'}]

Use the max function to find out who is the best and reveal the name!

best = max(pk_grp, key=lambda x: x["score"])["name"]

The winner is ------ p3

Okay, now it’s time to start another enjoyable game~

2. Statistics and source code

picture

1. Card type statistics

After playing 100,000 games and conducting frequency statistics on various card types, it can be seen that the calculated probabilities are basically consistent with the aforementioned permutations and combinations.

Counter({'单张': 371856, '对子': 84773, '金花': 24833, '顺子': 16239, '豹子': 1179, '同花顺': 1120})
单张频率:74.37%
对子频率:16.95%
金花频率:4.97%
顺子频率:3.25%
豹子频率:0.24%
同花顺频率:0.22%

2. Game case

The situations and results of each card type are as follows:

开牌结果------
{'name': 'p1', 'poker': ['方块5', '梅花3', '方块A'], 'score': 22, 'type': '单张'}
{'name': 'p2', 'poker': ['黑桃4', '方块8', '黑桃J'], 'score': 23, 'type': '单张'}
{'name': 'p3', 'poker': ['红心10', '红心K', '方块7'], 'score': 30, 'type': '单张'}
{'name': 'p4', 'poker': ['方块4', '梅花6', '方块J'], 'score': 21, 'type': '单张'}
{'name': 'p5', 'poker': ['红心5', '梅花10', '黑桃A'], 'score': 29, 'type': '单张'}
赢家是------
p3


开牌结果------
{'name': 'p1', 'poker': ['方块Q', '黑桃5', '黑桃K'], 'score': 30, 'type': '单张'}
{'name': 'p2', 'poker': ['黑桃2', '方块2', '红心10'], 'score': 18, 'type': '对子'}
{'name': 'p3', 'poker': ['梅花2', '黑桃4', '梅花J'], 'score': 17, 'type': '单张'}
{'name': 'p4', 'poker': ['红心K', '梅花7', '红心6'], 'score': 26, 'type': '单张'}
{'name': 'p5', 'poker': ['方块A', '方块6', '红心4'], 'score': 24, 'type': '单张'}
赢家是------
p1


开牌结果------
{'name': 'p1', 'poker': ['黑桃J', '黑桃5', '黑桃4'], 'score': 180, 'type': '金花'}
{'name': 'p2', 'poker': ['梅花7', '红心4', '梅花5'], 'score': 16, 'type': '单张'}
{'name': 'p3', 'poker': ['方块5', '黑桃9', '梅花10'], 'score': 24, 'type': '单张'}
{'name': 'p4', 'poker': ['黑桃Q', '梅花9', '黑桃10'], 'score': 31, 'type': '单张'}
{'name': 'p5', 'poker': ['红心9', '方块9', '红心A'], 'score': 50, 'type': '对子'}
赢家是------
p1


开牌结果------
{'name': 'p1', 'poker': ['方块8', '黑桃10', '方块9'], 'score': 2187, 'type': '顺子'}
{'name': 'p2', 'poker': ['梅花9', '红心Q', '黑桃3'], 'score': 24, 'type': '单张'}
{'name': 'p3', 'poker': ['方块A', '梅花K', '黑桃4'], 'score': 31, 'type': '单张'}
{'name': 'p4', 'poker': ['方块J', '红心J', '红心6'], 'score': 50, 'type': '对子'}
{'name': 'p5', 'poker': ['梅花5', '黑桃K', '方块3'], 'score': 21, 'type': '单张'}
赢家是------
p1


开牌结果------
{'name': 'p1', 'poker': ['黑桃Q', '黑桃8', '梅花6'], 'score': 26, 'type': '单张'}
{'name': 'p2', 'poker': ['红心3', '梅花3', '黑桃3'], 'score': 5994, 'type': '豹子'}
{'name': 'p3', 'poker': ['红心A', '红心6', '方块5'], 'score': 25, 'type': '单张'}
{'name': 'p4', 'poker': ['黑桃4', '梅花A', '方块2'], 'score': 20, 'type': '单张'}
{'name': 'p5', 'poker': ['梅花7', '黑桃6', '梅花8'], 'score': 1701, 'type': '顺子'}
赢家是------
p2


开牌结果------
{'name': 'p1', 'poker': ['黑桃5', '梅花9', '方块9'], 'score': 41, 'type': '对子'}
{'name': 'p2', 'poker': ['黑桃Q', '黑桃2', '红心Q'], 'score': 50, 'type': '对子'}
{'name': 'p3', 'poker': ['红心2', '黑桃7', '红心5'], 'score': 14, 'type': '单张'}
{'name': 'p4', 'poker': ['梅花3', '方块10', '黑桃A'], 'score': 27, 'type': '单张'}
{'name': 'p5', 'poker': ['黑桃9', '黑桃J', '黑桃10'], 'score': 29970, 'type': '同花顺'}
赢家是------
p5

3. Complete code

# @Seon
# 炸金花

from random import sample
from collections import Counter


def get_pk_lst(pls, pks):  # 发牌
    result = []
    for p in pls:
        pk = sample(pks, 3)
        for _pk in pk:
            pks.remove(_pk)
        result.append({"name": p, "poker": pk})
    return result


def calculate(_score_map, pk_lst):  # 返回得分和牌型
    n_lst = list(map(lambda x: _score_map[x], pk_lst))  # 点数映射
    same_suit = len(set([pk[:2] for pk in pk_lst])) == 1  # 是否同花色
    continuity = sorted(n_lst) == [i for i in range(min(n_lst), max(n_lst) + 1)] or set(n_lst) == {14, 2, 3}  # 是否连续
    check = len(set(n_lst))  # 重复情况
    if not same_suit and not continuity and check == 3:
        return sum(n_lst), "单张"
    if not same_suit and check == 2:
        w = [i for i in n_lst if n_lst.count(i) == 2][0]
        single = [i for i in n_lst if i != w][0]
        return w*2*2 + single, "对子"
    if same_suit and not continuity:
        return sum(n_lst)*9, "金花"
    if continuity and not same_suit:
        return sum(n_lst)*81, "顺子"
    if check == 1:
        return sum(n_lst)*666, "豹子"
    if continuity and same_suit:
        return sum(n_lst)*999, "同花顺"


def compare(_score_map, pk_grp):  # 比大小
    for p in pk_grp:
        p["score"], p["type"] = calculate(_score_map, p["poker"])
    print("开牌结果------")
    for p in pk_grp:
        print(p)
    print("赢家是------")
    best = max(pk_grp, key=lambda x: x["score"])["name"]
    print(best)
    return pk_grp


def show(_score_map, _players):   # 开局
    pokers = list(_score_map.keys())
    poker_grp = get_pk_lst(_players, pokers)
    return compare(_score_map, poker_grp)


def start_game(_score_map, _players, freq=1):   # 游戏和统计
    type_lst = []
    for i in range(freq):
        grp = show(_score_map, _players)
        type_lst = type_lst + [t["type"] for t in grp]
    c = Counter(type_lst)
    print(c)
    total = sum(c.values())
    for item in c.items():
        print(f"{item[0]}频率:{item[1]/total:.2%}")


if __name__ == '__main__':
    # 准备扑克牌
    suit = ["黑桃", "红心", "方块", "梅花"]
    num = [str(i) for i in range(2, 11)] + ["J", "Q", "K", "A"]
    score_map = {}  # 单张点数映射表
    for s in suit:
        count = 2
        for n in num:
            score_map[f"{s}{n}"] = count
            count += 1
    # 5个玩家入场
    players = [f"p{i}" for i in range(1, 6)]
    # 开始游戏
    start_game(score_map, players, freq=100000)      

Guess you like

Origin blog.csdn.net/m0_59595915/article/details/132622274