From 7ede84d4ab1e787e1303df34d98acc8f98aa5b35 Mon Sep 17 00:00:00 2001 From: fsmosca Date: Sun, 8 Aug 2021 13:14:48 +0800 Subject: [PATCH] Supports interrupt and continue * If the game that is about to be annotated is already in the output file then the annotation is skipped. Sample console log: Annotating game 1... Skip annotation, game 1 is already fully annotated. Annotating game 2... Skip annotation, game 2 is already fully annotated. Annotating game 3... Skip annotation, game 3 is already fully annotated. Annotating game 4... Skip annotation, game 4 is already fully annotated. Annotating game 5... Skip annotation, game 5 is already fully annotated. Annotating game 6... Skip annotation, game 6 is already fully annotated. Annotating game 7... Skip annotation, game 7 is already fully annotated. Annotating game 8... Skip annotation, game 8 is already fully annotated. Annotating game 9... Skip annotation, game 9 is already fully annotated. Annotating game 10... Skip annotation, game 10 is already fully annotated. Annotating game 11... Skip annotation, game 11 is already fully annotated. Annotating game 12... Skip annotation, game 12 is already fully annotated. Annotating game 13... Skip annotation, game 13 is already fully annotated. Annotating game 14... Skip annotation, game 14 is already fully annotated. Annotating game 15... Skip annotation, game 15 is already fully annotated. Annotating game 16... Skip annotation, game 16 is already fully annotated. Annotating game 17... Skip annotation, game 17 is already fully annotated. Annotating game 18... side: White, move_num: 1 side: Black, move_num: 1 --- chess_artist.py | 63 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/chess_artist.py b/chess_artist.py index 1a4d00e..e0bee89 100644 --- a/chess_artist.py +++ b/chess_artist.py @@ -9,8 +9,8 @@ __author__ = 'fsmosca' __script_name__ = 'Chess Artist' -__version__ = 'v2.33.0' -__credits__ = ['alxlk', 'ddugovic', 'huytd', 'kennyfrc', 'PixelAim', +__version__ = 'v3.0.0' +__credits__ = ['al75an', 'alxlk', 'ddugovic', 'huytd', 'kennyfrc', 'PixelAim', 'python-chess'] @@ -142,8 +142,6 @@ def Getboard(self, fen): else: raise Exception(f'Variant {self.variantTag} is not supported.') - return None - def UciToSanMove(self, fen, uciMove): """ Returns san move given fen and uci move """ board = self.Getboard(fen) @@ -1762,6 +1760,42 @@ def relative_score(side, score): :score: is wpov in pawn unit """ return score if side else -score + + def GameExist(self, header, baseHeader): + """ + Returns true if header is found in baseHeader list. + """ + for g in baseHeader: + if g == header: + return True + + return False + + def SavegameHeaders(self): + gameHeaders = [] + + outfile_path = Path(self.outfn) + if not outfile_path.is_file(): + return gameHeaders + + with open(self.outfn, encoding='ISO-8859-1') as h: + while True: + game = chess.pgn.read_game(h) + if game is None: + break + + # Copy game headers except Annotator tag. + header = {} + for key, value in game.headers.items(): + if key != 'Annotator': + header.update({key: value}) + + # Add ActualPly header in the game. This is also used to determine + # if a game is already fully annotated. + header.update({'ActualPly' : str(game.end().ply())}) + gameHeaders.append(header) + + return gameHeaders def AnnotatePgn(self): """ Parse the pgn file and annotate the games """ @@ -1769,6 +1803,9 @@ def AnnotatePgn(self): engineIdName = self.engIdName gameCnt = 0 + # Save the headers of the input pgn file. + outputGameHeaders = self.SavegameHeaders() + with open(self.infn, encoding='ISO-8859-1') as pgnHandle: while True: game = chess.pgn.read_game(pgnHandle) @@ -1777,6 +1814,21 @@ def AnnotatePgn(self): gameCnt += 1 + # Show progress in console. + print('Annotating game %d...' % (gameCnt)) + + # Check if this game is already annotated. + tmpHeader = {} + for key, value in game.headers.items(): + if key != 'Annotator': + tmpHeader.update({key: value}) + tmpHeader.update({'ActualPly': str(game.end().ply())}) + + if self.GameExist(tmpHeader, outputGameHeaders): + logging.info('Skip annotation, game {gameCnt} is already fully annotated.') + print(f'Skip annotation, game {gameCnt} is already fully annotated.') + continue + # Get variant name in pgn tag, try to cover as wide as possible. # Lichess: Chess960 # Chess.com: Chess960 @@ -1854,9 +1906,6 @@ def AnnotatePgn(self): # Used for formatting the output. self.writeCnt = 0 - # Show progress in console. - print('Annotating game %d...' %(gameCnt)) - # Save the tag section of the game. outfile_path = Path(self.outfn)