0
0

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.

jsonファイルをパースして処理するサンプル

Posted at

叡王戦で公開されている棋譜JSONをkif形式のファイルに変換するスクリプトを書いてみた。
いろいろ未完成で適当だがShougGUIで読み込めたのでまぁ良しとする。

python3 json2kif.py <URL> kif.json a.kif
json2kif.py
# -*- coding: utf-8 -*-
from logging import getLogger, StreamHandler, DEBUG

import sys
import os
import json
import unicodedata
import re
import urllib.request

# ログ出力のための print と import logging はやめてほしい - Qiita
# https://qiita.com/amedama/items/b856b2f30c2f38665701

logger = getLogger(__name__)
handler = StreamHandler()
handler.setLevel(DEBUG)
logger.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False


class FileWriter:
    filename = None
    tiow = None

    def __init__(self, fname):
        self.filename = fname
        self.tiow = open(self.filename, mode='a', encoding="utf-8")

    def write(self, msg):
        self.tiow.write(msg + "\n")

    def __del__(self):
        self.tiow.close()


def file_download(url, filename):
    """
    :param url:
    :param filename:
    :return:
    """
    urllib.request.urlretrieve(url, filename)


def get_east_asian_width_count(text):
    """
    Pythonで半角1文字、全角2文字として文字数(幅)カウント | note.nkmk.me
    https://note.nkmk.me/python-unicodedata-east-asian-width-count/

    :param text:
    :return:
    """
    count = 0
    for c in text:
        if unicodedata.east_asian_width(c) in 'FWA':
            count += 2
        else:
            count += 1
    return count


def space_ume(text):
    """
    12byteまで半角スペースで埋める
    :param text:
    :return:
    """
    for i in range(10):
        if get_east_asian_width_count(text) >= 12:
            break
        text = "{} ".format(text)
    return text


def main():
    args = sys.argv
    url = args[1]
    json_path = args[2]
    kif_path = args[3]

    file_download(url, json_path)

    # json.loadsでjsonを読み込み、for ループで特定の要素を抜き出すサンプル - Database JUNKY
    # https://hit.hateblo.jp/entry/python3/json
    f = open(json_path, 'r', encoding="utf-8")
    json_dict = json.load(f)

    if os.path.exists(kif_path):
        os.remove(kif_path)
    tiow = FileWriter(kif_path)

    outlist = list(['# --- 棋譜解説 V1.70 棋譜ファイル ---'])
    outlist.append("開始時刻:{}".format(json_dict['data'][0]['starttime']))
    outlist.append("終了時刻:{}".format(json_dict['data'][0]['endtime']))
    outlist.append("棋戦:{}".format(json_dict['data'][0]['event']))
    outlist.append("持ち時間:{}時間".format(json_dict['data'][0]['timelimit']))
    outlist.append("場所:{}".format(json_dict['data'][0]['place']))
    outlist.append("備考:{}".format(json_dict['data'][0]['note'].strip()))
    outlist.append("振り駒:あり")
    outlist.append("計測時方式:{}".format(json_dict['data'][0]['gametype']))
    outlist.append("秒読み:{}".format(json_dict['data'][0]['countdown']))
    dinnertime_start = json_dict['data'][0]['dinnertime_start']
    dinnertime_end = json_dict['data'][0]['dinnertime_end']
    outlist.append("夕食休憩:{}~{}".format(dinnertime_start, dinnertime_end))
    outlist.append("封じ手手数:0")
    outlist.append("手合割:{}".format(json_dict['data'][0]['handicap']))
    outlist.append("先手:{}".format(json_dict['data'][0]['player1']))
    outlist.append("後手:{}".format(json_dict['data'][0]['player2']))
    outlist.append("手数----指手---------消費時間--")

    for item in outlist:
        tiow.write(item)

    for key in json_dict['data'][0]['kif']:
        move = key['move']

        # 左成、右成から左右を削除
        # move.replace('左', '') # これは効かない
        move = re.sub(r'', '', move)
        move = re.sub(r'', '', move)

        if move == "投了":
            break

        if len(move) == 2:
            m = move
            m = "{}{}{}".format(m[:1], " ", m[1:])
            move = m

        if key['frY'] == 0 or key['frY'] == 10:
            move = "{}{}".format(move, "")
        else:
            xy = key['frX'] * 10 + key['frY']
            move = "{}({})".format(move, xy)

        move = space_ume(move)

        tiow.write("{:4d} {:<8} ({})".format(key['num'], move, " 0:00/00:00:00"))


if __name__ == "__main__":
    main()

0
0
2

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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?