【Python】【将棋ネタ】自身の棋譜に対して同一局面検索を行う

はじめに

PCソフト「激指」と対戦した棋譜を使って同一局面検索を行います。
KIF形式で保存した棋譜データをあらかじめSFNEに変換しておく必要があります。
その変換に関しては前回の記事に書きました。
touch-sp.hatenablog.com
今回は変換後のファイルを使用します。

Pythonスクリプト

import sys
import re
import glob
import os

sfen_files = glob.glob('sfen/*.sfen')

while True:
    input_text = input('sfenを入力して下さい、終了時はq\n')

    if input_text == 'q':
        break
    else:
        input_text = input_text.replace('sfen ', '')
        print('\n')
    
    text_list = input_text.split(' ')

    if len(text_list) < 3:
        print('データが不適です')
        continue

    pattern = r'^' + re.escape(text_list[0]) + r'\s([w|b])\s' + re.escape(text_list[2]) + r'\s' + r'(\d+)$'

    for each_file in sfen_files:
        with open(each_file, 'r') as f:
            my_data = f.read()

        m = re.finditer(pattern, my_data, flags = re.MULTILINE)
        result_list = list(m)

        if len(result_list) != 0:
            print(os.path.basename(each_file))
            sente = re.search(r'^先手:.*$', my_data, flags = re.MULTILINE).group()
            gote = re.search(r'^後手:.*$', my_data, flags = re.MULTILINE).group()
            for mm in result_list:
                teban = mm.groups()[0]
                teban_text = sente if teban == 'b' else gote
                sashite_pattern = r'^' + re.escape(mm.groups()[1]) + r'\s(\S+)$'
                sashite_search = re.search(sashite_pattern, my_data, flags = re.MULTILINE) 
                sashite = sashite_search.groups()[0]
                print('%s手目 %s が %s を指しました\n'%(mm.groups()[1], teban_text, sashite))

sys.exit()

使い方

上記スクリプトを実行するとSFENの文字列を入力するように促されます。

D:\shogi_record>py -3.8 search.py
sfenを入力して下さい、終了時はq
 


ここにSFENの文字列を入力して(貼り付けて)Enterキーを押すだけです。
実際に貼り付けた結果が以下のようになります。

D:\shogi_record>py -3.8 search.py
sfenを入力して下さい、終了時はq
lnsgkgsnl/1r7/ppppp1bpp/5pp2/7P1/2P6/PP1PPPP1P/1B3S1R1/LNSGKG1NL w - 8


20210708_1.sfen
8手目 後手:激指<全戦型>8級 が 42飛(82) を指しました

20210708_3.sfen
8手目 後手:激指<振飛車>8級 が 42飛(82) を指しました

sfenを入力して下さい、終了時はq
 

同一局面が2つ保存されていることがわかります。またその時の指し手もわかるようになっています。

無限ループとなっているので、終了したいときには「q」を入力します。

補足1

おそらく「激指」から直接SFENの文字列を取得することはできないと思います。
無料ソフト「ShogiGUI」を使っています。
 
「激指」上で
「ファイル」>「クリップボード」>「棋譜の書き出し」でいったんクリップボードにコピーして、
「ShogiGUI」上で
「編集」>「棋譜貼り付け」でファイル保存することなく棋譜を移すことが可能です。
 
その後、
「ShogiGUI」上で
「編集」>「局面コピー」>「Sfen」を選択するとSFENの文字列がクリップボードにコピーされます。
 
最後にそれをPythonスクリプトを実行しているターミナルに貼り付けます。

補足2

局面検索の際には手番と手数は使用しないようになっています。
そのためソフト上で盤面編集(局面編集)した図をそのまま使用可能です。