Python实现“扑克牌斗牛”游戏规则

        偶然间看到了“扑克牌斗牛”游戏规则,对其中各种“牛”的概率问题产生了兴趣,故研究了下游戏规则后使用Python实现了五张牌各种“牛”的判断规则,欢迎各位读者测试指正。

        废话不多说,直接上代码:

from itertools import combinations
import random

def createCards():
    cardType = ['梅花', '方块', '红桃', '黑桃']
    cardNum = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']
    cardPoints = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] * 4
    cardList = [cT + str(cN) for cT in cardType for cN in cardNum]
    cardDict = {}
    for i in range(len(cardList)): cardDict[cardList[i]] = cardPoints[i]
    return cardDict

#发牌方法,任意取出五张牌后,返回卡组信息列表(卡组列表,点数列表)及卡池剩余牌字典
def dealCards(cardDict):
    cardLists = random.sample([key for key in cardDict.keys()],5)
    cardMap = {}
    for card in cardLists: cardMap[card] = cardDict[card]
    pointList = [point for point in cardMap.values()]
    playerList = [cardLists,pointList]
    for card in cardLists:
        cardDict.pop(card)
    return playerList,cardDict

#将大于10的花牌点数设置为10
def cardRealpoints(num):
    if num in [11,12,13]:
        return 10
    else:
        return num
#通过卡牌点数获取卡牌
def pointCardMapping(point):
    cardNum = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']
    return cardNum[point-1]

#以下为各种牛的判断方法--------------------------------------------
#判断是否为炸弹 返回值炸弹点数,是否为炸弹
def bombList(pointList):
    for item in pointList:
        if pointList.count(item) == 4:
            return pointCardMapping(item),True
        else:
            return None,False

#判断是否为五小 返回值是否为五小
def fiveLittle(pointList):
    littleList = list(filter(lambda point:(point<5),pointList))#将点数小于5的点数取出成新列表
    # print(littleList)
    if len(littleList)== 5 and sum(littleList) == 10:#5张牌点数均小于5 且和为10
        return True
    else:
        return False

#判断是否为五花
def fiveFlower(pointList):
    flowerleList = list(filter(lambda point: (point > 10), pointList))  # 将点数大于10的点数取出成新列表
    # print(flowerleList)
    if len(flowerleList) == 5 and bombList(pointList)[1] == False:  # 5张牌点数均大于10 且卡组中无炸弹
        return True
    else:
        return False

#判断是否为四花
def fourFlower(pointList):
    flowerleList = list(filter(lambda point: (point > 10), pointList))  # 将点数大于10的点数取出成新列表
    # print(flowerleList)
    lastList = [point for point in pointList if point not in flowerleList]
    # 4张牌点数均大于10 且卡组中无炸弹且剩余一张牌点数为10
    if len(flowerleList) == 4 and bombList(pointList)[1] == False and (len(lastList)== 1 and sum(lastList) == 10):
        return True
    else:
        return False

#卡牌点数计算器 计算卡组点数列表中的点数和
def cardCalculator(pointList):
    sumPoints = 0
    for points in pointList:
        sumPoints += cardRealpoints(points)
    return sumPoints


#中间方法任取三张牌为10的倍数,并返回其组合方式(集合,集合中存元组,如{(1, 2, 7), (1, 1, 8)})
# J Q K 按照10点来计算
def getTen(pointList):
    getList = set(combinations(pointList,3)) # 五取三 组合
    # 使用点数计算器算出三张牌之和为10的倍数的组合
    tenList = [itemList for itemList in getList if cardCalculator(itemList) % 10 == 0]
    #讲组合去重
    tenSet = set(tuple(tenList))
    return tenSet

#判断牛10-牛1或无牛 入卡组存在多牛 则返回最大
def tenBull(pointList):
    tenSet = getTen(pointList)
    tenDict = {}
    #如果不为炸弹、五小、五花、四花且有牛
    if len(tenSet) > 0 and bombList(pointList)[1] == False and fiveLittle(pointList) == False and  fourFlower(pointList)  == False and fiveFlower(pointList) == False:
        for ten in tenSet:
            #使用点数计算器算出剩余两张牌之和并判断
            if (cardCalculator(pointList)-cardCalculator(ten)) % 10 == 0:
                tenDict[''.join([str(i)+' ' for i in ten])+'|'+''.join([str(t)+' ' for t in pointList if t not in ten])] = 10
            else:
                tenDict[''.join([str(i)+' ' for i in ten])+'|' + ''.join([str(t)+' ' for t in pointList if t not in ten])] = (sum(pointList)-sum(ten)) % 10
    # print(bombList(pointList),fiveLittle(pointList),fourFlower(pointList),fiveFlower(pointList),tenDict)
    #如果同时存在多种牛 则返回牛数最大的
    if len(tenDict) > 0:
        return max(zip(tenDict.values(),tenDict.keys()))
    else:
        return None

#以上为各种牛的判断方法--------------------------------------------

def gamePriority(playerList):
    if bombList(playerList[1])[1]:
        return '卡组{}为炸弹'.format(playerList[0])
    elif fiveLittle(playerList[1]):
        return '卡组{}为五小'.format(playerList[0])
    elif fiveFlower(playerList[1]):
        return '卡组{}为五花'.format(playerList[0])
    elif fourFlower(playerList[1]):
        return '卡组{}为四花'.format(playerList[0])
    else:
        result = tenBull(playerList[1])
        if result == None:
            return '卡组{}无牛'.format(playerList[0])
        else:
            return '卡组{}为牛{}'.format(playerList[0],result[0])

def createLogs():
    pass

def game():
    cardsMap = createCards()
    cardDicts = cardsMap.copy()
    n = 1
    logfile = open(r'D:\File\pythonfiles\gamelog.txt','a+')#牌组信息写入文件
    print('*'*50,file = logfile)
    while len(cardDicts)>=5:
        playerList, cardDict = dealCards(cardDicts)
        cardDicts = cardDict
        result = gamePriority(playerList)
        print('第{}次抽牌,{}'.format(n,result),file = logfile)
        n += 1

if __name__ == '__main__':
    game()

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是如何用Python实现一个交互式界面的扑克牌发牌程序。下面是一个简单的实现示例,您可以参考一下: ```python import random import tkinter as tk # 创建扑克牌的列表 suits = ['♠', '♥', '♦', '♣'] ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] deck = [rank + suit for suit in suits for rank in ranks] # 创建交互式界面 root = tk.Tk() root.title('扑克牌发牌程序') canvas = tk.Canvas(root, width=800, height=600) canvas.pack() # 创建玩家和底牌的标签 player_label = tk.Label(root, text='玩家:') player_label.place(x=50, y=50) deck_label = tk.Label(root, text='底牌:') deck_label.place(x=50, y=100) # 创建发牌按钮,点击后随机发一张牌给玩家或底牌 def deal_card(): card = random.choice(deck) deck.remove(card) if len(player_cards) < 5: player_cards.append(card) player_card_label.config(text=' '.join(player_cards)) else: deck_cards.append(card) deck_card_label.config(text=' '.join(deck_cards)) deal_button = tk.Button(root, text='发一张牌', command=deal_card) deal_button.place(x=50, y=150) # 创建玩家和底牌的显示标签 player_card_label = tk.Label(root, text='', font=('Arial', 20)) player_card_label.place(x=150, y=50) deck_card_label = tk.Label(root, text='', font=('Arial', 20)) deck_card_label.place(x=150, y=100) # 初始化玩家和底牌的牌组 player_cards = [] deck_cards = [] root.mainloop() ``` 这个程序使用了Tkinter库创建了一个交互式界面,包括一个发牌按钮和两个标签用于显示玩家和底牌的牌组。点击发牌按钮后,程序会随机从扑克牌列表中选取一张牌,并将其从列表中删除。如果玩家的牌组还没有满5张,则将这张牌加入玩家的牌组中,并更新玩家牌组的显示标签;否则,将这张牌加入底牌的牌组中,并更新底牌牌组的显示标签。 您可以根据自己的需求进行修改和扩展,比如增加计分功能、添加更多的按钮和标签等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值