Stage 10 記録からゲームを進める
10-1 記録ファイルを読み込む
これ以降は board.py ファイル Board クラスの tracefile メソッドにコーディングします。
def tracefile(self, destination_turn, destination_player, isrecwrite=True, logger=None):
### LOGGER SETTING
logger = logger or self.logger
# in case back to the first
if destination_turn == 1 and destination_player == WHITE:
local_board = Board()
return local_board
# preparing (initializing) the sub file; all the local moves are recorded on the sub file
open(SUBRECADDRESS, 'w').close()
# reading the main file
f = open(MAINRECADDRESS, 'r')
line = f.read()
f.close()
# deleting first and last spaces
line = line.strip()
logger.info('line is "{}"'.format(line))
# local Board
local_board = Board()
# DETECTING EACH LETTER IN LINE
for letter in line:
# when you come to the end of a sentence
if letter in [' ', '\t', '\n', ',', '.']:
logger.info('local_board.s is {}'.format(local_board.s))
motion = local_board.s_analyze()
# normal motion
if type(motion) is list:
local_board.move(*motion)
local_board.record(SUBRECADDRESS) # all the local moves are recorded on the sub file
# parameter manipulations
if local_board.player == BLACK:
local_board.turn += 1
local_board.player *= -1
# reaching destination
if local_board.turn == destination_turn and local_board.player == destination_player:
logger.info('trace succeeded')
if isrecwrite:
# copying the file
f = open(MAINRECADDRESS, 'w')
g = open(SUBRECADDRESS, 'r')
f.write(g.read())
f.close()
g.close()
return local_board
# game set
elif type(motion) is int:
print('GAME SET')
if isrecwrite:
# copying the record
f = open(MAINRECADDRESS, 'w')
g = open(SUBRECADDRESS, 'r')
f.write(g.read())
f.close()
g.close()
return motion
# initializing local_board.s
local_board.s = ''
# the sentence does not end yet
else:
local_board.s = ''.join([local_board.s, letter])
logger.debug('local_board.s = {}'.format(local_board.s))
# last one local_board.s; the same as in the for loop
logger.info('local_board.s is {}'.format(local_board.s))
motion = local_board.s_analyze()
if type(motion) is list:
local_board.move(*motion)
local_board.record(SUBRECADDRESS)
if local_board.player == BLACK:
local_board.turn += 1
local_board.player *= -1
# reaching destination
if local_board.turn == destination_turn and local_board.player == destination_player:
logger.info('trace succeeded')
if isrecwrite:
f = open(MAINRECADDRESS, 'w')
g = open(SUBRECADDRESS, 'r')
f.write(g.read())
f.close()
g.close()
return local_board
elif type(motion) is int:
if isrecwrite:
f = open(MAINRECADDRESS, 'w')
g = open(SUBRECADDRESS, 'r')
f.write(g.read())
f.close()
g.close()
return motion
# reaching here, you cannot trace
logger.warning('FAILED TO BACK')
return self
ウッソ......だろ......
こいつを全 4 回に分けてご説明します。
~~~~~~~~~~~~~~~
指定のターン・プレーヤーの手番の直前までゲームを進める機能です。例えばこういう記録がついていたとして
1 a4 c5 2 g3 Qa5 3 e4 Qa6
第 2 ターンの黒まで戻ると指定すると Qa5 を実行する
前
まで戻ります。つまり盤面はこう。
Qa5 の前だから、まだ Qa5 してないんだな。
その通りです。
~~~~~~~~~~~~~~~
まずは引数を見ていきましょう。
def tracefile(self, destination_turn, destination_player, isrecwrite=True, logger=None):
destination_turn | ゴールとなる指定ターン |
destination_player | ゴールとなる指定プレーヤー |
isrecwrite | 記録を書き換えるか |
先ほどの例で言えば、destination_turn=2, destination_player=BLACK で第 2 ターン黒が Qa5 とする
前
まで戻ってくれます。
中身に入ります。最初はやっぱりロガーを設定します。
def tracefile(self, destination_turn, destination_player, isrecwrite=True, logger=None):
### LOGGER SETTING
logger = logger or self.logger
ここは Board クラスの中身ですから、ロガーは指定のない限りクラスのロガーを使うのがいいでしょう。
~~~~~~~~~~~~~~~
ここから先ではメソッド内で local_board という Board の影武者インスタンスを作成し、これをいじります。
何回かやったな
ええ、6-3 なんかで。
コードに戻りましょう。まず第 1 ターンで白が駒を動かす直前で操作を止める場合、まだ駒は初期配置ですから、local_board を初期設定してすぐにリターンしてください。
# in case back to the first
if destination_turn == 1 and destination_player == WHITE:
local_board = Board()
return local_board
別に場合わけなんてせんでええやろ
なんで場合わけが必要なのかはもうちょい先になるまでわかりませんよ。
~~~~~~~~~~~~~~~
そのほか駒の動きを要する場合は、まず SUBRECADDRESS を書き込みモード 'w' で開いた後すぐに閉じて初期化、真っ白にします。
# preparing (initializing) the sub file; all the local moves are recorded on the sub file
open(SUBRECADDRESS, 'w').close()
次いで MAINRECADDRESS の中身をすべて line に読み取ってしまいます。同時に両端にある空白文字と改行文字を strip メソッドですべて消します。
# reading the main file
f = open(MAINRECADDRESS, 'r')
# deleting first and last spaces
line = f.read()
f.close()
# deleting first and last spaces
line = line.strip()
logger.info('line is "{}"'.format(line))
~~~~~~~~~~~~~~~
line には棋譜として意味のある文だけでなく、例えばターン番号を表す数字が入っているなど、無視しなければいけない文があります。例えばこんな感じ。
1\ta4 c5 \n2\tg3 Qa5
タブ文字とか改行が余分に入ってんのか
無視すべき文を無視し、拾うべき文を拾う。これが tracefile に求められる機能です。
それでは local_board を宣言して一文一文に目を向けていきましょう。
# local Board
local_board = Board()