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
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)
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
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
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)
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")
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
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)
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)
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)
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
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)
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
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)
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()
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")