在B站学习Python的视频上,遇到一个题目,挺有意思,试着实现了一下,记录下来!题目如下:#### 游戏规则:一付扑克牌,去掉大小王,每个玩家发3张牌,最后比大小棋牌游戏,看谁赢。有以下几种牌:豹子:三张一样的牌,如3张6.顺金:又称同花顺,即3张同样花色的顺子, 如红桃 5、6、7顺子:又称拖拉机,花色不同,但是顺子,如红桃5、方片6、黑桃7,组成的顺子对子:2张牌一样单张:单张最大的是A这几种牌的大小顺序为, **豹子>顺金>顺子>对子>单张**#### 需程序实现的点:先生成一付完整的扑克牌给5个玩家随机发牌统一开牌,比大小,输出赢家是谁阅读提示:先从main()函数往回看,是如何调用的!#!/usr/bin/env python 3.9.5
# -*- coding: utf-8 -*-
# @Time : 2021/6/17 10:25
# @Author : CG Zhang
# @Site :
# @File : 炸金花游戏.py
# @Software: PyCharm
# @Note :
import random
class Cards:
'''生成一副新牌'''
def __init__(self):
flower = ["桃", "心", "梅", "方"]
numb = [ "2","3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
self.cards = [f+n for f in flower for n in numb]
def __str__(self):
return self.cards
def get(self, n:int):
''' 定义取牌属性
:param n: 取牌张数
:return: 随机牌
'''
if not n > len(self.cards):
card = random.sample(self.cards, n)
for _c in card:
self.cards.remove(_c) #取走之后要从总数里面删除
return card
else:
print("牌不够了!")
class Player:
'''self: New 玩家'''
def __init__(self, name, card):
self.name = name
self.card = card
def __str__(self):
return self.name,self.card
def score_flower(_data:list):
'''
:param _data: 给牌计分
:return: 同花 = 623505 分
'''
if _data[0] == _data[1] == _data[2]: #同花
return 623505
else:
return 0
def score_numbs(_data:list):
'''
:param _data: exmp: in: ["8","5","12"], out: 1797 给牌值计分,基础分原则要求比下一级的最大值要大1
:return:炸弹 = 1249965 + 权重分 ( max: AAA = 1252918, min: 222 = 1249979),
*顺金 = 626460 + 顺子 ( max: 同花QKA = 1249964, min: 同花A23 = 670785),
*同花 = 623505 + 权重分 ( max: 同花JKA = 626459, min: 同花245 = 623519),
常规顺子 = 44325 * 权值( max:14,min:2) + 权重分 ( max: QKA = 623504, min: 234 = 88662),
特殊顺子 = 44325 ( 即:A23 = 固定分:44325),
对子 = 2955 * 权值( max:14,min:2) + 权重分 ( max: AAK = 44324, min: 223 = 5924),
单张 = 权重分( max:AAA = 2954分,min:222 = 14分)
'''
_data = sorted(_data , reverse = False) #升序排列
_wi = _data[0] ** 1 + _data[1] ** 2 + _data[2] ** 3 # 牌值加权算法
if _data[0] == _data[1] == _data[2]: #炸弹
return 1249965 + _wi
elif _data[0]+1 == _data[1] == _data[2]-1 : # 常规顺子
return 44325 * _data[2] + _wi # 加权算法:基础分*最大牌值
elif _data[0]+1 == _data[1] == _data[2]-11: # 特殊顺子,即:A23
return 44325
elif _data[0] == _data[1] or _data[1] == _data[2]: #对子
return 2955 * _data[1] + _wi # 加权算法:基础分*对子的单牌值
else:
return _wi #单张
def slicer(card:list):
'''
:param card: 给3张牌按照花色和数字进行切片,如 ['桃2', '桃A', '方10'] ==> flower:['桃', '桃', '方']、numb:['2', '14', '10']
:return: 返回牌值
'''
flower = [c[0] for c in card]
numb = list(map(lambda s:int(s) if s.isdigit() else {'J':11,'Q':12,'K':13,"A":14}[s] , [c[1:] for c in card]))
return score_flower(flower) + score_numbs(numb)
def compare(_data:dict):
'''
:param _data: in: exmp: {'张三': 1433, '李四': 2216, '王五': 23485, '李六': 2923, '孙七': 1797}
:return: 比较字典中的values,返回打印最大的keys,即赢家
'''
winer = max([v for k,v in _data.items()])
for k,v in _data.items():
if v == winer:
print(f"{k},赢!") # 这样写可保证,如果赢家牌都一样,都能打印
def main():
'''本游戏支持多人一起玩,但人数不能超过17,取牌数量仅支持3(否者没算法支持)'''
cards = Cards()
players = ["张三", "李四", "王五", "李六", "孙七"]
result = {}
for name in players:
player = Player(name,cards.get(3)) #每人取3张牌
print(player.name,":",player.card) #发牌
result.update({ player.name : slicer(player.card) })
print("-" * 70)
print(result)
print("-" * 70)
compare(result) #比较
if __name__ == '__main__':
main()运行效果如下:张三 : ['心7', '桃9', '梅9']李四 : ['方5', '方Q', '心6']王五 : ['心4', '心9', '心J']李六 : ['梅4', '梅7', '桃4']孙七 : ['梅Q', '心Q', '心10']----------------------------------------------------------------------{'张三': 27412, '李四': 1769, '王五': 624921, '李六': 12183, '孙七': 37342}----------------------------------------------------------------------王五,赢!
16
2022
03
Python实现炸金花游戏
发布日期:2022-03-16 13:09 点击次数:111
- 相关棋牌游戏技巧