Stage 4 駒の動きを判定する
4-5 駒を飛び越える動きを除外する
キングまで終わったからって気を緩めてはいけません。ルークやビショップなど、駒をまたぐ動きを放置したまんまでしょう。ケリをつけます。
# SEARCHING FOR AN OBSTACLE IN THE WAY OF Q/R/B
direction = [fundam.PosNeg(toFILE - frFILE), fundam.PosNeg(toRANK - frRANK)] # ex. [f, r] + UP = [f, r - 1]
focused = [frFILE + direction[FILE], frRANK + direction[RANK]] # focused square
while focused[FILE] != toFILE or focused[RANK] != toRANK: # while not reaching TO
# out of the board
if not (fundam.InSize(focused[0]) and fundam.InSize(focused[1])):
logger.warning('direction does not reach TO')
break
# if there is a piece on the way
if self.board[focused[FILE]][focused[RANK]] != EMPTY:
logger.debug('THERE IS AN OBSTACLE in the way')
return False
# controlling parameters
focused[FILE] += direction[FILE]
focused[RANK] += direction[RANK]
# there is nothing in the wauy
return True
~~~~~~~~~~~~~~~
まずリスト型で direction を定義していますね。
# SEARCHING FOR AN OBSTACLE IN THE WAY OF Q/R/B
direction = [fundam.PosNeg(toFILE - frFILE), fundam.PosNeg(toRANK - frRANK)] # ex. [f, r] + UP = [f, r - 1]
focused = [frFILE + direction[FILE], frRANK + direction[RANK]] # focused square
文字通り駒の進む方向を表しています。この方向は [+1, +1], [-1, 0], ... といった具合に、「一歩先のマスに行くとき加える値」を表しています。
白側からみて、左に行くのであれば [-1, 0], 右後ろへは [+1, -1] といったように。各要素の値は ±1 か 0 のどれかですから、これは file, rank それぞれに対し、PosNeg(to - fr) とすればできますね。
~~~~~~~~~~~~~~~
その次は focused です。「注目しているマス」を表しています。
# SEARCHING FOR AN OBSTACLE IN THE WAY OF Q/R/B
direction = [fundam.PosNeg(toFILE - frFILE), fundam.PosNeg(toRANK - frRANK)] # ex. [f, r] + UP = [f, r - 1]
focused = [frFILE + direction[FILE], frRANK + direction[RANK]] # focused square
例えばルークを rank が減る方向に動かそうとしたとき、focused はこんな感じに動きます。
上の例では focused がポーンにぶつかっていますよね。移動先がこのポーンよりも向こう側にあればポーンを飛び越えて移動することになりますので、ルール違反となります。
こんな具合に、まだ focused が移動先までたどり着いていないのに board[focused[FILE]][focused[RANK]] が EMPTY でなければ、入力された動きは途中で駒にでくわしたことになりますから「動かせない」False をリターンします。
while focused[FILE] != toFILE or focused[RANK] != toRANK: # while not reaching TO
# out of the board
if not (fundam.InSize(focused[0]) and fundam.InSize(focused[1])):
logger.warning('')
break
# if there is a piece on the way
if self.board[focused[FILE]][focused[RANK]] != EMPTY:
logger.debug('THERE IS AN OBSTACLE in the way')
return False
# controlling parameters
focused[FILE] += direction[FILE]
focused[RANK] += direction[RANK]
~~~~~~~~~~~~~~~
盤面の外に出た場合は、目的地すら通り過ごしていますのでちょっと注意が必要ですが、とりあえず障害物はありませんから while を脱出しましょう。
while focused[FILE] != toFILE or focused[RANK] != toRANK: # while not reaching TO
# out of the board
if not (fundam.InSize(focused[0]) and fundam.InSize(focused[1])):
logger.warning('')
break
# if there is a piece on the way
if self.board[focused[FILE]][focused[RANK]] != EMPTY:
logger.debug('THERE IS AN OBSTACLE in the way')
return False
# controlling parameters
focused[FILE] += direction[FILE]
focused[RANK] += direction[RANK]
いやいや、目的地通り越したらアウトだろ
ええ、ですからここはシステムエラーということで強制終了しても構いませんよ。
~~~~~~~~~~~~~~~
特にイベントが起こらなかった場合は focused を動かします。
while focused[FILE] != toFILE or focused[RANK] != toRANK: # while not reaching TO
# out of the board
if not (fundam.InSize(focused[0]) and fundam.InSize(focused[1])):
logger.warning('')
break
# if there is a piece on the way
if self.board[focused[FILE]][focused[RANK]] != EMPTY:
logger.debug('THERE IS AN OBSTACLE in the way')
return False
# controlling parameters
focused[FILE] += direction[FILE]
focused[RANK] += direction[RANK]
先ほども申しました通り、次のマスへ行くには direction の各要素を focused の各座標に加えればいいですね。
while ループをすべてクリアしたら途中に障害物となる駒はありません。他に確認することもありませんから、True を返して問題ないでしょう。
お疲れ様でした。これにて駒の動きの判定は終了です。