ludolulu 发表于 2020-3-7 22:54:25

新手python38课作品---金字塔卡牌游戏

法国读书的时候,跟法国人喝酒学会玩的一个游戏,金字塔(Pyramide). 用的方法都是小甲鱼老师课上教的,感觉应该会有很多有待优化精简的部分。。。有没有大佬有耐心看看给点建议的,不胜感激.

金字塔游戏解说

首先,这是一个来自古埃及的卡牌游戏。。。

每位玩家会拿到4张牌。玩家要先看清自己的牌,并记住买张牌的顺序!!!玩家不能向他人透露自己的卡牌。 法老有情提示:顺序真的很重要哦。
金字塔形的公共牌一共有4行,从底行到顶行每行牌数,及对应惩罚基数分别为4张(每张1分),3张(每张2分),2张(每张3分),1张(每张4分)。
公共牌会从底行开始依次翻开。
每张公共牌翻开后,玩家之间可以互相自由发起挑战,每个玩家只能挑战一次。

挑战规则如下:

1.挑战发起者可以质疑他所选中的玩家,“你相信我有N张这张公共牌么?”,一张公开牌最多挑战3个人次,可以是同一个人哦。

    【例子】比如有A,B,C三个玩家,该轮公共牌是第3行的"2":A向B,C发起挑战:“B,你相信我有两张2么?”(消耗2个人次)
                                                                         “C, 你相信我有1张2么?”(消耗1个人次)
                                                         A总共发出3个人次挑战。

    因为扑克牌相同个号码最多4张,(我们这里去除大小王),玩家手里至多有3张同号,公开牌才会有可能出现1张,所以N<=3。

2.挑战发出后,被挑战者可以选择完全相信,部分相信,完全不信。
    完全相信:选择妥协,积分扣除(被挑战张数*该公开牌惩罚基数),个人不相信张数=0
    部分相信:相信的张数同上操作,扣除惩罚基数,个人不相信张数记入总不相信张数。
    完全不信:被挑战张数全部计入总不相信张总数。

    接着上方【例子】,若:B选择相信A有1张2,则B先扣2分,个人不相信张数=1,C同时选择不相信A,总不相信张数=2。
                     若:B选择相信A有两张2,则B扣4分,个人不相信张数=0,C选择不相信A,总不相信张数=1。
                  
3.被挑战者回应后,如果总不相信张数不等于0,则挑战者需要展示等量的个人卡牌序号,并验证这些序号对应的牌都等号于该公开牌,才算挑战成功。
    挑战成功:不相信玩家分别扣除(两倍惩罚基数*个人不相信张数)
    挑战失败:挑战玩家扣除(两倍惩罚基数*总不相信张数)

    接着上方【例子】,若:A 选择自己第1和第3张牌,经过验证,确实都等于2。则挑战成功:B,C分别扣除4分。
                     若:A 选择自己第1和第3张牌,经过验证,不都等于2。则挑战失败:A扣除8分。
   
当没有任何玩家再争对此公开牌发起挑战后,开始翻起下一张公共牌,一直到金字塔顶。

玩家起始分都为0分,最终分最低者失败,需要喝酒哦!法老悄悄告诉你,其实在古埃及,每扣一分就要喝一口哦。

游戏过程中,忘记自己卡牌或顺序的玩家可以点击Help来查询自己的卡牌,不过会扣除5分哦!

介绍有点长。。。清楚明白那就开始吧!!!!

import random
import easygui as g


def game():
    cartes=(list(range(2,11))+['J','Q','K','A'])*4    #去掉大小王52张牌集
    random.shuffle(cartes)                            #洗牌
    rang=    #公开牌金字塔型
    sum_rang=rang
    base=1          #惩罚基数或者行数
    global name_info
    for i in range(num_players):
      name=g.enterbox('N.%d player, pls enter your name:'%(i+1))
      g.msgbox('We are going to distribute carte,make sure there\'s no others!!!',ok_button='K')
      player_carte=[]
      for j in range(4):
            player_carte.append(cartes.pop())    #给每个玩家发牌
      dictplayer=Player(name,player_carte)#实例化玩家对象
      name_info+='N.%d player :%s\n'%((i+1),name)   #记录所有玩家名称及对应编号
      g.msgbox('Please remember your cartes and its ORDERS!!!And then press OK\n'+str(dictplayer.cartes),ok_button='K')
      
    for i in range(sum(rang)):   
      open_carte=cartes.pop()   #翻公开牌
      if i>=sum_rang:      #让惩罚基数对应行数增加
            sum_rang+=rang
            base+=1
      while True:
            temp=g.buttonbox('\nThe N.%d open carte is :【%s】\nThe base is %d POINTS now.\n\nAnyone dares to CHALLANGER ??? '%(i+1,open_carte,base),choices=('es','o','elp','heck scores'))
            if temp=='o':
                break
            if temp=='es':
                challenging(open_carte,base)#进入挑战环节
                score()   #显示当前分数
            if temp=='elp':
                please_help_me()
            elif temp=='heck scores':
                score()
               
    score(a=0)
   
            
def challenging(open_carte,base):   #挑战功能
    num_challenger=int(g.enterbox('Who\'s challenging ? Enter player number pls.\n\n'+name_info))-1    #挑战者编号
    listnum_challenged=list(range(1,num_players+1))   
    listnum_challenged.remove(num_challenger+1)#去掉自身编号
    listnum_challenged=listnum_challenged*3
    listnum_challenged.sort()
    listnum_challenged=g.multchoicebox('Who\'s the target ?\nChoose player number please,you have AT MOST 3 choices,it can be the same person ! \n\n'\
                                       +name_info,choices=listnum_challenged)
    listnum_challenged=list(map(int,listnum_challenged))    #被挑战者编号列表,该功能将列表字符串都变成整数
    list_dontbelieve=[] #被挑战而且不信的人编号
    name_dontbelieve=[] #被挑战且不信的人名
    already=[]   #已经提问过的被挑战者
    count_dontbelieve=0#总共不相信人次
    for i in listnum_challenged[:]:
      if i not in already:    #已出现过的被挑战者不再重复出现
            already.append(i)
            num_challenged=i-1    #单个被挑战者编号
            times=listnum_challenged.count(i)   #该玩家被挑战次数
            
            def compromise(a,b):    #编号b玩家,被a次挑战并完全妥协
                        g.msgbox('Oh! %s, you will never know the truth...'%dictplayer.name,ok_button='K')
                        dictplayer.credit-=base*a   #妥协相信扣一倍基数
            def dontBelieve(a,b):    #编号b玩家,仅相信a次,不完全信
                        nonlocal times,count_dontbelieve
                        dictplayer.credit-=base*a
                        dictplayer.base=base*(times-a)   #记录该玩家直面挑战的倍数
                        list_dontbelieve.append(b)
                        name_dontbelieve.append(dictplayer.name)
                        count_dontbelieve+=(times-a)
            if times>1:   #被挑战多次
                temp=int(g.enterbox('%s, you are challenged for %d times, how many times do you trust %s ?'\
                              %(dictplayer.name,times,dictplayer.name)))
            else:#被挑战一次
                temp=g.ynbox('%s,do you trust %s ?'%(dictplayer.name,dictplayer.name))
                if temp=='Yes':
                  temp=1
            if temp==times : #完全妥协
                compromise(temp,num_challenged)
            else:
                dontBelieve(temp,num_challenged)
                  
    name_dontbelieve=' & '.join(name_dontbelieve) #去掉首尾'[]'
    if list_dontbelieve!=[]:       #如果还有人不相信
      temp=g.multchoicebox('%s,you have to entre in TOTAL%dcartes to convince %s'\
                            %(dictplayer.name,count_dontbelieve,name_dontbelieve),choices=)#记录挑战者出示的牌序号
      temp=list(map(int,temp))

      for each in temp:   #检查出示的每张卡牌
         win=1
         if dictplayer.cartes==open_carte:    #若相等,则继续
               continue
         else:
               win=0               #任一张不等则输
               break
      if win:
            for each in list_dontbelieve:
               dictplayer.credit-=2*dictplayer.base#挑战者成功,不信的被挑战者依次扣不信张数乘2倍基数
            g.msgbox('AMAZINGGG!!!%s,you really got %d 【%s】'%(dictplayer.name,count_dontbelieve,open_carte),ok_button='K')
      else:            #挑战者失败,挑战者扣2倍基数*坚持不信人数
            dictplayer.credit-=2*base*count_dontbelieve
            g.msgbox('Bravooooo!!!%s, %s is a big liar!'%(name_dontbelieve,dictplayer.name),ok_button='K')

            
   
def score(a=1):   #当前分数展示
    text=''
    min=0
    title='Current scores !'
    pic=''
    for i in range(num_players):
      if dictplayer.credit<min:   #计算最低分玩家
            min=dictplayer.credit
            min_num=i
      text+='N.%d player:%-5s, your score is %2d.\n'%(i+1,dictplayer.name,dictplayer.credit)
    if a:
      pass
    else:
      text+='\n\n%s, you are looser! Finish your beer !!!'%dictplayer.name
      title='GAME OVER!!!'
    g.msgbox(text,title,ok_button='K')


def please_help_me():   #忘牌提示
    num=g.enterbox('Who wants to see his cartes ? Enter player number pls:\n\n'+name_info)
    if num:
      num=int(num)-1
      temp=g.ynbox('%s,are you sure ? It will cost you 5 points !!!'%dictplayer.name)
      if temp:
            g.msgbox(dictplayer.cartes,ok_button='K')
            dictplayer.credit-=5
            score()
      else:
            print('Carry on, trust yourself !!!',ok_button='K')


class Player:   #玩家类
   credit=0
   base=1
   def __init__(self,name,cartes):
       self.name=name
       self.cartes=cartes
   

dictplayer={}
name_info='' #记录所有玩家名称及对应编号
num_players=int(g.enterbox('Please enter number of players:',title='欢迎来到神秘的古埃及!!!'))

game()
页: [1]
查看完整版本: 新手python38课作品---金字塔卡牌游戏