将棋AIで学ぶディープラーニング on Mac and Google Colab

AI

[方策ネットワーク]
第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

コメント

タイトルとURLをコピーしました