Pythonプログラミングで

チェスを作る

Stage 5 駒を動かす

5-2 キャスリングの例外処理をする

ここからは「ただ自分の駒をそのまま動かすだけじゃいけない動き」を扱って行きます。

代表格がキャスリングですね。キングだけじゃなくてルークも移動しなければいけませんから。

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

まず move の引数から「これはキャスリングしようとしているな」と判別できなければなりません。5-7 でも確認した通り、キャスリングはキングの動きとして扱いますから、まずは「動かそうとしている駒がキングだ」ということを見極めます。

そのために piece 変数を定義しています。

                        
        piece = abs(self.board[frFILE][frRANK])
                        
                    

player については不要です。実際に駒を動かすのは self.player ですから、新しく変数使う必要ないでしょ?

UNAVAILABLE

じゃあなんで 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 であればキングサイドです。

UNAVAILABLE

場合わけに則ってルークを動かします。

                        
            # 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 にしておきましょう。これ忘れると「あれれ?ルークが増えてるぞ?」なんて奇怪なことになりかねません。

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

これでルークの移動は完璧です。

UNAVAILABLE

よっしゃキング動かすぜ

キングはあとで他の場合と一緒に動かしますから、残しておいてください。

NEXT 5-3 アンパッサンの例外処理をする