Example #1
0
 def askAnKang(self):
     posibleMinset = self.canAnKang()
     #print(posibleMinset)
     if len(posibleMinset) == 0:
         return False
     elif len(posibleMinset) == 1:
         ankang = self.inputS("Do you want to 暗槓" +
                              Pai.showHand(posibleMinset[0]) + "? y/n: ")
         if ankang == "y":
             self.minset = posibleMinset[0]
             self.printS("You selected {}".format(Pai.showHand(
                 self.minset)))
             return True
         else:
             return False
     else:
         ankang = self.inputS("Do you want to 暗槓? y/n: ")
         if ankang == "y":
             idx = int(
                 self.inputS(
                     "Which set do you want to 暗槓? Please input the number(1~) \n"
                     +
                     str([Pai.showHand(minset)
                          for minset in posibleMinset]) + ": ")) - 1
             self.minset = posibleMinset[idx]
             print("You selected {}".format(Pai.showHand(self.minset)))
             return True
         else:
             return False
Example #2
0
    def pon(self, paiCut):
        """
        Perform pon.
        
        Args:
            paiCut (int,int): index of Pai cut by other Players.
        
        """
        t, n = paiCut
        a = Pai.hand2Array(self.hand)
        assert (np.sum(a[t]) >= 2)
        # search for tile in hand
        tile = []
        for i in range(4):
            if len(tile) >= 2:
                break

            if a[t, i] == 1:
                a[t, i] = 0
                tile.append((t, i))
        # add at the end to indicate the pai taken from others
        tile.append(paiCut)
        # record in openHand
        self.openHand['pon'].append(tile)
        self.hand = Pai.array2Hand(a)
        return 'pon'
def showTesthand(test):
    hand = []
    for s in test[0]:
        for p in s:
            hand.append(p)
    ophand = []
    for s in test[1]:
        for p in s:
            ophand.append(p)
    return Pai.showHand(hand) + Pai.showHand(ophand)
Example #4
0
 def askChi(self,posibleMinset):
     minchi = input("Do you want to 吃? y/n: ")
     if minchi ==  "y":
         chi_prompt = "Select from: \n"
         for i, option in enumerate(posibleMinset):
             chi_prompt += "{}. {} ".format(i+1, Pai.showHand(option))
         select = input(chi_prompt)
         print("You selected {}".format(Pai.showHand(posibleMinset[int(select)-1])))
         self.minset = posibleMinset[int(select)-1]
         return True
     else:
         self.minset = []
         return False
Example #5
0
    def askRiichi(self):
        if self.isRiichi:
            return False
        if self.openHand["chi"] or self.openHand["pon"] or self.openHand[
                "minKang"]:
            return False
        cutpais = []
        for pai in self.hand:
            hand = self.hand.copy()
            hand.remove(pai)
            if breakdown(hand, self.getOpenHand()) != []:
                cutpais.append(pai)

        if cutpais != []:
            # interaction
            i = int(
                self.inputS(
                    "You can 立直! If you Do not want to 立直 Please press '0'\n Which Pai do you want to cut? (1~) \n"
                    + Pai.showHand(cutpais) + ": "))
            if i == 0:
                self.isRiichi = False
            else:
                self.isRiichi = True
                self.riichipai = cutpais[i - 1]
            return self.isRiichi
Example #6
0
 def printWinner(self):
     if self.winner == None:
         print(
             "---------------------------NO ONE WIN-------------------------\n"
         )
     else:
         player = self.winner
         yaku = self.playerYaku[self.players.index(player)]
         content = ""
         if player == None:
             content += "No One Wined" + "\n"
         else:
             content += "###############################################################################################\n"
             content += "Player " + player.name + " Win!!\n"
             content += "Scores: " + str(player.score) + "\n"
             content += "役: " + yaku.judgeRon + "\n"
             player.hand.sort()
             player.hand.append(self.lastPai)
             ophand = reduce(lambda x, y: x + y,
                             list(map(Pai.showHand, player.getOpenHand())),
                             "")
             content += str(Pai.showHand(player.hand)) + ophand + "\n"
             content += "################################################################################################\n"
             content += "WINNER is " + player.name + "\n"
             content += "\n\(・ω・\)" + player.name + "!(/・ω・)/恭喜你!\n"
         print(content)
Example #7
0
    def startGame(self):
        self.baopaiCount = -1
        self.baopai = [self.yama[self.baopaiCount]]
        self.baopaiCount -= 1
        self.libaopai = [self.yama[self.baopaiCount]]
        self.baopaiCount -= 1
        self.redbaopai = [(4, 0), (13, 0), (13, 1), (22, 0)]
        for wind, player in zip(["東", "南", "西", "北"], self.players):
            hand = self.yama[:13]
            self.yama = self.yama[13:]
            # call player's method
            player.setWind(wind)
            # player.setHand(hand)
            player.setHand([(p, 0) for p in Pai.parsedPai("222444m333555s2p")])
            player.baopai = self.baopai
            player.libaopai = self.libaopai
            player.redbaopai = self.redbaopai

        self.cutPai = None
        self.state = "SET_PLAYER"
        self.winner = None
        self.playerCounter = np.zeros([4])
        self.minCounter = np.zeros([4, 4])
        self.riichiTurn = [(0, False)] * 4
        self.playerTumo = [False, False, False, False]
        self.playerYaku = [""] * 4
        self.rinxian = False
        print("Prepared\nLet's Start the GAME !!\n")
Example #8
0
 def askPon(self,posibleMinset):
     minpon = input("Do you want to 碰"+Pai.showHand(posibleMinset)+"? y/n: ")
     if minpon == "y":
         self.minset = posibleMinset
         return True
     else:
         self.minset = []
         return False
Example #9
0
 def playerChi(self, player):
     minSet = player.chi()
     content = ""
     content += "################################################################################################\n"
     content += "Player " + player.name + " did 吃 \n"
     content += "Set is " + str(Pai.showHand(minSet)) + "\n"
     content += "#################################################################################################\n"
     print(content)
Example #10
0
 def playerChi(self,player):
     minSet = player.chi(self.cutPai)
     content = ""
     content += "################################################################################################\n"
     content += "Player "+player.name+" did 吃 \n"
     content += "Set is "+str(Pai.showHand(minSet))+"\n"
     content += "#################################################################################################\n"
     self.printEveryOne(content)
Example #11
0
 def playerPon(self, player):
     minSet = player.pon(self.cutPai)
     content = ""
     content += "################################################################################################\n"
     content += "Player " + player.name + " did PON \n"
     content += "Set is " + str(Pai.showHand(minSet)) + "\n"
     content += "#################################################################################################\n"
     print(content)
Example #12
0
 def printPlayerTurn(self,player,pai):
     content = ""
     content += "宝牌: "+Pai.showHand(self.baopai)+"\n"
     # print each players River (already cut Pais)
     for p in self.players:
         # player.river is Pais player already cut
         content += "Player "+p.name+"'s River is "+Pai.showHand(p.river)+"\n"
     for p in self.players:
         # player.min is player's min Pai already got
         if p == player:
             content += "----------------------------------------------------\n"
             content += "Main Player :"+player.name+"\n"
             content += "Min Pai :"+player.strOpenHand()+"\n"
             content += "Player's Hand: "+Pai.showHand(player.hand)+"\n"
             content += "----------------------------------------------------\n"
             continue
         #content += "Player "+p.name+"'s Hand is "+"SECRET"+"\n"
         content += "Player "+p.name+"'s Min Pai is "+p.strOpenHand()+"\n"
     return content
Example #13
0
 def askMinKang(self,posibleMinset):
     #print(posibleMinset)
     if len(posibleMinset)==0:
         return False
     else:
         minkang = input("Do you want to 槓"+Pai.showHand(posibleMinset)+"? y/n: ")
         if minkang == "y":
             self.minset = posibleMinset
             return True
         else:
             return False
 def playerKakan(self,player):
     minSet = player.jiagang(self.cutPai)
     self.baopai.append(self.yama[self.baopaiCount])
     self.baopaiCount -= 1
     self.libaopai.append(self.yama[self.baopaiCount])
     self.baopaiCount -= 1
     for p in self.players:
         p.baopai = self.baopai
         p.libaopai = self.libaopai
     content = ""
     content += "Player "+player.name+" did JIAKAN \n"
     content += "Set is "+str(Pai.showHand(minSet))+"\n"
     self.sendEveryOne(content)
Example #15
0
 def checkWait(self):
     """
     [[Int]]
     return a list of list of tenpai
     """
     b = breakdown(self.hand,self.getOpenHand())
     ten = [[] for i in range(len(b))]
     seq2_count = 0
     # find all ten
     for i, possibility in enumerate(b):
         for form in possibility:
             if len(form) == 2:
                 if has_seq2(form):
                     seq2_count += 1
                     a = Pai.previous(form[0]) 
                     if a is not None: ten[i].append(a)
                     b = Pai.next(form[1])
                     if b is not None: ten[i].append(b)
                 if has_pair(form) and seq2_count == 0:
                     ten[i].append(Pai.same(form[0]))
             if len(form) == 1:
                 ten[i].append(Pai.same(form[0]))
     return ten
Example #16
0
 def playerKan(self, player, anKang=False):
     minSet = player.kan(self.cutPai, anKang=anKang)
     self.baopai.append(self.yama[self.baopaiCount])
     self.baopaiCount -= 1
     self.libaopai.append(self.yama[self.baopaiCount])
     self.baopaiCount -= 1
     for p in self.players:
         p.baopai = self.baopai
         p.libaopai = self.libaopai
     content = ""
     content += "################################################################################################\n"
     content += "Player " + player.name + " did KAN \n"
     content += "Set is " + str(Pai.showHand(minSet)) + "\n"
     content += "#################################################################################################\n"
     print(content)
 def printWinner(self):
     if self.winner == None:
         self.sendEveryOne("NO ONE WIN\n")
     else:
         player = self.winner
         yaku = self.playerYaku[player.idx]
         content = ""
         content += "Player "+player.name+" Win!!\n"
         content += "Scores: "+str(player.score)+"\n"
         content += "役: "+yaku.judgeRon+"\n"
         player.hand.sort()
         player.hand.append(self.lastPai)
         content += str(Pai.showHand(player.hand))+"\n"
         content += "\n\(・ω・\)"+player.name+"!(/・ω・)/恭喜你!\n"
     self.sendEveryOne(content)
Example #18
0
 def strOpenHand(self):
     ophand = {}
     for k,msets in self.openHand.items():
         ophand[k] = [Pai.showHand(mset) for mset in msets]
     return str(ophand)
 def playerPon(self,player):
     minSet = player.pon(self.cutPai)
     content = ""
     content += "Player "+player.name+" did PON \n"
     content += "Set is "+str(Pai.showHand(minSet))+"\n"
     self.sendEveryOne(content)
    def GameFSM(self):
        self.setSockets()
        self.startGame()
        
        while not self.zeroYama() and len(self.baopai)<5:

            # STATE "SET_NEXT_PLAYER"
            if self.state == "SET_PLAYER":
                self.player = self.players[(self.player.idx+1) % 4]
                self.playerCounter[self.player.idx] += 1
                #self.sendEveryOne("MAIN PLAYER: "+self.player.name+" | WIND: "+self.player.wind+" | Turn:"+str(int(sum(self.playerCounter))))
                self.state = "GIVE_PAI"

            # STATE "GIVE_PAI_TO_PLAYER"
            elif self.state == "GIVE_PAI" or self.state == "KAN":
                if self.state == "KAN":
                    self.rinxian = True
                pai = self.yama[0]
                self.yama = self.yama[1:]
                # check Tumo
                win, yaku = self.player.checkTumo(pai)
                if win:
                    self.state = "WIN"
                    self.winner = self.player
                    self.playerYaku[self.player.idx] = yaku
                    self.playerTumo[self.player.idx] = True
                    self.lastPai = pai
                    break
                self.player.givePai(pai)
                self.rinxian = False
                # check ankang
                anKang  = player.askAnKang()
                #print(anKang)
                if anKang:
                    self.playerKan(player,anKang=True)
                    self.state = "KAN"
                    continue
                # check Riici
                riichi = player.askRiichi()
                #print(riichi)
                jiaGang = player.askJiaGang()
                #print(jiaGang)
                if riichi:
                    self.playerRiichi(player)
                    self.state = "CUT"
                elif jiaGang:
                    self.cutPai = pai
                    self.state = "KAKAN"
                else:
                    self.state = "CUT"
            
            # STATE "PLAYER KAKAN"
            elif self.state == "KAKAN":
                self.playerKakan(self.player)
                # check Ron of other player (槍槓)
                for p in self.players:
                    if p == self.player:
                        continue 
                    win, yaku = p.checkRon(self.cutPai)
                    if win:
                        self.state = "WIN"
                        self.winner = p
                        yaku.setJudgeRon("槍槓")
                        yaku.addfan(1)
                        self.playerYaku[p.idx] = yaku
                        self.lastPai = self.cutPai
                if self.state == "WIN":
                    break
                else:
                    self.state = "KAN"

            # STATE "PLAYER_CUT_PAI"
            elif self.state == "CUT" or self.state == "CHI/PON":
                # send current information to every player 
                self.sendEveryOne("")

                if self.player.isRiichi:
                    self.cutPai = self.player.autoCut()
                else:
                    ophand = reduce(lambda x,y: x+y, list(map(Pai.showHand,player.getOpenHand())),"")
                    self.sendPlayer(player,"You drawed "+Pai.showHand([pai])+"\n","print")
                    content = "\n"+str(Pai.showHand(player.hand))+ophand+"\n"
                    self.sendPlayer(player,content,"print")
                    target = int(self.player.conn.recv(1024).decode("utf-8")) -1
                    self.cutPai = self.player.cut(target)
                # print cut info
                self.playerCutPai(self.player)

                # check Ron
                for p in self.players:
                    if p == self.player:
                        continue
                    win, yaku = p.checkRon(self.cutPai)
                    #print(win,self.cutPai,p.hand)
                    if win:
                        self.state = "WIN"
                        self.winner = p
                        self.playerYaku[p.idx] = yaku
                        self.lastPai = self.cutPai
                if self.state == "WIN":
                    #print("breaking")
                    break
                self.state = "MIN"
            
            # STATE "PLAYER_MIN"
            elif self.state == "MIN":
                # check the players who want to Min and select player who could Min
                minPlayers = []
                for p in self.players:
                    # player who want to Kan shoule return ("Kan",minSet)
                    # player who do not Min should return (None,None)
                    if p == self.player:
                        continue
                    minType = p.askMin(self.cutPai)
                    if minType:
                        minPlayers.append([p, minType])
                
                if not len(minPlayers) == 0:
                    # select player with highest priority
                    minPlayer = self.selectMinPlayers(minPlayers)
                    self.minCounter[minPlayer[0].idx,self.player.idx] += 1
                    # player change to MinPlayer
                    self.player = minPlayer[0]

                    if minPlayer[1] == "Kan":
                        self.playerKan(self.player,anKang=False)
                        self.state = "Kan"

                    elif minPlayer[1] == "Pon":
                        self.playerPon(self.player)
                        self.state = "CHI/PON"

                    else:
                        self.playerChi(self.player)
                        self.state = "CHI/PON"
                else:
                    # add cutPai to the player's river
                    self.player.river.append(self.cutPai)
                    # Go to Next turn
                    self.state = "SET_PLAYER"
            
            # STATE "BLACK_HALL"
            else:
                self.state = "BLACK_HALL"

        # GameEnd
        if not self.state == "WIN":
            self.sendEveryOne("流局\n")
            self.winner = self.checkNagashiMangan()
            if self.winner:
                self.sendEveryOne(self.winner.name+" did 流局満貫\n")
                nagashi = True
                #ronInfo = self.playerYaku[self.winner.idx]
                #ronInfo.setJudgeRon(",流局満貫")
                #ronInfo.addfan(5)
                #ronInfo.setallup()
        else:
            nagashi = False
            self.checkSpecialYaku(self.winner.idx)
        # move score to the winner
        if self.state == "WIN" and self.winner.idx == 0:
            # winner is EAST
            ronInfo = self.playerYaku[self.winner.idx]
            self.winner.score += ronInfo.zj
            for i in range(1,4):
                self.players[i].score -= ronInfo.xj
        elif self.state == "WIN":
            # winner is Not EAST
            ronInfo = self.playerYaku[self.winner.idx]
            self.winner.score += ronInfo.zj
            for i in range(4):
                if i == 0:
                    self.players[i].score -= ronInfo.dj
                elif i == self.winner.idx:
                    continue
                else:
                    self.players[i].score -= ronInfo.xj
        else:
            pass

        if not nagashi:
            self.printWinner()
        time.sleep(5)    
        self.sendEveryOne("FINISH GAME")

        # close each socket
        for i in range(len(self.players)):
            self.sockets[i].close()
Example #21
0
    def GameFSM(self):

        self.startGame()
        player = self.players[-1]
        print("Prepared\nLet's Start the GAME !!\n")

        while not self.zeroYama() and len(self.baopai) < 5:

            # STATE "SET_NEXT_PLAYER"
            if self.state == "SET_PLAYER":
                player = self.players[(self.players.index(player) + 1) % 4]
                self.playerCounter[self.players.index(player)] += 1
                print("--------------MAIN PLAYER: ", player.name,
                      " | WIND: ", player.wind, " | Turn:",
                      int(sum(self.playerCounter)), " --------------")
                self.state = "GIVE_PAI"

            # STATE "GIVE_PAI_TO_PLAYER"
            elif self.state == "GIVE_PAI" or self.state == "KAN":
                if self.state == "KAN":
                    self.rinxian = True
                pai = self.yama[0]
                self.yama = self.yama[1:]
                # print out state
                self.printPlayerTurn(player, pai)
                # check Tumo
                win, yaku = player.checkTumo(pai)
                if win:
                    self.state = "WIN"
                    self.winner = player
                    self.playerYaku[self.players.index(player)] = yaku
                    self.playerTumo[self.players.index(player)] = True
                    self.lastPai = pai
                    #self.printWinner(player,yaku)
                    break
                player.givePai(pai)
                self.rinxian = False
                # check Riici etc.
                anKang = player.askAnKang()
                #print(anKang)
                if anKang:
                    self.playerKan(player, anKang=True)
                    self.state = "KAN"
                    continue
                riichi = player.askRiichi()
                #print(riichi)
                jiaGang = player.askJiaGang()
                #print(jiaGang)
                if riichi:
                    self.playerRiichi(player)
                    self.state = "CUT"
                elif jiaGang:
                    self.cutPai = pai
                    self.state = "KAKAN"
                else:
                    self.state = "CUT"

            # STATE "PLAYER KAKAN"
            elif self.state == "KAKAN":
                self.playerKakan(player)
                # check Ron of other player (槍槓)
                for p in self.players:
                    win, yaku = p.checkRon(self.cutPai)
                    if win:
                        self.state = "WIN"
                        self.winner = p
                        yaku.setJudgeRon("槍槓")
                        ronInfo.addfan(1)
                        self.playerYaku[self.players.index(p)] = yaku
                        self.lastPai = self.cutPai
                        #self.printWinner(p,yaku)
                if self.state == "WIN":
                    break
                else:
                    self.state = "KAN"

            # STATE "PLAYER_CUT_PAI"
            elif self.state == "CUT" or self.state == "CHI/PON":
                if player.isRiichi:
                    self.cutPai = player.autoCut()
                else:
                    # show hand
                    ophand = reduce(
                        lambda x, y: x + y,
                        list(map(Pai.showHand, player.getOpenHand())), "")
                    content = str(Pai.showHand(player.hand)) + ophand + "\n"
                    print(content)
                    target = int(
                        input(player.name +
                              " Please SELECT the Pai to CUT\n")) - 1
                    self.cutPai = player.cut(target)
                    self.playerCutPai(player)

                # check Ron
                for p in self.players:
                    win, yaku = p.checkRon(self.cutPai)
                    #print(win,self.cutPai,p.hand)
                    if win:
                        self.state = "WIN"
                        self.winner = p
                        self.playerYaku[self.players.index(p)] = yaku
                        self.lastPai = self.cutPai
                        #self.printWinner(p,yaku)
                if self.state == "WIN":
                    #print("breaking")
                    break
                self.state = "MIN"

            # STATE "PLAYER_MIN"
            elif self.state == "MIN":
                # check the players who want to Min and select player who could Min
                minPlayers = []
                for p in self.players:
                    # player who want to Kan shoule return "Kan"
                    # player who do not Min should return None
                    if p == player:
                        continue
                    minType = p.askMin(self.cutPai)
                    if minType:
                        minPlayers.append([p, minType])

                if not len(minPlayers) == 0:
                    # select player with highest priority
                    minPlayer = self.selectMinPlayers(minPlayers)
                    self.minCounter[self.players.index(minPlayer[0]),
                                    self.players.index(player)] += 1
                    # player change to MinPlayer
                    player = minPlayer[0]

                    if minPlayer[1] == "Kan":
                        self.playerKan(player, anKang=False)
                        self.state = "KAN"

                    elif minPlayer[1] == "Pon":
                        self.playerPon(player)
                        self.state = "CHI/PON"

                    else:
                        self.playerChi(player)
                        self.state = "CHI/PON"
                else:
                    # add cutPai to the player's river
                    player.river.append(self.cutPai)
                    # Go to Next turn
                    self.state = "SET_PLAYER"

            # STATE "BLACK_HALL"
            else:
                self.state = "BLACK_HALL"

        # GameEnd
        if not self.state == "WIN":
            print(
                "\n******************************流局******************************\n"
            )
            self.winner = self.checkNagashiMangan()
            if not self.winner == None:
                ronInfo = self.playerYaku[self.players.index(self.winner)]
                ronInfo.setJudgeRon(",流局満貫")
                ronInfo.addfan(5)
                ronInfo.setallup()
                nagashi = True
        else:
            self.checkSpecialYaku(self.players.index(self.winner))
            nagashi = False
        # move score to the winner
        if self.state == "WIN" and self.players.index(self.winner) == 0:
            # winner is EAST
            ronInfo = self.playerYaku[self.players.index(self.winner)]
            self.winner.score += ronInfo.zj
            for i in range(1, 4):
                self.players[i].score -= ronInfo.xj
        elif self.state == "WIN":
            # winner is Not EAST
            ronInfo = self.playerYaku[self.players.index(self.winner)]
            self.winner.score += ronInfo.zj
            for i in range(4):
                if i == 0:
                    self.players[i].score -= ronInfo.dj
                elif i == self.players.index(self.winner):
                    continue
                else:
                    self.players[i].score -= ronInfo.xj
        else:
            pass

        if not nagashi:
            self.printWinner()
        print("FINISH GAME")