.png)
今天的第二个作品,哈哈哈哈,搞起来感觉还挺有意思的,不过代码里纸牌J,Q,K,A几个数字被我替换成了11,12,13,14......主要是没有想到简单的办法让其比较,索性都用数字了,我太菜了,希望有大佬指点一下。
代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | importrandom   #导入随机数函数defpuke():    """    生成一副52张的扑克牌(除去大小王)    :return:    """    list1 =['黑桃', '红桃', '方块', '梅花']    list2 =[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]    list3 =[]    fori inlist1:        forj inlist2:            dict1 ={i: j}            list3.append(dict1)    returnlist3deffunc(num):    """    判断随机生成的三张扑克类型,对不同类型的牌 底分进行相应的翻倍    其中num参数返回的是对玩家牌型计算后的分数。    (最小单张是:2,    11,12,13,14  分别代表:J,Q,K,A)    :param num:    :return:    """    user_list1 =[]     #用于存储牌的花色    user_list2 =[]     #用于存储牌的数字    globallist4     #声明调用外部全局变量    fori inlist4:        user_list1.append(list(i.keys()))        forj ini:            user_list1.append(list(i.values()))    user_list2.append(user_list1[1])        #将遍历后的数字添加进user_list2中    user_list2.append(user_list1[3])    user_list2.append(user_list1[5])    user_list2 =[int(x) foritem inuser_list2 forx initem]      #合并列表    user_list2.sort()       #列表排序    ifuser_list2[0] ==user_list1[1] ==user_list1[2]:     #判断三张数字是否相同        num =user_list1[1][0] *100000+zhadan    elifuser_list1[0] ==user_list1[2] ==user_list1[4] anduser_list2[2] -user_list2[1] ==user_list2[1] -\            user_list2[0] ==1:     #判断三张花色是否相同且连号        num =user_list2[1] *10000+shunjin    elifuser_list2[2] -user_list2[1] ==user_list2[1] -user_list2[0] ==1:       #判断是否连号        num =user_list2[1] *1000+shunzi    elifuser_list2[0] ==user_list2[1] oruser_list2[1] ==user_list2[2] oruser_list2[2] ==user_list2[0]:        #判断是否有两个一样的数字        ifuser_list2[0] ==user_list2[1]:            num =user_list2[0] *100+duizi        ifuser_list2[0] ==user_list2[2]:            num =user_list2[2] *100+duizi        ifuser_list2[2] ==user_list2[1]:            num =user_list2[1] *100+duizi    elifuser_list2[0] !=user_list2[1] !=user_list2[2]:       #最后一种可能,单张        num =user_list2[2] *10+user_list2[1] +danzhang    returnnum      #返回计算后的分值#    定义玩家牌型的底分zhadan =100shunjin =80shunzi =60duizi =40danzhang =20 gamer =[]      #定义新列表,存放玩家数量gamers =int(input('请输入玩家数量(只能2 - 9名):'))ifgamers >=2andgamers <=9:        #判断用户输入的人数是否在规定范围内    fori inrange(gamers):  # 玩家数量由用户定义,代表整体循环的次数        list4 =[]  # 用于存储每名玩家随机得到的三张牌        forj inrange(3):            sun =random.randint(1, len(puke()) -1)  # 以随机数为扑克整体的下标进行查找对应的牌            list4.append(puke()[sun])  # 添加进列表            puke().remove(puke()[sun])  # 把已经发出去的牌在扑克牌整体中进行删除        print(f'{i + 1}号玩家的底牌:{list4}')        ifi ==0:            user_1 =func(0)            gamer.append(user_1)        elifi ==1:            user_2 =func(0)            gamer.append(user_2)        elifi ==2:            user_3 =func(0)            gamer.append(user_3)        elifi ==3:            user_4 =func(0)            gamer.append(user_4)        elifi ==4:            user_5 =func(0)            gamer.append(user_5)        elifi ==5:            user_6 =func(0)            gamer.append(user_6)        elifi ==6:            user_7 =func(0)            gamer.append(user_7)        elifi ==7:            user_8 =func(0)            gamer.append(user_8)        elifi ==8:            user_9 =func(0)            gamer.append(user_9)else:    print('你输入的人数不合理,请重新输入。') old_grade =[]       #定义一个新列表,用于存放以玩家排序的分数new_grade =[]         #定义一个新列表,用于存放以大小排序后的分数fori ingamer:         #遍历玩家分数列表    old_grade.append(i)new_grade.extend(old_grade)old_grade.sort(reverse=True)     #降序排列后的分数列表 user =1forj innew_grade:     #遍历玩家顺序的列表    ifj ==old_grade[0]:        print(f'{user}号玩家获胜,得分:{old_grade[0]}')     #最终赢家的分数没有实际意义,仅为了判断最大值    else:        user +=1 | 
一、Poker 类(扑克牌)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Card =collections.namedtuple('Card', ['rank', 'suit'])classPoker(MutableSequence):    # 扑克牌的相关定义    ranks =[str(n) forn inrange(2, 11)] +list('JQKA')    suits ='spades hearts diamonds clubs'.split()  # 黑桃,红桃,方块,梅花    suit_values =dict(spades=3, hearts=2, diamonds=1, clubs=0)#黑桃最大,红桃次之,方块再次之,梅花最小    def__init__(self):        self._cards =[Card(rank, suit) forrank inself.ranks                                           forsuit inself.suits]    def__len__(self):        returnlen(self._cards)    def__getitem__(self, position):  # 仅仅实现了__getitem__方法,该对象就变成可迭代的        returnself._cards[position]    def__setitem__(self, position, value):        self._cards[position] =value    def__delitem__(self, position):        delself._cards[position]    definsert(self, position, value):        self._cards[position] =value | 
一副扑克牌有 54 张牌,其中 52 张是正牌,另2张是副牌(大王和小王)。本程序中未涉及到大小王。52 张正牌又均分为 13 张一组,并以黑桃、红桃、梅花、方块四种花色表示各组,每组花色的牌包括从 2-10 以及 J、Q、K、A 标示的 13 张牌。
二、Player 类(玩家)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | Own_Poker =collections.namedtuple('Own_Poker', ['id', 'rank', 'suit', 'score'])classPlayer():    '''    牌型  豹子:三张同样大小的牌。  顺金:花色相同的三张连牌。  金花:三张花色相同的牌。     顺子:三张花色不全相同的连牌。  对子:三张牌中有两张同样大小的牌。  单张:除以上牌型的牌。    '''    def__init__(self, id, poker):        self.id=id        self.poker =poker  #一副扑克牌        self.pokers =[]    #玩家手中的牌        self.type=0# 每个人初始都假定为三张毫无关系的牌,也就是扑克牌赢法中的“单张”    defset_card_score(self, card):        '''        按照点数判定扑克牌的大小        :param card:扑克牌卡片        :return:扑克牌点数大小        '''        rank_value =Poker.ranks.index(card.rank)        suit_values =Poker.suit_values        returnrank_value *len(suit_values) +suit_values[card.suit]    defsort_card_index(self, rank_index_list):        '''        通过值减下标的方式分组,如果三个值连续则被分配到同一个g中        比如说ll=[3,4,5,7,8],分组时,enumerate(ll)=[(0,3),(1,4),(2,5),(3,7),(4,8)],fun函数值减下标,结果一样的,就归为一组        在本程序中,如果是三张连续的扑克牌,则应该是同一个g中,此时返回为Ture,否则为False        :param rank_index_list:        :return:        '''        fun =lambdax: x[1] -x[0]        fork, g ingroupby(enumerate(rank_index_list), fun):  # 返回一个产生按照fun进行分组后的值集合的迭代器.            iflen([v fori, v ing]) ==3:                returnTrue        returnFalse    defjudge_type(self):        '''        玩家随机发完三张牌后,根据扑克牌玩法进行区分,对手中的牌进行判别属于哪种类型        :return:        '''        suit_list =[]        rank_list =[]        score_list =[]        forpoker inself.pokers:            suit_list.append(poker.suit)            rank_list.append(poker.rank)            score_list.append(poker.score)        rank_index_list =[]  # 扑克牌卡片在Poker中rank中的index        forrank inrank_list:            index =self.poker.ranks.index(rank)            rank_index_list.append(index)        iflen(set(rank_list)) ==1:            self.type=5# 豹子        eliflen(set(suit_list)) ==1:            ifself.sort_card_index(rank_index_list):                self.type=4# 顺金            else:                self.type=3# 金花        elifself.sort_card_index(rank_index_list):            self.type=2# 顺子        eliflen(set(rank_list)) ==2:            self.type=1# 对子    defplay(self):        self.judge_type() | 
每位玩家都有一个名称,用同一副扑克牌,炸金花游戏要求每人手中有三张牌,根据手中的牌,程序初步判断属于哪种牌型,用于后续游戏取胜机制做判断。
三、Winner 类(游戏取胜机制)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | classWinner():    def__init__(self, player1, player2):        self.player1 =player1        self.player2 =player2    defget_max_card(self, player):        '''        筛选出三张牌中最大的牌,这里返回的是在ranks中的index        :param player:        :return:        '''        ranks =Poker.ranks        rank_index_list =[]  # 扑克牌卡片在Poker中rank中的index        forpoker inplayer.pokers:            index =ranks.index(poker.rank)            rank_index_list.append(index)        returnmax(rank_index_list)    defget_card_suit(self, player):        '''        返回扑克牌花色大小        :param player:        :return:        '''        suit_values =Poker.suit_values        suit =player.pokers[0].suit        returnsuit_values[suit]    defget_card_value(self, player):        '''        当牌型是对子的时候,经过匹配找出是对子的牌和单个的牌,这里返回的是牌的index,便于比较大小        :param player:        :return:        '''        ranks =Poker.ranks        rank_index_dict ={}  # 扑克牌卡片在Poker中rank中的index        repeat_rank_value =0# 成对的两张扑克牌的大小        single_rank_value =0# 单个的扑克牌的大小        forpoker inplayer.pokers:            index =ranks.index(poker.rank)            ifindex inrank_index_dict:                rank_index_dict[index] +=1            else:                rank_index_dict[index] =1        rank_index_dict =sorted(rank_index_dict.items(), key=lambdad: d[1], reverse=True)        n =0        forkey inrank_index_dict:            ifn ==0:                repeat_rank_value =key            else:                single_rank_value =key            n +=1        returnrepeat_rank_value, single_rank_value    defget_player_score(self, player):        '''        当牌型为单牌时,计算手中的牌相加后的值大小        :param player:        :return:        '''        ranks =Poker.ranks        score =0        forpoker inplayer.pokers:            index =ranks.index(poker.rank)  # 扑克牌卡片在Poker中rank中的index            score +=index        returnscore    defget_winner(self):        player1, player2 =self.player1, self.player2        # 先比较玩家手中的牌型,大的胜出,玩牌的规则暂时不涉及到牌色,如有修改可以在此基础上调整        # 豹子> 顺金 > 金花 > 顺子 > 对子 > 单张        ifplayer1.type> player2.type:            returnplayer1        elifplayer1.type< player2.type:            returnplayer2        else:  # 当玩家双方手中的牌型一致时,根据赢法一一判断            ifplayer1.type==5orplayer1.type==4orplayer1.type==2:  # 豹子、顺金、顺子 规则说明:按照比点                ifself.get_max_card(player1) > self.get_max_card(player2):                    returnplayer1                else:                    returnplayer2            elifplayer1.type==1:  # 对子 规则说明:先比较相同两张的值的大小,谁大谁胜出;如果对子相同,再比较单个                repeat_rank_value1, single_rank_value1 =self.get_card_value(player1)                repeat_rank_value2, single_rank_value2 =self.get_card_value(player1)                ifrepeat_rank_value1 > repeat_rank_value2:                    returnplayer1                elifrepeat_rank_value1 < repeat_rank_value2:                    returnplayer2                else:                    ifsingle_rank_value1 > single_rank_value2:                        returnplayer1                    elifsingle_rank_value1 < single_rank_value2:                        returnplayer2                    else:                        returnNone# 平局,大家手上的牌一样大            else:  # 单牌,金花   规则:比较所有牌的点数大小,不区分牌色                ifself.get_player_score(player1) > self.get_player_score(player2):                    returnplayer1                elifself.get_player_score(player1) < self.get_player_score(player2):                    returnplayer2                else:                    returnNone | 
由于不是很清楚炸金花的游戏规则,这里我们采用的是最简单的游戏规则。
牌型 豹子:三张同样大小的牌。顺金:花色相同的三张连牌。金花:三张花色相同的牌。 顺子:三张花色不全相同的连牌。 对子:三张牌中有两张同样大小的牌。单张:除以上牌型的牌。
玩法比较简单,豹子> 顺金 > 金花 > 顺子 > 对子 > 单张,当牌型不一致的话,谁牌型大谁胜出;当牌型一致的时候,又分为三种情况,一是豹子、顺金、顺子,比较玩家手中牌的最大值,谁拥有最大牌面值谁胜出;二是对子,比较玩家手中对子的牌面大小,如果相同再另行比较;三是金花、单张,比较玩家手中所有牌面大小之和。
除了上述三个对象类外,还需要一个发牌者(荷官)来主持洗牌和发牌。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | defcompare_card(card1, card2):    '''    比较两种扑克牌是否相同    :param card1:    :param card2:    :return: 相同返回为True,否则为False    '''    ifcard1.rank ==card2.rank andcard1.suit ==card2.suit:        returnTrue    returnFalsedefdutch_official_work(poker, player1, player2):    '''    发牌人(荷官)给两位玩家轮替发牌,发出去的牌都需要从这副扑克牌中剔除出去    :param poker: 那一副扑克牌    :param player1:玩家1    :param player2:玩家2    :return:整理后的扑克牌    '''    defdistribute_card(player):        card =choice(poker)  # 发牌        player.pokers.append(Own_Poker(player.id, card.rank, card.suit, player.set_card_score(card)))        fori inrange(len(poker)):            ifcompare_card(card, poker[i]):                poker.__delitem__(i)                break    shuffle(poker)  # 洗牌    fork inrange(3):        distribute_card(player1)        distribute_card(player2)    returnpoker | 
详细代码可以访问 https://github.com/Acorn2/fluentPyStudy/blob/master/chapter01/Poker_Demo.py
到此这篇关于Python实现炸金花游戏的示例代码的文章就介绍到这了,更多相关Python 炸金花游戏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!