Pythonプログラミングで

チェスを作る

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) とすればできますね。

UNAVAILABLE

~~~~~~~~~~~~~~~

その次は 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 はこんな感じに動きます。

UNAVAILABLE

上の例では 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]
                        
                    
UNAVAILABLE

いやいや、目的地通り越したらアウトだろ

ええ、ですからここはシステムエラーということで強制終了しても構いませんよ。

~~~~~~~~~~~~~~~

特にイベントが起こらなかった場合は 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 の各座標に加えればいいですね。

UNAVAILABLE

while ループをすべてクリアしたら途中に障害物となる駒はありません。他に確認することもありませんから、True を返して問題ないでしょう。

お疲れ様でした。これにて駒の動きの判定は終了です。

NEXT Stage 5 駒を動かす