Stage 6 勝敗を判定する
6-2 チェックの数を数える
お次はチェックの判定です。
まあ判定と呼ぶくらいですからチェックの有無を True / False でリターンするメソッドかけば事足りますよ。でもダブルチェックとかトリプルチェックという表し方がチェスの棋譜にはありまして、それを見据えて何ヶ所でチェックされているかをリターンする機能が欲しいなと。
なんでめんどくせーことすんだよ
プログラミングはいつもユーザー第一ですから。
じゃあターミナルで棋譜使ってチェスなんてやらせるなよ
それはごもっともだ。
~~~~~~~~~~~~~~~
で、checkcounter メソッドです。
def checkcounter(self, checkee, logger=None):
### LOGGER SETTING
logger = logger or self.logger
### SEARCHING FOR CHECKEE'S KING
TO = self.king_place(checkee)
try:
toFILE = TO[FILE]
toRANK = TO[RANK]
except:
logger.info('THERE IS NO KING ON THE BOARD')
return False
# COUNTING UP CHECKS
count = 0
# searching all the squares, count up the checking pieces
for frFILE in range(SIZE):
for frRANK in range(SIZE):
# pawn might capture the king by promoting, so do not forget promote=Q or something
if fundam.PosNeg(self.board[frFILE][frRANK]) == -checkee and self.motionjudge(frFILE, frRANK, toFILE, toRANK, Q):
logger.info('CHECK: {}, {} -> {}, {}'.format(frFILE, frRANK, toFILE, toRANK))
count += 1
# if checkee is not checked, return 0
return count
~~~~~~~~~~~~~~~
中身を見ていきましょう。
def checkcounter(self, checkee, logger=None):
引数の checkee は
チェックを受けている
プレーヤー番号です。間違えないでください。しっかりわかるようにあえてこの名前をつけたんですから。それなりに英語をやった人ならわかるでしょ?
~~~~~~~~~~~~~~~
中に入ったらまずはロガーを設定して、
def checkcounter(self, checkee, logger=None):
### LOGGER SETTING
logger = logger or self.logger
6-1 で作った king_place で checkee のキングを探します。そもそもキングがいなければ相手はチェックのしようがないので、キングがいなければ別処理。
### SEARCHING FOR CHECKEE'S KING
TO = self.king_place(checkee)
try:
toFILE = TO[FILE]
toRANK = TO[RANK]
except:
logger.info('THERE IS NO KING ON THE BOARD')
return False
もしキングがいない (king_place が EMPTY つまり 0) なら、TO の型は list ではなく int になりますから、try 文の中でわざとエラーを起こして except へ入り False をリターンする仕組みになっています。
エラー起きなかったらそのまま TO にキングの位置が入るんやな
そうです。
~~~~~~~~~~~~~~~
その後チェックの個数を記録する count という変数を用意します。
# COUNTING UP CHECKS
count = 0
# searching all the squares, count up the checking pieces
for frFILE in range(SIZE):
for frRANK in range(SIZE):
for 文によって盤面上すべての相手の駒の座標を frFILE, frRANK の中に入れ
# COUNTING UP CHECKS
count = 0
# searching all squares for opponent's piece to reach KING
for frFILE in range(SIZE):
for frRANK in range(SIZE):
# pawn might capture the king by promoting, so do not forget promote=Q or something
if fundam.PosNeg(self.board[frFILE][frRANK]) == -checkee and self.motionjudge(frFILE, frRANK, toFILE, toRANK, Q):
駒が checkee にとって相手のものだったら
for frFILE in range(SIZE):
for frRANK in range(SIZE):
# pawn might capture the king by promoting, so do not forget promote=Q or something
if fundam.PosNeg(self.board[frFILE][frRANK]) == -checkee and self.motionjudge(frFILE, frRANK, toFILE, toRANK, Q):
logger.info('CHECK: {}, {} -> {}, {}'.format(frFILE, frRANK, toFILE, toRANK))
count += 1
motionjudge を実行してみます。
for frFILE in range(SIZE):
for frRANK in range(SIZE):
# pawn might capture the king by promoting, so do not forget promote=Q or something
if fundam.PosNeg(self.board[frFILE][frRANK]) == -checkee and self.motionjudge(frFILE, frRANK, toFILE, toRANK, Q):
logger.info('CHECK: {}, {} -> {}, {}'.format(frFILE, frRANK, toFILE, toRANK))
count += 1
もし motionjudge が True をリターンすれば「キングのいるマスに行ける」つまりチェックしていることになりますから、チェックの数を数えてくれてる count の値を増やしてあげましょう。この時ロガーも一緒に出してあげると親切ですね。
# pawn might capture the king by promoting, so do not forget promote=Q or something
if fundam.PosNeg(self.board[frFILE][frRANK]) == -checkee and self.motionjudge(frFILE, frRANK, toFILE, toRANK, Q):
logger.info('CHECK: {}, {} -> {}, {}'.format(frFILE, frRANK, toFILE, toRANK))
count += 1
~~~~~~~~~~~~~~~
ループを抜けたら count をリターンします。
# if checkee is not checked, return 0
return count
つまりチェックされている回数が返されます。もしチェックされていなければ
リターンは 0
です。False ではないことに注意してください。