0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python3でMJSCORE形式の牌譜を解析

Posted at

#データベースにしたこと

備忘録を兼ねて何のデータをどのようにとったかまとめておきます。

  • 全体データ(whole_data)
     試合データをまとめたもの(list)
  • 試合データ(shiai_data)
    局データをまとめたもの(list)
  • 局データ(kyoku_data)
    局目・点数・和了データ(流局)・配牌・ドラ表示牌・捨て牌・立直のタイミング・和了のタイミング・終局時の手牌・牌譜を内包したもの(list)
  1. 局目
     東一局~南四局までを1~4のintで表したもの
  2. 点数
     局ごとの点数の変動をlistにしたもの
  3. 和了データ
    和了の役や流局をしたかどうかを取得したもの(2019/04/11現在では流局の情報のみ)
  4. 配牌
     配牌をlistで取得したもの
  5. ドラ表示牌
     str
  6. 捨て牌
    list
  7. 立直のタイミング
    int(局時間)
  8. 和了のタイミング
     同上
  9. 終局時の手牌
     list
  10. 牌譜
    list

以下ソースコード

file_name=""#ファイル名
target_file=open(file_name,"rb")
lines = target_file.readlines()


tonnanwhich=0


players=["","","",""]#プレイヤーの名前を格納
players_cell=["","","",""]

whole_data=[] #試合データを内包する
shiai_data=[] #局データを内包する
kyoku_data=[] #局目・点数・和了データ(流局)・配牌・ドラ表示牌・捨て牌・立直のタイミング・和了のタイミング・終局時の手牌・牌譜を内包する

haipai_data=["","","",""] #配牌データを東家から北家の順に内包する
ie_num=0 #局目を取得(東一局~南四局)
dpoint_data=[0,0,0,0] #局の点数の収支
kyokugyo=0 #和了の役/流局 から 配牌の四行 を表す行を取得
ryukyoku_flag=0 #流局したら1
paifu_list=[] #*で始まる行の牌譜を一つなぎのリストにしたもの
paifu_list_kari=[] #↑の一行分
paifugyo=0 #牌譜を書いた行がいつまで続くか記録するもの(ドラが書いてある行で1になってスタート)
tehai_list=[[[],[],[]],[[],[],[]],[[],[],[]],[[],[],[]]] #終局時の手牌をリストにする([[手牌],[鳴いた牌],[暗槓の牌]]という形で保持する)
sute_hai=[[],[],[],[]] #捨て牌のリスト
kyoku_time=0 #局時間(paifu_cell一個につき1進む)
riichi_kyoku_time=[0,0,0,0] #立直した人とそのタイミング(局時間)
hola_kyoku_time=[0,0,0,0] #和了した人とそのタイミング(局時間)


for row in lines:

    try:
        row = row.decode("utf-8")
    except UnicodeDecodeError:
                # utf-8でないバイト列が含まれる行はスキップする
        row = target_file.readline()
        continue

    rlist = row.split()
    rlistlist = list(rlist)

    if "=====" in row:
        if "東" in row:
            houwhich=1
        else:
            houwhich=2

    elif "持点" in row:
        players_cell[0]=rlist[1]
        players_cell[1]=rlist[3]
        players_cell[2]=rlist[5]
        players_cell[3]=rlist[7]
        i = 0

        for i in range(4):
            player_celllist=list(players_cell[i])
            j=0
            nflag=0
            player_name=""
            for j in range(20):
                if player_celllist[j] == "]":
                    nflag=1
                elif player_celllist[j] == "/":
                    break
                elif nflag==1:
                    player_name+=player_celllist[j]
                else:
                    pass
            players[i]=player_name
    #ツモ率・放銃率・流局率
    elif "局" in row and "本場" in row:
        #局目を取得
        rlistlist0=list(rlist[0])
        ie_index=rlistlist0.index("局")-1
        ie_num=int(rlistlist0[ie_index])
        kyoku_data.append(ie_num)

        #プレイヤーの得点の差分を取得
        rlistlist1=list(rlist[1])
        riichi_honsu=int(rlistlist1[-2])
        rlist_len=len(rlist)
        roop_len=rlist_len-2
        for i in range(roop_len):
            I=i+2
            if I%2==0:
                dpoint_player=players.index(rlist[I])
            else:
                dpoint_num=int(rlist[I])
                dpoint_data[dpoint_player]=dpoint_num
        kyoku_data.append(dpoint_data)
        kyokugyo=1

    elif kyokugyo == 1:
        kyokugyo=2
        #流局したかどうか
        if "流局" in row:
            ryukyoku_flag=1
            kyoku_data.append(ryukyoku_flag)
        #必要なら点数とかその他(手牌から読み取れるよね……?)(ダブロンとか見ないと)


    elif kyokugyo > 1:
        #配牌データを取得する
        rlistlist0=list(rlist[0])
        if rlistlist0[1] == "1":
            haipai_list=rlistlist0[4:]
            haipai_str="".join(haipai_list)
            haipai_data[0]=haipai_str
        elif rlistlist0[1] == "2":
            haipai_list=rlistlist0[4:]
            haipai_str="".join(haipai_list)
            haipai_data[1]=haipai_str
        elif rlistlist0[1] == "3":
            haipai_list=rlistlist0[4:]
            haipai_str="".join(haipai_list)
            haipai_data[2]=haipai_str
        elif rlistlist0[1] == "4":
            haipai_list=rlistlist0[4:]
            haipai_str="".join(haipai_list)
            haipai_data[3]=haipai_str
        kyokugyo+=1
        if kyokugyo == 6:
            kyokugyo = 0
            kyoku_data.append(haipai_data)

    elif "表ドラ" in row and "裏ドラ" in row:
        #ドラ表示牌及び裏ドラを取得する
        rlistlist0=list(rlist[0])
        rlistlist1=list(rlist[1])
        omotedora=rlistlist0[5:]
        uradora=rlistlist1[5:]
        omotedora="".join(omotedora)
        uradora="".join(uradora)
        kyoku_data.append(omotedora)
        paifugyo=1

    elif paifugyo > 0:
        #*から始まる牌譜をリストにして取得する
        if "*" in row:
            paifu_list_kari=rlist[1:]
            paifu_list_kari_len=len(paifu_list_kari)
            for i in range(paifu_list_kari_len):
                paifu_list.append(paifu_list_kari[i])
        else:
            paifugyo=0
            #得られた牌譜データから最終手牌を作る(鳴きと残り手牌を分けて)
            for i in range(4): #配牌で手牌を初期化
                haipai_data_len=len(haipai_data[i])
                haipai_data_list=list(haipai_data[i])
                haipai_list=[]
                flag = 0
                for j in range(haipai_data_len):
                    if haipai_data_list[j] == "東" or haipai_data_list[j] == "南" or haipai_data_list[j] == "西" or haipai_data_list[j] == "北" or haipai_data_list[j] == "白" or haipai_data_list[j] == "発" or haipai_data_list[j] == "中":
                        haipai_list.append(haipai_data_list[j])
                    elif flag == 1:
                        haipai_the_hai=haipai_data_list[j-1]+haipai_data_list[j]
                        haipai_list.append(haipai_the_hai)
                        flag = 0
                    else:
                        flag = 1
                tehai_list[i][0]=haipai_list
            paifu_list_len=len(paifu_list)
            for i in range(paifu_list_len):
                kyoku_time+=1
                paifu_cell=paifu_list[i]
                paifu_cell_list=list(paifu_cell)
                paifu_cell_list_len=len(paifu_cell_list)
                act_player=int(paifu_cell_list[0])-1
                if "G" == paifu_cell_list[1]: #ツモ牌
                    if paifu_cell_list_len == 4: #ツモ牌が数牌
                        the_hai=paifu_cell_list[2]+paifu_cell_list[3]
                    else:
                        the_hai=paifu_cell_list[2]
                    tehai_list[act_player][0].append(the_hai)
                    act_past_player=act_player
                elif "D" == paifu_cell_list[1] or "d" == paifu_cell_list[1]: #捨てる牌
                    if paifu_cell_list_len == 4: #捨てる牌が数牌
                        the_hai=paifu_cell_list[2]+paifu_cell_list[3]
                    else:
                        the_hai=paifu_cell_list[2]
                    tehai_list[act_player][0].remove(the_hai)
                    sute_hai[act_player].append(the_hai)
                    act_past_player=act_player
                elif "N" == paifu_cell_list[1]: #ポンッ!(cv.亦野誠子)
                    if paifu_cell_list_len == 4: #ポンする牌が字牌
                        the_hai=paifu_cell_list[2]
                        tehai_list[act_player][0].remove(the_hai)
                        tehai_list[act_player][0].remove(the_hai)
                        del sute_hai[act_past_player][-1]
                        for i in range(3):
                            tehai_list[act_player][1].append(the_hai)
                    else:
                        the_hai1=paifu_cell_list[2]+paifu_cell_list[3]
                        the_hai2=paifu_cell_list[4]+paifu_cell_list[5]
                        the_hai3=sute_hai[act_past_player][-1]
                        del sute_hai[act_past_player][-1]
                        tehai_list[act_player][0].remove(the_hai1)
                        tehai_list[act_player][0].remove(the_hai2)
                        tehai_list[act_player][1].append(the_hai1)
                        tehai_list[act_player][1].append(the_hai2)
                        tehai_list[act_player][1].append(the_hai3)

                elif "C" == paifu_cell_list[1]: #チー
                    the_hai1=paifu_cell_list[2]+paifu_cell_list[3]
                    the_hai2=paifu_cell_list[4]+paifu_cell_list[5]
                    the_hai3=sute_hai[act_past_player][-1]
                    tehai_list[act_player][0].remove(the_hai1)
                    tehai_list[act_player][0].remove(the_hai2)
                    del sute_hai[act_past_player][-1]
                    tehai_list[act_player][1].append(the_hai1)
                    tehai_list[act_player][1].append(the_hai2)
                    tehai_list[act_player][1].append(the_hai3)
                elif "K" == paifu_cell_list[1]: #槓
                    if act_past_player == act_player: #暗槓or加槓
                        if paifu_cell_list_len == 4: #ツモ牌が数牌
                            the_hai=paifu_cell_list[2]+paifu_cell_list[3]
                        else:
                            the_hai=paifu_cell_list[2]

                        if the_hai in tehai_list[act_player][1]: #加槓
                            tehai_list[act_player][0].remove(the_hai)
                            tehai_list[act_player][1].append(the_hai)
                        else: #赤牌も考慮
                            if "5" in the_hai:
                                if the_hai == "5P":
                                    if "5p" in tehai_list[act_player][1]:
                                        tehai_list[act_player][0].remove("5P")
                                        tehai_list[act_player][1].append("5P")
                                    else:
                                        tehai_list[act_player][0].remove("5P")
                                        tehai_list[act_player][2].append("5P")
                                        for i in range(3):
                                            tehai_list[act_player][0].remove("5p")
                                            tehai_list[act_player][2].append("5p")
                                if the_hai == "5S":
                                    if "5s" in tehai_list[act_player][1]:
                                        tehai_list[act_player][0].remove("5S")
                                        tehai_list[act_player][1].append("5S")
                                    else:
                                        tehai_list[act_player][0].remove("5S")
                                        tehai_list[act_player][2].append("5S")
                                        for i in range(3):
                                            tehai_list[act_player][0].remove("5s")
                                            tehai_list[act_player][2].append("5s")
                                if the_hai == "5M":
                                    if "5m" in tehai_list[act_player][1]:
                                        tehai_list[act_player][0].remove("5M")
                                        tehai_list[act_player][1].append("5M")
                                    else:
                                        tehai_list[act_player][0].remove("5M")
                                        tehai_list[act_player][2].append("5M")
                                        for i in range(3):
                                            tehai_list[act_player][0].remove("5m")
                                            tehai_list[act_player][2].append("5m")
                            else:
                                for i in range(4):
                                    tehai_list[act_player][0].remove(the_hai)
                                    tehai_list[act_player][2].append(the_hai)
                    else: #大明槓
                        if paifu_cell_list_len == 4: #鳴く牌が数牌
                            the_hai=paifu_cell_list[2]+paifu_cell_list[3]
                        else:
                            the_hai=paifu_cell_list[2]

                        del sute_hai[act_past_player][-1]
                        tehai_list[act_player][1].append(the_hai)
                        if "5" in the_hai:
                            if the_hai=="5p":
                                tehai_list[act_player][0].remove(the_hai)
                                tehai_list[act_player][0].remove(the_hai)
                                tehai_list[act_player][0].remove("5P")
                                tehai_list[act_player][1].append(the_hai)
                                tehai_list[act_player][1].append(the_hai)
                                tehai_list[act_player][1].append("5P")
                            elif the_hai=="5P":
                                for i in range(3):
                                    tehai_list[act_player][0].remove("5p")
                                    tehai_list[act_player][0].append("5p")
                            if the_hai=="5s":
                                tehai_list[act_player][0].remove(the_hai)
                                tehai_list[act_player][0].remove(the_hai)
                                tehai_list[act_player][0].remove("5S")
                                tehai_list[act_player][1].append(the_hai)
                                tehai_list[act_player][1].append(the_hai)
                                tehai_list[act_player][1].append("5S")
                            elif the_hai=="5S":
                                for i in range(3):
                                    tehai_list[act_player][0].remove("5s")
                                    tehai_list[act_player][0].append("5s")
                            if the_hai=="5m":
                                tehai_list[act_player][0].remove(the_hai)
                                tehai_list[act_player][0].remove(the_hai)
                                tehai_list[act_player][0].remove("5M")
                                tehai_list[act_player][1].append(the_hai)
                                tehai_list[act_player][1].append(the_hai)
                                tehai_list[act_player][1].append("5M")
                            elif the_hai=="5M":
                                for i in range(3):
                                    tehai_list[act_player][0].remove("5m")
                                    tehai_list[act_player][0].append("5m")
                        else:
                            for i in range(3):
                                tehai_list[act_player][0].remove(the_hai)
                                tehai_list[act_player][1].append(the_hai)
                elif "R" == paifu_cell_list[1]: #立直のタイミング
                    riichi_kyoku_time[act_player]=kyoku_time
                    kyoku_time+=1
                elif "A" == paifu_cell_list[1]: #和了のタイミング
                    hola_kyoku_time[act_player]=kyoku_time
                    kyoku_time+=1
            kyoku_data.append(sute_hai)
            kyoku_data.append(riichi_kyoku_time)
            kyoku_data.append(hola_kyoku_time)
            kyoku_data.append(tehai_list)
            kyoku_data.append(paifu_list)
            #局データが完成(やったー!)
            shiai_data.append(kyoku_data)
            kyoku_data=[]
            paifu_list=[]
            tehai_list=[[[],[],[]],[[],[],[]],[[],[],[]],[[],[],[]]] #終局時の手牌をリストにする([[手牌],[鳴いた牌],[暗槓の牌]]という形で保持する)
            sute_hai=[[],[],[],[]] #捨て牌のリスト
            kyoku_time=0
    elif "----" in row:
        whole_data.append(shiai_data)
        shiai_data=[]

あとはデータベースから必要なデータだけ引っ張ってこればいいので楽ですね。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?