Pythonプログラミングで

チェスを作る

Stage 10 記録からゲームを進める

10-3 1手戻る機能を実装する

ここまで棋譜を再現するように駒を動かす機能を実装してきました。これを使うと「1 手戻る」という非常に魅力的な機能を実装できます。

8-48-5 で実装した部分の続き、playmode で特殊イベントを扱ったところにコーディングします。

                        
        # help code
        if main_board.s in ['H', 'h']:
            ...
        # resign code
        if main_board.s in ['X', 'x']:
            ...
        # back code
        if main_board.s in ['Z', 'z']:
            # necessary for the opponent to allow the player to back
            if main_board.player == WHITE:
                print('Do you agree, BLACK (y/n)? >>> ', end='')
            elif main_board.player == BLACK:
                print('Do you agree, WHITE (y/n) >>> ', end='')
            else:
                logger.error('UNEXPECTED VALUE of PLAYER in the while loop')
                sys.exit('SYSTEM ERROR')
            # in case rejected
            if input() not in ['y', 'Y', 'Yes', 'YES', 'yes']:
                continue
            # in case allowed
            new_board = main_board.tracefile(main_board.turn - 1, main_board.player, isrecwrite=True)
            # unavailable to back
            if new_board == main_board:
                logger.warning('IMPOSSIBLE TO BACK')
                print('SORRY, NOW WE CANNOT BACK THE BOARD')
            # available to back
            else:
                main_board = new_board
                main_board.print(turnmode=turnmode)
            continue        
                        
                    

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

まず相手に確認をとります。

                        
        # back code
        if main_board.s in ['Z', 'z']:
            # necessary for the opponent to allow the player to back
            if main_board.player == WHITE:
                print('Do you agree, BLACK (y/n)? >>> ', end='')
            elif main_board.player == BLACK:
                print('Do you agree, WHITE (y/n) >>> ', end='')
            else:
                logger.error('UNEXPECTED VALUE of PLAYER in the while loop')
                sys.exit('SYSTEM ERROR')
                        
                    

本来こういうボードゲームで「待った」はなしなので、ここは外さないでください。もし相手が yes と言わなければ当然 continue して while ループの先頭に戻り、同じプレーヤーにもう一度操作を考え直してもらいます。

                        
            # in case rejected
            if input() not in ['y', 'Y', 'Yes', 'YES', 'yes']:
                continue 
                        
                    

それ以外、相手から了承 "y" が得られれば、new_board にひとつ前の自分のターンで駒を動かす直前の状態を代入します。

                        
            # in case allowed
            new_board = main_board.tracefile(main_board.turn - 1, main_board.player, isrecwrite=True)
                        
                    

要はここまでの棋譜をもう一度はじめからたどって、player が駒を動かす直前の状態にしています。

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

もし new_board が main_board と同じであれば、tracefile は定義したクラスでいう self をリターンしたことになりますから失敗です。

                        
            # unavailable to back
            if new_board == main_board:
                logger.warning('IMPOSSIBLE TO BACK')
                print('SORRY, NOW WE CANNOT BACK THE BOARD')
                        
                    
UNAVAILABLE

tracefile が self をリターンすんのは destination に辿りつかなかった場合だったな

そのほかの場合は成功していますから、main_board へ new_board を代入します。

                        
            # available to back
            else:
                main_board = new_board
                main_board.print(turnmode=turnmode)
                        
                    

そして main_board.print を忘れずに。プレーヤーとしてはこれがないと

UNAVAILABLE

あれ、本当に戻ったのかな

と不安になってしまいます。

成功にせよ失敗にせよ、次の操作も同じ人が行いますので continue してループ先頭へ行ってください。

                        
            # available to back
            else:
                main_board = new_board
                main_board.print(turnmode=turnmode)
            continue
                        
                    

NEXT 10-4 棋譜からゲームを再現する機能を実装する