Stage 5 駒を動かす
5-2 キャスリングの例外処理をする
ここからは「ただ自分の駒をそのまま動かすだけじゃいけない動き」を扱って行きます。
代表格がキャスリングですね。キングだけじゃなくてルークも移動しなければいけませんから。
~~~~~~~~~~~~~~~
まず move の引数から「これはキャスリングしようとしているな」と判別できなければなりません。5-7 でも確認した通り、キャスリングはキングの動きとして扱いますから、まずは「動かそうとしている駒がキングだ」ということを見極めます。
そのために piece 変数を定義しています。
piece = abs(self.board[frFILE][frRANK])
player については不要です。実際に駒を動かすのは self.player ですから、新しく変数使う必要ないでしょ?
じゃあなんで motionjudge のときは self.player を使わなかったん?
そんなに知りたいなら motionjudge のキャスリングのところでどうやって「相手にチェックされているか」を調べたか思い出してください。忘れた?しゃーねーな、ここだよここ。
~~~~~~~~~~~~~~~
さて、キングが横に 2 マス以上進んでいれば間違いなくキャスリングですね。本来なら1マスしか進めないんですから。直下の if 文によって piece がキングでヨコに 2 マス以上の移動をしていることが分かったとしましょう。
### SPECIAL EVENTS
# castling
if piece == KING and abs(toFILE - frFILE) > 1:
# preparing the rank
if self.player == WHITE:
rank = 1 - 1
elif self.player == BLACK:
rank = 8 - 1
else:
logger.error('UNEXPECTED VALUE of PLAYER in move')
print('SYSTEM ERROR')
sys.exit('SYSTEM ERROR')
キャスリングはすべて同じ rank 内で行われます。その番号は白と黒で異なりますので、このあと行う場合分けが少なく済むように rank という変数を用意しておきます。白黒それぞれ第 1, 第 8 rank です。インデックスとして使いますので、-1 をお忘れなく。
### SPECIAL EVENTS
# castling
if piece == KING and abs(toFILE - frFILE) > 1:
# preparing the rank
if self.player == WHITE:
rank = 1 - 1
elif self.player == BLACK:
rank = 8 - 1
else:
logger.error('UNEXPECTED VALUE of PLAYER in move')
print('SYSTEM ERROR')
sys.exit('SYSTEM ERROR')
~~~~~~~~~~~~~~~
今度は file の変化からクイーンサイドとキングサイドで場合分けします。移動先が c の file であればクイーンサイド、g の file であればキングサイドです。
場合わけに則ってルークを動かします。
# moving rook
if toFILE == c - 1:
self.board[d - 1][rank] = self.player * ROOK
self.board[a - 1][rank] = EMPTY
elif toFILE == g - 1:
self.board[f - 1][rank] = self.player * ROOK
self.board[h - 1][rank] = EMPTY
else:
logger.error('UNEXPECTED VALUE of toFILE in move')
return False
キャスリングが終われば元々ルークのあった場所は何も残らないので、しっかり EMPTY にしておきましょう。これ忘れると「あれれ?ルークが増えてるぞ?」なんて奇怪なことになりかねません。
~~~~~~~~~~~~~~~
これでルークの移動は完璧です。
よっしゃキング動かすぜ
キングはあとで他の場合と一緒に動かしますから、残しておいてください。