山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

天鳳のログから和了データを抽出する その2

天鳳のログの解析

前回は、天鳳のログからAGARIタグの抽出を行いましたが、この情報だけでは場風の情報がありません。符と翻と得点から親か子であるかはすぐに分かるので、場風を特定するのはさらに役を考慮すれば可能だと思います。ですが、それは大変なのでログから抽出したいと思います。

INIT タグ

blog.kobalab.net

このサイトによると親や場風の情報は INIT タグにあることが分かるので、前回のプログラムを修正します。

import os
import gzip
from lxml import html
import requests
import lxml
import re
from bs4 import BeautifulSoup

script_dir = script_dir = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(script_dir, "../tenhou_log/2018/scc20180101.html.gz")

idx = len('href="http://tenhou.net/0/?log=')

agari_data = []

with gzip.open(path, "rt", encoding="utf_8") as f:
    line = f.readline()
    while(line):
        v = line.split(" ")
        # 三麻を除く 
        if '三' in v[4]:
            line = f.readline()
            continue
        print(line)
        url = 'http://tenhou.net/0/log/?' + v[7][idx : len(v[7]) - 8]
        r = requests. get(url)
        html = lxml.html.fromstring(r.text)
        soup = BeautifulSoup(r.text, 'lxml-xml')
        data = soup.find_all(re.compile('AGARI|INIT'))
        init = ''
        for d in data:
            if d.name == 'INIT': init = d
            else:
                agari_data.append(init)
                agari_data.append(d)
        
        line = f.readline()

        

output_path = os.path.join(script_dir, "../text/agari_log_1.txt")

 with open(output_path, 'w', encoding='utf_8') as f:
     for data in agari_data:
         f.write(str(data))
         f.write('\n')

流局時の INIT の情報は必要ないので、和了が発生したときのみその情報を抽出します。なので、和了が発生した直前の INIT タグが必要となります。天鳳はダブロンがあるので、AGARI タグのひとつ前のタグが INIT ではなく AGARI タグとなるときに注意します。

data = soup.find_all(re.compile('AGARI|INIT'))

正規表現を使って、HTMLから'AGARI' または 'INIT' タグを抽出し配列に格納し、テストデータのファイルに書き込みます。

最終的には、フォルダのファイル名一覧を取得し、全てのログからテストデータの作成を行いたいと思います。

和了データの抽出

INIT タグの情報

場風

INIT タグの内容は次の通りです。

    <INIT seed="0,0,0,1,3,67" ten="250,250,250,250" oya="0" hai0="9,80,97,82,64,5,131,135,66,6,50,110,123" hai1="104,93,127,101,21,78,116,29,45,36,42,122,92" hai2="85,1,108,134,87,99,125,58,28,3,60,37,52" hai3="128,70,74,124,51,59,77,27,129,38,53,56,95"/>

seed の最初の数字が局に対応しています。東1局は 0、東2局は 1、であり、南1局は 4 となります。したがって、この数字を  x とすると、

 \dfrac{x}{4}

の値が 0 のときは東場であり、1のときは南場となります。(小数点以下切り捨て)

自風

AGARI タグには誰が和了したかの番号があるので、和了した人の自風を INIT タグから求めます。

東1局の親の番号が0であり、そこから反時計回りに1, 2, 3 となっています。したがって、親の番号を  p とし、和了した人の番号を  x とすると、

 (x - p + 4) \mod 4

が自風の番号となります。東南西北は 0, 1, 2, 3 に対応します。