[方策ネットワーク]
第7章5〜7
read_kifu.py
read_kifu()
引数:棋譜ファイルのパスを羅列したテキストファイル
出力:(「局面図」「指し手」「勝敗」)を局面ごとに算出し、1局面を1要素としてリストに追加していき、全棋譜を読み込み終わったら一つのリストとして出力する。
1局面のデータは下記5要素で構成。
-piece_bb:15要素
-occupied:2要素
-pieces_in_hand:2要素
-move_label:1要素
-win:1要素
最終的な出力は[([15要素], [2要素], [2要素], [1要素], [1要素]), (同じセット), ・・・が手数 x 対局数]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import shogi
import shogi.CSA
import copy
from pydlshogi.features import *
from pydlshogi.common import * ##################test
# read kifu
def read_kifu(kifu_list_file):
i = 0
positions = []
with open(kifu_list_file, 'r') as f:
for line in f.readlines():
filepath = line.rstrip('\r\n')
i += 1
print(i)
# 棋譜データを変数kifuに代入。
# 棋譜データはnames、sfen、moves、winの4つのキーを持ったディクショナリ。
# このディクショナリが1要素としてリストに入っている。[0]でディクショナリだけ取り出す。
kifu = shogi.CSA.Parser.parse_file(filepath)[0]
win_color = shogi.BLACK if kifu['win'] == 'b' else shogi.WHITE
board = shogi.Board()
for move in kifu['moves']:
# ■board:print(board)で盤面を2次元表示できる。
# ■piece_bb:15要素の配列。各要素は各駒の配置を示す。0:空白、1:歩、2:香、・・・
# bit board。bit boardとは下記のようなもの。
# 各要素が81桁(=81マス)の2進数(つまりbit board)の10進数表示である。
# 2進数81桁表示したいときはprint('{:0=81b}'.format(10進数の値)) でできる。
# ■occupied:2要素の配列。各要素は先手後手の占有している駒の位置。bit board。
# ■pieces_in_hand:2要素の配列。各要素は先手後手がどの駒(=key)を何枚(=value)持っているかを示すディクショナリ型。
if board.turn == shogi.BLACK:
piece_bb = copy.deepcopy(board.piece_bb)
occupied = copy.deepcopy((board.occupied[shogi.BLACK], board.occupied[shogi.WHITE]))
pieces_in_hand = copy.deepcopy((board.pieces_in_hand[shogi.BLACK], board.pieces_in_hand[shogi.WHITE]))
else:
piece_bb = [bb_rotate_180(bb) for bb in board.piece_bb]
occupied = (bb_rotate_180(board.occupied[shogi.WHITE]), bb_rotate_180(board.occupied[shogi.BLACK]))
pieces_in_hand = copy.deepcopy((board.pieces_in_hand[shogi.WHITE], board.pieces_in_hand[shogi.BLACK]))
# move label
i_move = shogi.Move.from_usi(move) # 指し手の変数moveを引数としてMoveクラスのインスタンスを生成
move_label = make_output_label(i_move, board.turn)
# ■ Moveクラス
# from_square変数 :盤面を0~80の数値で表したときの移動元の値。
# 9で割ったときの商がy座標、余りがx座標となる。xy座標は0オリジン。
# to_square変数 :同上(移動先)。
#
# x座標
# 0 1 2 3 4 5 6 7 8
#
# 0 1 2 3 4 5 6 7 8 0 y座標
# 9 10 11 12 13 14 15 16 17 1
# 18 19 20 21 22 23 24 25 26 2
# 27 28 29 30 31 32 33 34 35 3
# 36 37 38 39 40 41 42 43 44 4
# 45 46 47 48 49 50 51 52 53 5
# 54 55 56 57 58 59 60 61 62 6
# 63 64 65 66 67 68 69 70 71 7
# 72 73 74 75 76 77 78 79 80 8
#
# print(board)
#
# try:
# y_from, x_from = divmod(s.from_square, 9)
# y_to, x_to = divmod(s.to_square, 9)
# print('from:',x_from, y_from)
# print('to :',x_to, y_to)
#
# move_direction = DOWN
# print('moved:', move_direction)
# except:
# pass
# result
win = 1 if win_color == board.turn else 0
# 変数positionsに局面(最初の3つの変数)、その局面での指し手、勝敗を追加
positions.append((piece_bb, occupied, pieces_in_hand, move_label, win))
# 1手進める
board.push_usi(move)
return positions
コメント