炸金花游戏功能的实现(发牌,计算牌型,比牌)——python2.7

最近公司在做棋牌类游戏项目,看到炸金花的玩法后,就自己先写出炸金花的基本功能实现,给那些python爱好者参考一下。

炸金花是民间非常流行的一种扑克牌玩法,它具有独特的比牌规则,玩家按照规则以手中的三张牌来比输赢。游戏过程中需要考验玩家的胆略和智慧,由于玩法简单,易于上手,炸金花是被公认的最受欢迎的纸牌游戏之一。炸金花游戏参与人数 2- 6 人,使用一副去掉到大小王的扑克牌,共 52 张牌。

在本游戏demo中,用户输入游戏人数,系统给每位玩家发三张牌,然后进行比牌排序,最后挑选出牌最大的玩家。
排序判断:可以赋予牌型固定值,比如同花顺60,同花50,顺子40…牌型相同的,再进行细节比较。

文件目录如下:
在这里插入图片描述

初始化牌堆:game_config.py

#coding=utf-8

import random




# 花色 红黑方梅
SUITS = ['H', 'S', 'D', 'C']
# 初始基本牌
INIT_LIST = ['2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q','K','A']

MAPPING_LIST_NUM = '23456789TJQKA'
MAPPING_LIST_COLOR = 'DCHS'  # 方梅红黑

def init_landlords():
    lis = []
    for card in INIT_LIST:  # 数字
        for suit in SUITS:  # 花色
            lis.append('{0}{1}'.format(card, suit))
    random.shuffle(lis)
    return lis
    # print "初始化牌堆:", lis

def exchange_number(cards):
    number = []
    for r, s in cards:
        temp = MAPPING_LIST_NUM.index(r)
        number.append(temp)
    return number


def exchange_color(cards):
    color = []
    for r, s in cards:
        temp = MAPPING_LIST_COLOR.index(s)
        color.append(temp)
    return color



if __name__ =='__main__':
    init_landlords()

比牌 : compare.py

#coding=utf-8
from game.game_config import *
from collections import Counter

BAOZI = 60     # 三条
COLORSEQ = 50  # 同花顺
COLOR = 40     # 同花
SEQ = 30       # 顺子
PAIR = 20      # 对子
SINGLE = 10    # 单张

# 单张比较
def cmpcard(x, y):
    x_num = MAPPING_LIST_NUM.index(x[0])
    x_col = MAPPING_LIST_COLOR.index(x[1])
    y_num = MAPPING_LIST_NUM.index(y[0])
    y_col = MAPPING_LIST_COLOR.index(y[1])
    if x_num < y_num:
        return -1
    elif x_num > y_num:
        return 1
    else:
        if x_col < y_col:
            return -1
        elif x_col > y_col:
            return 1
        else:
            return 0



def judgetype(cards):
    temp = cards[:]
    if baozi(cards):  # 豹子
        print "豹子"
        return BAOZI
    if color(cards):  # 同色
        if seq(cards):    # 顺子
            print "同花顺"
            return COLORSEQ   # 同花顺
        print "同花"
        return COLOR    # 同花
    if seq(cards):
        print "顺子"
        return SEQ
    if pair(cards):
        print "对子"
        return PAIR
    else:
        print "单张"
        return SINGLE   # 单张

# 三条
def baozi(pokers):
    count = exchange_number(pokers)
    if len(set(count)) == 1:
        return True


# 同花,红的返1,黑的返2
def color(pokers):
    colorlist = exchange_color(pokers)
    ss = set(colorlist)  # set集合判断是否同花
    if len(ss) == 1:
        if list(ss)[0] in [1, 3]:    # 1,3对应C,S  草黑
            return 2
        elif list(ss)[0] in [0, 2]:   # 0,2 对应  方红
            return 1


# 顺子
def seq(pokers):
    count = exchange_number(pokers)
    sortcount = sorted(count)
    if (sortcount[2] == sortcount[1] + 1 and sortcount[1] == sortcount[0] + 1) or (
            sortcount[0] == 2 and sortcount[1] == 3 and sortcount[2] == 14):         # 判断 A 2 3 情况
        return True


# 对子
def pair(pokers):
    count = exchange_number(pokers)
    if count_card(count, 2):
        return True

# 挑出cards中一张数量为n的牌
def count_card(cards, n):
    lis = Counter(cards)    # counter方法:计数
    returns = []
    for r, num in lis.most_common():  # most_common 找出出现频率最高 的方法 返回的是一个dict
        if num == n:
            returns.append(r)
            return returns
    return returns

发牌:deal.py

#coding=utf-8
from game.game_config import *
from game.compare import *
from game.compare import *
from operator import itemgetter



def deal():
    lis = init_landlords()
    seat = 0
    tile_list = []
    player_num = int(raw_input("请输入玩家数量(玩家人数建议为2—6人) :"))
    if player_num <= 6 and player_num >=2:
        while seat < player_num:
            tile = []
            rounds = 0
            while rounds < 3:
                tile.append(lis.pop())  # tile中三张
                rounds += 1
            tile_list.append(tile)  # tile_list中  3张*人数
            seat += 1
    elif player_num < 0:
        print "玩家人数错误"
        return
    elif player_num >= 0 and player_num <= 1:
        print "人数不够"
        return
    else:
        print "人数超过"
        return


    # 牌排序后分发到玩家手中
    card_group = []
    group_type = []
    seat_list = []
    for key, value in enumerate(tile_list):
        # print player,value
        card_group.append(sorted(value, cmp=cmpcard))
        seat_list.append(key)
    # print "发%d个人的牌:"%player_num,card_group

    for key, value in enumerate(card_group):
        s = judgetype(value)
        group_type.append(s)  # 玩家三张牌的牌型
        print "玩家%d的牌 :" % key ,value,s
        print "______________________________________"
        # dic_score[key] = s
    # print card_group,group_type
    # print "玩家的牌型:",group_type






    player_card = zip(seat_list,card_group,group_type)
    # print player_card

    cmp_data = []
    for i in range(len(player_card)):
        data_i = player_card[i]
        player_seat = data_i[0]
        card_list = data_i[1]
        card_type = data_i[2]
        max_card = max(card_list, key=lambda x: MAPPING_LIST_NUM.index(x[0]))
        cmp_data.append([card_type, MAPPING_LIST_NUM.index(max_card[0]), MAPPING_LIST_COLOR.index(max_card[1]), data_i])
        # print cmp_data
    result = sorted(cmp_data, key=itemgetter(0, 1, 2))


    sorted_list = []
    # print result
    for res in result:
        sorted_list.append(res[3])
    print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
    print "本局牌最大的是 :     玩家{0}".format(sorted_list[-1][0])








if __name__ == '__main__':
    deal()

优化:
(1)该游戏demo目前会出现2个bug。第一个是按理来说A23是最小的顺子,A23与其他顺子的比较无法实现,需要再增加一个方法把A23确定为最小顺子即可;第二个是对子的比较,比如玩家1手里有55J,玩家2手里有33A,系统会判定玩家2的牌大,解决方案是增加一个比较方法,当牌型都为对子,即牌型等于20时,先从对子中取一张牌比较(对子大的获胜),如果对子相同就看谁拿到黑桃对。
(2)要做成成型的游戏,就需要创建玩家对象,把牌型,分数这些作为属性传入玩家对象中去。
(3)未完待续…

游戏demo运行结果:

D:\python_works\venv\Scripts\python.exe D:/python_works/game/deal.py
请输入玩家数量(玩家人数建议为2—6人) :4
单张
玩家0的牌 : ['7S', '8D', 'TH'] 10
______________________________________
单张
玩家1的牌 : ['3C', '7H', '8S'] 10
______________________________________
对子
玩家2的牌 : ['6C', 'KD', 'KH'] 20
______________________________________
单张
玩家3的牌 : ['6S', '7D', 'AS'] 10
______________________________________
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
本局牌最大的是 :     玩家2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章