记录一次面向对象程序设计的尝试

【写在前面:其实我也不知道这是不是面向对象,感觉上是吧= =毕竟非计算机专业的课教得太浅,比较深的计算机专业课一方面没时间去蹭课,另一方面也怕听不懂……】

最近一不小心沉迷于某个卡牌游戏,奈何游戏内的玩家有点少,尤其是半夜很难凑成一房(而且没有开挂的乐趣),于是就想试着给自己写个陪玩。

游戏名叫“炸弹猫”,规则大致是这样的:

  • 各个玩家轮流摸牌,摸到炸弹如果没有“解除”卡牌,即出局。
  • 各个卡牌有不同的作用。
  • 最后未出局的玩家获胜。

卡牌有很多种,包括解除(解除炸弹)、跳过(跳过本轮摸牌)、反转(跳过本轮摸牌并改变顺逆时针)、攻击(叠加摸牌次数转移给某人)、侦察(查看牌堆顶X张牌)、洗牌、抽底(抽牌堆底部)、乞讨(向其他玩家索要一张)……当然,还有炸弹(没有解除的情况下摸到就出局)。

正好学了一个学期的python,于是就打算从零开始先完成游戏的基本逻辑,再写个AI陪玩。

整体思路是这样的:一共三个类,一个牌堆类,用于控制牌堆和玩家的手牌(堆);一个玩家类,用于存一些玩家状态;一个游戏控制类,呃……我也不知道怎么说这个部分,反正整个游戏的判断逻辑都写在这个里面。其实我也不知道为什么要这么分= =好像一开始写的时候没这么打算的,写着写着就这样了……好在最后能跑起来。所以这样应该算是面向对象了吧……

至于AI部分,原计划是打算写在一个AI控制类里的,但是不知道怎么就写到游戏控制逻辑里面去了= =而且还有很严重的bug(比如AI明明使用了侦查看到了下一张牌是炸弹,还去摸这张牌死了)。由于当时没有很清楚地理清AI的逻辑,先一股脑儿写然后就成这坨烂代码了……改也改不好……记录一下以此为戒!

这应该是我第一次面向对象程序设计的尝试,可以说是有点失败了233没能达到自己的预期。不过至少自己和自己斗智斗勇还是可以的,还可以加几个弱智AI陪玩2333

 

最后附上github地址和游戏效果图(懒得写GUI了,命令行凑合一下):https://github.com/RainbowHerry/boomcat

 

import random
class Card:
    cardlist=["0解除","1跳过","2反转","3攻击","4侦察","5洗牌","6抽底","7乞讨","8自爆","9炸弹"]
    def __init__(self,num,pile=False):
        self.num=num
        if(pile):
            self.lst=[random.randint(0,8) for ovo in range(self.num-1)]+[9]*(pile-1)+[7]*pile
            random.shuffle(self.lst)
        else:
            self.lst=[0]+[random.randint(1,8) for ovo in range(self.num-1)]
    def _showlist(self):
        for i in self.lst:
            print(self.cardlist[i],end=" ")
        print()
    def delwhere(self,where):
        del self.lst[where]
    def delwhat(self,what):
        loc=self.lst.index(what)
        del self.lst[loc]
    def foreseelist(self,where):
        print("你看到了:",end="")
        if(where>=len(self.lst)):
            where=len(self.lst)-1
        for i in range(where-1):
            print(self.cardlist[self.lst[i]],end=",")
        print(self.cardlist[self.lst[where]],end="!\n")
    def shufflelist(self):
        random.shuffle(self.lst)
    def takeone(self,up=True):
        if(up):
            cardtaken=self.lst[0]
            del self.lst[0]
        else:
            cardtaken=self.lst[-1]
            del self.lst[-1]
        return cardtaken
    def addone(self,crd):
        self.lst.append(crd)
    def addwhere(self,crd,where):
        self.lst.insert(where,crd)
    def locate9(self):
        return self.lst.index(9)
    def locatewhat(self,what):
        try:
            return self.lst.index(what)
        except:
            return False
    def takewhere(self,where):
        cardtaken=self.lst[where]
        del self.lst[where]
        return cardtaken
    def __str__(self):
        res=""
        for i in self.lst:
            res+=self.cardlist[i]+" "
        return res

class Player:
    num=0
    #There are some bugs in AI part. If you need to play with AI, change "ai=False" to "ai=True"
    def __init__(self,ai=False):
        self.num=Player.num
        Player.num+=1
        self.card=Card(5)
        self.alive=True
        self.times=0
        self.ai=ai
    def __str__(self):
        return str(self.num)+";"+str(self.card)+";"+str(self.alive)+";"+str(self.times)
    def isalive(self):
        return self.alive
    def isai(self):
        return self.ai
        
class GameCtrl:
    def __init__(self,playernum):
        self.playernum=playernum
        self.pile=Card(playernum*7,pile=playernum)
        self.playerlst=[]
        self.alivelst=[]
        self.runing=True
        self.winner=""
        self.r=False
        for i in range(self.playernum-1):
            self.playerlst.append(Player())
        self.playerlst.append(Player(ai=False))
        self.alivelst=self.playerlst.copy()
        self.turn=random.randint(0,playernum-1)
    def _showall(self):
        print("self.playernum:",self.playernum)
        print("self.pile:",self.pile)
        for i in self.playerlst:
            print("self.player:",i)
    def showbasicinfo(self):
        print(r"牌堆还有{0}张牌,抽中炸弹的几率为{1}%;".format(len(self.pile.lst),int((100*(len(self.alivelst)-1))/len(self.pile.lst))),end="")
        for i in self.alivelst:
            print(i.num,"号玩家还有",len(i.card.lst),"张牌;",sep="",end="")
        print()
    def nextturn(self):
        print("-"*10)
        alives=0
        for i in self.playerlst:
            if(i.isalive()):
                self.winner=i.num
                alives+=1
        if(alives==1):
            self.runing=False
        if(self.r):
            for ovo in range(self.playernum):
                if(self.turn<self.playernum-1):
                    self.turn+=1
                else:
                    self.turn=self.turn+1-self.playernum
                try:
                    if(self.playerlst[self.turn].isalive()):
                        break
                except:
                    self.turn=0
        else:
            for ovo in range(self.playernum):
                if(self.turn>0):
                    self.turn-=1
                else:
                    self.turn=self.turn-1+self.playernum
                
                try:
                    if(self.playerlst[self.turn].isalive()):
                        break
                except:
                    self.turn=self.playernum
    def dointurn(self):
        self.playerlst[self.turn].times+=1
        def aidointurn():
            def aitakeone():
                self.playerlst[self.turn].times-=1
                print(str(self.playerlst[self.turn].num)+"号玩家(BOT)牌堆摸了一张牌!")
                tko=self.pile.takeone()
                if(tko==9):
                    print(str(self.playerlst[self.turn].num)+"号玩家(BOT)摸到了炸弹!")
                    if "0" in str(self.playerlst[self.turn].card):
                        self.playerlst[self.turn].card.delwhat(0)
                        wh=random.randint(0,len(self.pile.lst)-1)
                        self.pile.addwhere(9,wh)
                        return False
                    else:
                        self.playerlst[self.turn].alive=False
                        del self.alivelst[self.alivelst.index(self.playerlst[self.turn])]
                        print(str(self.playerlst[self.turn].num)+"号玩家(BOT)阵亡!")
                        return True
                else:
                    self.playerlst[self.turn].card.addone(tko)                
            while self.playerlst[self.turn].times>0:
                atkus=False
                if(self.pile.locate9()-1>self.playerlst[self.turn].times):
                    if(self.playerlst[self.turn].card.locatewhat(8)):
                        if(random.randint(1,100)%4!=1):
                            self.playerlst[self.turn].card.delwhat(8)
                            print(str(self.playerlst[self.turn].num)+"号玩家(BOT)打出[自爆]!")
                            self.playerlst[self.turn].times+=2
                    if(aitakeone()):
                        break
                    else:
                        continue
                else:
                    if(self.playerlst[self.turn].card.locatewhat(4)):
                        print(str(self.playerlst[self.turn].num)+"号玩家(BOT)使用了[侦察]!")
                        self.playerlst[self.turn].card.delwhat(4)
                    if(self.pile.locate9()>1):
                        if(random.randint(1,100)%2==1):
                            if(aitakeone()):
                                break
                            else:
                                continue
                        if(random.randint(1,100)%2==1):
                            if(aitakeone()):
                                break
                            else:
                                continue
                    if(self.playerlst[self.turn].times):
                        seed=random.randint(1,100)
                        if(seed%2==0):
                            if(self.playerlst[self.turn].card.locatewhat(1)):
                                self.playerlst[self.turn].card.delwhat(1)
                                print(str(self.playerlst[self.turn].num)+"号玩家(BOT)打出[跳过]!")
                                self.playerlst[self.turn].times-=1
                                continue
                        if(seed%2==1):
                            if(self.playerlst[self.turn].card.locatewhat(2)):
                                self.playerlst[self.turn].card.delwhat(2)
                                print(str(self.playerlst[self.turn].num)+"号玩家(BOT)打出[反转]!")
                                self.r=not(self.r)
                                self.playerlst[self.turn].times-=1
                                continue
                        if(seed%2==1):
                            if(self.playerlst[self.turn].card.locatewhat(5)):
                                self.playerlst[self.turn].card.delwhat(5)
                                print(str(self.playerlst[self.turn].num)+"号玩家(BOT)打出[洗牌]!")
                                self.pile.shufflelist()
                                continue
                        if(seed%2==0):
                            if(self.playerlst[self.turn].card.locatewhat(6)):
                                if(self.pile.lst[-1]!=9):
                                    self.playerlst[self.turn].card.delwhat(6)
                                    print(str(self.playerlst[self.turn].num)+"号玩家(BOT)打出[抽底]!")
                                    crd=self.pile.takeone(up=False)
                                    if(crd!=9):
                                        self.playerlst[self.turn].card.addone(crd)
                                        self.playerlst[self.turn].times-=1
                                        continue
                                    else:
                                        if "0" in str(self.playerlst[self.turn].card):
                                            self.playerlst[self.turn].card.delwhat(0)
                                            wh=random.randint(0,len(self.pile.lst)-1)
                                            self.pile.addwhere(9,wh)
                                            continue
                                        else:
                                            self.playerlst[self.turn].alive=False
                                            del self.alivelst[self.alivelst.index(self.playerlst[self.turn])]
                                            print(str(self.playerlst[self.turn].num)+"号玩家(BOT)阵亡!")
                                            break
                        if(seed%5!=4):
                            if(self.playerlst[self.turn].card.locatewhat(7)):
                                self.playerlst[self.turn].card.delwhat(7)
                                qt=self.alivelst[random.randint(1,100)%len(self.alivelst)]
                                while(qt==self.playerlst[self.turn]):
                                    qt=self.alivelst[random.randint(1,100)%len(self.alivelst)]
                                qt=qt.num
                                print(str(self.playerlst[self.turn].num)+"号玩家(BOT)向"+str(qt)+"号玩家打出[乞讨]!")
                                self.playerlst[self.turn].card.addone(self.playerlst[qt].card.takewhere(-1))
                                continue
                        while(self.pile.locate9()<=1):
                            a=self.playerlst[self.turn].card.locatewhat(1)
                            b=self.playerlst[self.turn].card.locatewhat(2)
                            c=self.playerlst[self.turn].card.locatewhat(3)
                            if(a and b):
                                self.playerlst[self.turn].card.delwhat(1)
                                print(str(self.playerlst[self.turn].num)+"号玩家(BOT)打出[跳过]!")
                                atkus=True
                                self.playerlst[self.turn].times-=1
                                break
                            elif(a):
                                self.playerlst[self.turn].card.delwhat(1)
                                print(str(self.playerlst[self.turn].num)+"号玩家(BOT)打出[跳过]!")
                                atkus=True
                                self.playerlst[self.turn].times-=1
                                break
                            elif(b):
                                self.playerlst[self.turn].card.delwhat(2)
                                print(str(self.playerlst[self.turn].num)+"号玩家(BOT)打出[反转]!")
                                atkus=True
                                self.r=not(self.r)
                                self.playerlst[self.turn].times-=1
                                break
                            else:
                                if(c):
                                    self.playerlst[self.turn].card.delwhat(3)
                                    atk=self.alivelst[random.randint(1,100)%len(self.alivelst)]
                                    while(atk==self.playerlst[self.turn]):
                                        atk=self.alivelst[random.randint(1,100)%len(self.alivelst)]
                                    atk=atk.num
                                    atkus=True
                                    tmp=self.playerlst[self.turn].times
                                    self.playerlst[self.turn].times=0
                                    self.playerlst[atk].times=tmp+2
                                    self.turn=atk
                                    break                                
                    if(atkus):
                        continue
                    else:
                        if(aitakeone()):
                            break
                        else:
                            continue                                         
        if(self.playerlst[self.turn].isai()):
            aidointurn()
        else:
            self.showbasicinfo()
            while self.playerlst[self.turn].times>0:
                usecard=input("你是"+str(self.turn)+"号玩家("+str(self.playerlst[self.turn].times)+"次),手牌有:"+str(self.playerlst[self.turn].card)+"\n你要使用:")
                if(usecard=="" or (int(usecard) in self.playerlst[self.turn].card.lst)):
                    if(usecard=="0"):
                        print("解除不可主动打出!")
                    if(usecard=="1"):
                        self.playerlst[self.turn].card.delwhat(1)
                        self.playerlst[self.turn].times-=1
                    if(usecard=="2"):
                        self.playerlst[self.turn].card.delwhat(2)
                        self.r=not(self.r)
                        self.playerlst[self.turn].times-=1
                    if(usecard=="3"):
                        self.playerlst[self.turn].card.delwhat(3)
                        atk=input("你要攻击0-"+str(self.playernum-1)+"号玩家:")
                        try:
                            if(self.playerlst[int(atk)].alive):
                                tmp=self.playerlst[self.turn].times
                                self.playerlst[self.turn].times=0
                                self.playerlst[int(atk)].times=tmp+2
                                self.turn=int(atk)
                                self.dointurn()
                        except:
                            print("玩家无效!")
                            continue
                    if(usecard=="4"):
                        self.playerlst[self.turn].card.delwhat(4)
                        self.pile.foreseelist(3)
                    if(usecard=="5"):
                        self.playerlst[self.turn].card.delwhat(5)
                        self.pile.shufflelist()
                    if(usecard=="6"):
                        self.playerlst[self.turn].card.delwhat(6)
                        crd=self.pile.takeone(up=False)
                        if(crd!=9):
                            self.playerlst[self.turn].card.addone(crd)
                            self.playerlst[self.turn].times-=1
                            continue
                        else:
                            if "0" in str(self.playerlst[self.turn].card):
                                self.playerlst[self.turn].card.delwhat(0)
                                wh=input("BOOM!你要把炸弹放在第0-"+str(len(self.pile.lst)-1)+"张:")
                                try:
                                    self.pile.addwhere(9,int(wh))
                                except:
                                    self.pile.addwhere(9,0)
                                continue
                            else:
                                self.playerlst[self.turn].alive=False
                                print("你("+str(self.turn)+"号玩家)摸到炸弹阵亡了!")
                                del self.alivelst[self.alivelst.index(self.playerlst[self.turn])]
                                break
                                
                        self.playerlst[self.turn].times-=1
                    if(usecard=="7"):
                        self.playerlst[self.turn].card.delwhat(7)
                        #
                        qt=input("你要向0-"+str(self.playernum-1)+"号玩家乞讨:")
                        try:
                            if(self.playerlst[int(qt)].alive):
                                self.playerlst[self.turn].card.addone(self.playerlst[int(qt)].card.takewhere(-1))
                        except:
                            print("玩家无效!")
                            continue
                    if(usecard=="8"):
                        self.playerlst[self.turn].card.delwhat(8)
                        self.playerlst[self.turn].times+=2
                    if(usecard==""):
                        self.playerlst[self.turn].times-=1
                        tko=self.pile.takeone()
                        if(tko==9):
                            if "0" in str(self.playerlst[self.turn].card):
                                self.playerlst[self.turn].card.delwhat(0)
                                wh=input("BOOM!你要把炸弹放在第0-"+str(len(self.pile.lst)-1)+"张:")
                                try:
                                    self.pile.addwhere(9,int(wh))
                                except:
                                    self.pile.addwhere(9,0)
                                continue
                            else:
                                self.playerlst[self.turn].alive=False
                                print("你("+str(self.turn)+"号玩家)摸到炸弹阵亡了!")
                                del self.alivelst[self.alivelst.index(self.playerlst[self.turn])]
                                break
                        else:
                            self.playerlst[self.turn].card.addone(tko)                                 
                else:
                    print("此卡不存在!")
                    continue
            

gc=GameCtrl(4)
while(gc.runing):
    #gc._showall()
    gc.dointurn()
    gc.nextturn()

print("游戏结束!获胜的是",gc.winner,"号玩家。",sep="")

目前评论:1   其中:访客  0   博主  0


    Warning: A non-numeric value encountered in /www/wwwroot/i.pegasi.top/wp-content/themes/begin/inc/function/comment-template.php on line 31
  1. avatar sekaino

    Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/wwwroot/i.pegasi.top/wp-content/themes/begin/inc/function/setting.php on line 1367
评论加载中...

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

图片 表情