Pythonプログラミングで

チェスを作る

Stage 9 ゲーム進行を記録する

9-2 棋譜から余計な文字を削除する

board.py ファイルの Board クラスに record メソッドがありますね。ここで self.s を棋譜としてファイルに記述する作業を行います。

                        
    def record(self, address, logger=None):
        ### LOGGER SETTING
        logger = logger or self.logger
        
        ### ADJUSTING s
        # removing spaces, !, ?
        self.s = self.s.replace(' ', '').replace('!', '').replace('?', '')

        # avoiding bugs
        if len(self.s) == 0:
            logger.debug('len(s) == 0')
            return False

        # normal pattern
        match = re.match(r'^[PRNBQK]?[a-h]?[1-8]?[x]?[a-h][1-8](=[RNBQ]|e.p.)?[\++#]?$', self.s)
        
        # normal pattern matched
        if match:
            s_record = match.group()
        # resign
        elif self.s in ['1-0', '0-1', '1/2-1/2']:
            s_record = self.s
        # castling
        elif self.s in ['O-O-O', 'O-O', 'o-o-o', 'o-o', '0-0-0', '0-0']:
            s_record = self.s.replace('o', 'O').replace('0', 'O')
        # invalid format
        else:
            logger.info('OUT OF FORMAT in record')
            return False
        
        ### RECORDING
        # open the recording file
        f = open(address, 'a')

        # WHITE WINS (BLACK DIDN'T MOVE)
        if s_record == '1-0':
            f.write('1-0')
        # BLACK WINS (WHITE DIDN'T MOVE)
        elif s_record == '0-1':
            f.write('{}\t0-1'.format(self.turn))
        # writing on WHITE side
        elif self.player == WHITE:
            f.write('{}\t'.format(self.turn) + s_record.ljust(12))
        # writing on BLACK side
        elif self.player == BLACK:
            f.write(s_record.ljust(12) + '\n')
        else:
            logger.error('UNEXPECTED VALUE of PLAYER in record')
            print('SYSTEM ERROR')
            sys.exit('SYSTEM ERROR')
        
        f.close()

        # return as succeeded
        return True
                        
                    
UNAVAILABLE

相変わらずクソなげーな

ちゃんと切り分けて説明しますよ。

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

まずは毎度の通り引数を確認します。

                        
    def record(self, address, logger=None):
                        
                    

address は記録するファイルのアドレスですね。MAINRECADDRESS だけでなく SUBRECADDRESS に記録するときもこのメソッドを使いますので、デフォルトの指定は不要です。

まずはいつも通りロガーを設定しましょう。

                        
    def record(self, address, logger=None):
        ### LOGGER SETTING
        logger = logger or self.logger 
                        
                    

もう説明いらないでしょ。

UNAVAILABLE

ちゃんと仕事せえよ

残念でしたぁ〜。4-1 ですでに説明済みです。仕事終わってますぅ〜。

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

7-1 でやったように、self.s から不要な文字を取り除いて、棋譜として残すのにふさわしい形にします。

                        
        ### ADJUSTING s
        # removing spaces, !, ?
        self.s = self.s.replace(' ', '').replace('!', '').replace('?', '')
                    
        # avoiding bugs
        if len(self.s) == 0:
            logger.debug('len(s) == 0')
            return False
                        
                    

ほんとに 7-1 と同じですよ。コピペで結構です。

それが終わったら s_record という文字列変数に棋譜を格納します。7-2 で扱った正規表現に基づいたものと、それ以外のもので分けていますね。

                        
        # normal pattern
        match = re.match(r'^[PRNBQK]?[a-h]?[1-8]?[x]?[a-h][1-8](=[RNBQ]|e.p.)?[\++#]?$', self.s)
        
        # normal pattern matched
        if match:
            s_record = match.group()
        # resign
        elif self.s in ['1-0', '0-1', '1/2-1/2']:
            s_record = self.s
        # castling
        elif self.s in ['O-O-O', 'O-O', 'o-o-o', 'o-o', '0-0-0', '0-0']:
            s_record = self.s.replace('o', 'O').replace('0', 'O')
        # invalid format
        else:
            logger.info('OUT OF FORMAT in record')
            return False
                        
                    

別枠に設けられているキャスリングは "O" を用いるのがが本来の形ですけれども、このコードでは数字のゼロを使って "0-0-0" という形や、小文字を使って "o-o" とした形も許容していますので、「キャスリング該当の場合に限り」"o" と "0" を "O" へ変換します。

UNAVAILABLE

最初から ゼロ → オー にすりゃいいじゃんか

キャスリングでない場合に 0 → O (ゼロからオー)の変換をすると、勝敗を表す "1-0", "0-1" にまで影響が及びますので注意してください。8-3 で説明済みです。

NEXT 9-3 記録ファイルに棋譜を書き込む