炸金花遊戲功能的實現(發牌,計算牌型,比牌)——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

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