コード例 #1
0
def Can_Hu(extra_card, data, is_ZIMO):
    ## give extra_card(draw or others play), judge if can HU and return
    # if_Hu(bool), action, data
    play_ID, quan, pack, hand, hua = data["info"]
    #将list转换成tuple
    new_pack = []
    for item in pack:
        new_pack.append(tuple(item))
    new_pack = tuple(new_pack)
    try:
        new_hand = decode_card(hand)  #transfer list[int] -> list[string]
        ans = MahjongFanCalculator(new_pack, new_hand, extra_card, hua,
                                   is_ZIMO, False, False, False, play_ID, quan)
        fan = 0
        for item in ans:
            fan += item[0]
        fan = fan - hua
        if fan < 8:  #未到8番
            raise Exception
    except Exception as err:
        #not HU
        return False, "", ""
    else:
        action = "HU"
        data = ""
        return True, action, data
コード例 #2
0
 def judgeHu(self, last_card, playerID, isGANG, dianPao=False):
     hand = []
     for ind, cardcnt in enumerate(self.hand_free):
         for _ in range(cardcnt):
             hand.append(self.getCardName(ind))
     if self.history[self.getCardInd(last_card)] == 4:
         isJUEZHANG = True
     else:
         isJUEZHANG = False
     if self.tile_count[(playerID + 1) % 4] == 0:
         isLAST = True
     else:
         isLAST = False
     if not dianPao:
         hand.remove(last_card)
     try:
         ans = MahjongFanCalculator(tuple(self.hand_fixed_data), tuple(hand), last_card, 0, playerID==self.myPlayerID,
                                    isJUEZHANG, isGANG, isLAST, self.myPlayerID, self.quan)
     except Exception as err:
         if str(err) == 'ERROR_NOT_WIN':
             return 0
         else:
             if not self.botzone:
                 print(hand, last_card, self.hand_fixed_data)
                 print(self.fname)
                 print(err)
                 return 0
     else:
         fan_count = 0
         for fan in ans:
             fan_count += fan[0]
         return fan_count
コード例 #3
0
ファイル: main.py プロジェクト: AOZMH/Mahjong-AI
def judge_hu(dat, isZimo, isGang):
    # 调用算番库判定有没有胡牌
    # 当前明牌、和牌
    cur_pack = tuple((tuple(pk) for pk in dat['pack']))
    winTile = dat['cur_request'][-1]

    # 自摸一张牌(包括杠上开花),此时新的那张牌已经加入avail_cards了,但判胡时不应在手牌里,所以去掉
    if isZimo:
        dat['avail_cards'].remove(winTile)
    cur_hand = tuple(dat['avail_cards'])  # 当前手牌

    # 判定海底捞月、妙手回春需要计算别人的牌墙
    if isZimo:
        next_id = (dat['id'] + 1) % 4  # 判断我的下家牌墙里有没有牌
    else:
        next_id = (int(dat['cur_request'][1]) + 1) % 4  # 判断出牌者的下家牌墙里有没有牌
    isLast = (dat['card_wall_remain'][next_id] == 0)  # 没牌了,则是妙手回春/海底捞月,即isLast
    if isGang and not isZimo:  # 但是如果是抢杠胡,isLast一定是False,这块需要特判,因为那张胡牌实际上没打出来,没有所谓的下家
        isLast = False

    # 判定和绝张需要判定明牌里面是否已经有三张winTile
    if dat['all_shown_cards'].count(winTile) + int(isZimo) >= 4:
        isJuezhang = True
    else:
        isJuezhang = False

    try:
        judge_res = MahjongFanCalculator(cur_pack, cur_hand, winTile, 0,
                                         isZimo, isJuezhang, isGang, isLast,
                                         dat['quan'], dat['id'])
    except Exception as err:
        judge_res = str(err)
    # print(judge_res, '\n', isZimo, isGang, isLast, isJuezhang)

    if isinstance(judge_res, str):
        cur_fan = 0
    else:
        cur_fan = sum([fan[0] for fan in judge_res])

    # 之后还得恢复回来,因为还可能计算别的
    if isZimo:
        dat['avail_cards'].append(winTile)

    if cur_fan >= 8:
        return True, judge_res
    else:
        return False, judge_res
コード例 #4
0
ファイル: main.py プロジェクト: AOZMH/Mahjong-AI
def naive_cal_fan(dat, card):
    cur_pack = tuple((tuple(pk) for pk in dat['pack']))
    cur_hand = tuple(dat['avail_cards'])  # 当前手牌
    isLast = False
    isZimo = True  # 自摸比较容易
    isGang = False
    isJuezhang = False
    if dat['all_shown_cards'].count(card) == 3:
        isJuezhang = True
    try:
        judge_res = MahjongFanCalculator(cur_pack, cur_hand, card, 0, isZimo,
                                         isJuezhang, isGang, isLast,
                                         dat['quan'], dat['id'])
    except Exception as err:
        judge_res = str(err)
    if isinstance(judge_res, str):
        cur_fan = 0
    else:
        cur_fan = sum([fan[0] for fan in judge_res])
    return cur_fan
コード例 #5
0
 def _checkMahjong(self, player, isSelfDrawn = False, isAboutKong = False):
     try:
         fans = MahjongFanCalculator(
             pack = tuple(self.packs[player]),
             hand = tuple(self.hands[player]),
             winTile = self.curTile,
             flowerCount = len(self.flowers[player]),
             isSelfDrawn = isSelfDrawn,
             is4thTile = self.shownTiles[self.curTile] == 4,
             isAboutKong = isAboutKong,
             isWallLast = self.wallLast,
             seatWind = player,
             prevalentWind = self.prevalentWind,
             verbose = True
         )
         f = []
         fanCnt = 0
         for fanPoint, cnt, fanName, fanNameEn in fans:
             f.append(dict(name = fanName, cnt = cnt, value = fanPoint))
             fanCnt += fanPoint * cnt
         if fanCnt < 8: raise Error('Not Enough Fans')
         if isSelfDrawn:
             score = [-(8 + fanCnt)] * 4
             score[player] = (8 + fanCnt) * 3
         else:
             score = [-8] * 4
             score[player] = 8 * 3 + fanCnt
             score[self.curPlayer] -= fanCnt
         self.display.append(dict(
             action = 'HU',
             player = player,
             fan = f,
             fanCnt = fanCnt,
             score = score
         ))
         self.round = None
         return tuple(score)
     except Exception as e:
         raise Error(player)
コード例 #6
0
ファイル: test.py プロジェクト: ailab-pku/PyMahjongGB
from MahjongGB import MahjongFanCalculator, MahjongShanten

# Non-positional arguments
print(
    MahjongFanCalculator((), ("W1", "W1", "W1", "W2", "W2", "W2", "W3", "W3",
                              "W3", "W4", "W4", "W4", "W5"), "W5", 1, True,
                         False, False, True, 0, 0))
print(
    MahjongShanten((), ("W1", "W1", "W1", "W2", "W2", "W2", "W3", "W3", "W3",
                        "W4", "W4", "W4", "W5")))
print(
    MahjongShanten((), ("W1", "B1", "T1", "W2", "W2", "W2", "W3", "J3", "F3",
                        "F4", "W4", "W4", "W9")))

# Support keyword arguments
print(
    MahjongFanCalculator(pack=(("GANG", "W1", 2), ),
                         hand=("W2", "W2", "W2", "W3", "W3", "W3", "W4", "W4",
                               "W4", "W5"),
                         winTile="W5",
                         flowerCount=2,
                         isSelfDrawn=False,
                         is4thTile=False,
                         isAboutKong=False,
                         isWallLast=False,
                         seatWind=0,
                         prevalentWind=0))
print(
    MahjongShanten(pack=(("GANG", "W1", 2), ),
                   hand=("W1", "B1", "T1", "W2", "W2", "W2", "W3", "J3", "F3",
                         "F4")))
コード例 #7
0
    def step(self, action:list):
        '''
        用于update状态
        @param: action:
            example:
                [("PASS", 0), ("PASS", 1), ("PASS", 2), ("PASS", 3)]
                0/1/2/3分别表示玩家的id
        '''
        new_action = []
        for x in action:
            tmp = json.loads(x[0])
            new_action.append((tmp['response'], x[1]))
        action = new_action
        if self.game_state[:9] == "NEED_PASS":
            if self.game_state != "NEED_PASS":
                '''
                这里可以胡牌
                '''
                for i in range(4):
                    if action[i][0][:2] == "HU":
                        player_id = action[i][1]
                        tmp_hand = copy.deepcopy(self.hand[player_id])
                        try:
                            result = MahjongFanCalculator(
                                tuple(self.pack[player_id]),
                                tuple(tmp_hand),
                                self.disc_tile,
                                len(self.flower[player_id]),
                                False,
                                self.desk.count(self.disc_tile) == 3,
                                False, # 这里没完全理解到这个参数啥意思。。
                                len(self.wall) == 0,
                                player_id,
                                self.wind
                            )
                            sumv = 0
                            for x in result:
                                sumv += x[0]
                            if sumv < 8:
                                raise BaseException(f"{player_id} 进行了错胡")
                        except:
                            raise BaseException(f"{player_id} 进行了错胡")
                        self.is_end = True
                        self.result = player_id
                        return
            for i in range(4):
                if action[i][0][:4] != "PASS":
                    raise BaseException(f"{action[i][1]} 你应该输出PASS")
            self.game_state = ""
        elif self.game_state == "DRAW":
            for i in range(4):
                if action[i][0][:4] == "PASS":
                    if action[i][1] == (self.prev_player+1)%4:
                        raise BaseException(f"{action[i][1]} 你不应该输出PASS"+str(action[i]))
                    continue
                if action[i][1] != (self.prev_player+1)%4:
                    raise BaseException(f"{action[i][1]}你现在应该输出PASS")
                player_id = action[i][1]
                if action[i][0][:4] == "PLAY":
                    self.game_state = "PLAYED"
                    self.player_id = player_id
                    self.disc_tile = action[i][0][5:7]
                    if self.hand[player_id].count(self.disc_tile) == 0:
                        raise BaseException(f"{player_id} 试图discard他没有的牌")
                    self.hand[player_id].pop(self.hand[player_id].index(self.disc_tile))
                    return
                elif action[i][0][:4] == "GANG":
                    self.game_state = "GANGED"
                    self.player_id = player_id
                    self.disc_tile = action[i][0][5:7]
                    if self.hand[player_id].count(self.disc_tile) < 4:
                        raise BaseException(f"{player_id} 试图gang他没有的牌")
                    for j in range(4): self.hand[player_id].pop(self.hand[player_id].index(self.disc_tile))
                    self.pack[player_id].append(("GANG", self.disc_tile, 0))
                    return
                elif action[i][0][:4] == "BUGANG":
                    self.game_state = "BUGANGED"
                    self.player_id = player_id
                    self.disc_tile = action[i][0][7:9]
                    if self.hand[player_id].count(self.disc_tile) == 0:
                        raise BaseException(f"{player_id} 试图bugang他没有的牌")
                    self.hand[player_id].pop(self.hand[player_id].index(self.disc_tile))
                    ok = False
                    for i in range(len(self.pack[player_id])):
                        if self.pack[player_id][i][1] == self.disc_tile:
                            self.pack[player_id][i][0] = "GANG"
                            ok = True
                            break
                    if not ok:
                        raise BaseException(f"{player_id} 试图bugang他没有的PENG")
                    return
                elif action[i][0][:4] == "HU":
                    tmp_hand = copy.deepcopy(self.hand[player_id])
                    tmp_hand.pop(tmp_hand.index(self.last_draw))
                    try:
                        result = MahjongFanCalculator(
                            tuple(self.pack[player_id]),
                            tuple(tmp_hand),
                            self.last_draw,
                            len(self.flower[player_id]),
                            True,
                            self.desk.count(self.last_draw) == 3,
                            self.ganged == 1,
                            len(self.wall) == 0,
                            player_id,
                            self.wind
                        )
                        sumv = 0
                        for x in result:
                            sumv += x[0]
                        if sumv < 8:
                            raise BaseException(f"{player_id} 进行了错胡")
                    except Exception as err:
                        raise BaseException(f"{player_id} 进行了错胡")
                    self.is_end = True
                    self.result = player_id
                    return
        elif self.game_state == "PLAYED_WAITING":
            for i in range(len(action)):
                player_id = action[i][1]
                if action[i][0][:2] == "HU":
                    tmp_hand = copy.deepcopy(self.hand[player_id])
                    try:
                        result = MahjongFanCalculator(
                            tuple(self.pack[player_id]),
                            tuple(tmp_hand),
                            self.disc_tile,
                            len(self.flower[player_id]),
                            False,
                            self.desk.count(self.disc_tile) == 3,
                            False,
                            len(self.wall) == 0,
                            player_id,
                            self.wind
                        )
                        sumv = 0
                        for x in result:
                            sumv += x[0]
                        if sumv < 8:
                            raise BaseException(f"{player_id} 进行了错胡 {sumv}")
                    except:
                        raise BaseException(f"{player_id} 进行了错胡")
                    self.is_end = True
                    self.result = player_id
                    return
            for i in range(len(action)):
                player_id = action[i][1]
                if action[i][0][:4] == "PENG":
                    self.desk.pop(self.desk.index(self.disc_tile))
                    self.pack[player_id].append(("PENG", self.disc_tile, (player_id-self.player_id+4)%4))
                    if self.hand[player_id].count(self.disc_tile) < 2:
                        raise BaseException(f"{player_id} 试图peng他没有的牌")
                    for j in range(2): self.hand[player_id].pop(self.hand[player_id].index(self.disc_tile))
                    self.disc_tile = action[i][0].split(' ')[1]
                    if self.hand[player_id].count(self.disc_tile) == 0:
                        raise BaseException(f"{player_id} 试图在peng的时候discard他没有的牌")
                    self.hand[player_id].pop(self.hand[player_id].index(self.disc_tile))
                    self.player_id = player_id
                    self.game_state = "PENGED"
                    return
                elif action[i][0][:4] == "GANG":
                    self.desk.pop(self.desk.index(self.disc_tile))
                    self.pack[player_id].append(("GANG", self.disc_tile, (player_id-self.player_id+4)%4))
                    if self.hand[player_id].count(self.disc_tile) < 3:
                        raise BaseException(f"{player_id} 试图gang他没有的牌")
                    for j in range(3): self.hand[player_id].pop(self.hand[player_id].index(self.disc_tile))
                    self.disc_tile = ""
                    self.player_id = -1
                    self.game_state = "GANGED"
                    return
            for i in range(len(action)):
                player_id = action[i][1]
                if action[i][0][:3] == "CHI":
                    self.desk.pop(self.desk.index(self.disc_tile))
                    if (player_id+3)%4 != self.player_id:
                        raise BaseException(f"{player_id} 试图从错误的位置进行吃牌")
                    chi_tile = action[i][0][4:6]
                    out_tile = action[i][0][7:9]
                    self.hand[player_id].append(self.disc_tile)
                    if self.hand[player_id].count(out_tile) == 0:
                        raise BaseException(f"{player_id} 试图使用他没有的牌 {out_tile}")
                    if self.hand[player_id].count(chi_tile) == 0:
                        raise BaseException(f"{player_id} 试图使用他没有的牌 {chi_tile}")
                    if self.hand[player_id].count(prevTile(chi_tile)) == 0:
                        raise BaseException(f"{player_id} 试图使用他没有的牌 {prevTile(chi_tile)}")
                    if self.hand[player_id].count(backTile(chi_tile)) == 0:
                        raise BaseException(f"{player_id} 试图使用他没有的牌 {backTile(chi_tile)}")
                    self.hand[player_id].pop(self.hand[player_id].index(out_tile))
                    self.hand[player_id].pop(self.hand[player_id].index(chi_tile))
                    self.hand[player_id].pop(self.hand[player_id].index(prevTile(chi_tile)))
                    self.hand[player_id].pop(self.hand[player_id].index(backTile(chi_tile)))

                    number = 2
                    if prevTile(chi_tile) == self.disc_tile: number = 1
                    if backTile(chi_tile) == self.disc_tile: number = 3
                    
                    self.pack[player_id].append(("CHI", chi_tile, number))
                    self.chi_tile = chi_tile
                    self.disc_tile = out_tile
                    self.player_id = player_id
                    self.game_state = "CHIED"
                    return
            self.game_state = ""
            self.player_id = -1
            return
コード例 #8
0
ファイル: test.py プロジェクト: chriswang2468/mj
from MahjongGB import MahjongFanCalculator

try:
    ans=MahjongFanCalculator((),("W1","W1","W1","W2","W2","W2","W3","W3","W3","W4","W4","W4","W5"),"W5",1,True,False,False,True,0,0)
except Exception as err:
    print(err)
else:
    print(ans)

try:
    ans=MahjongFanCalculator((("GANG","W1",2),),("W2","W2","W2","W3","W3","W3","W4","W4","W4","W5"),"W5",1,False,False,False,False,0,0)
except Exception as err:
    print(err)
else:
    print(ans)

#错误
try:
    ans=MahjongFanCalculator((),("W1","W1","W1","W2","W2","W2","W3","W3","W3","W4","W4","W4"),"W5",1,True,False,False,True,0,0)
except Exception as err:
    print(err)
else:
    print(ans)

#没和
try:
    ans=MahjongFanCalculator((("CHI","W1",0),),("W2","W2","W2","W3","W3","W3","W4","W4","W4","W5"),"W7",1,False,False,False,False,0,0)
except Exception as err:
    print(err)
else:
    print(ans)