예제 #1
0
def load_game(game: Game, saved_game: chess.pgn.Game) -> None:
    """
    :param game: Game
    :param saved_game: chess.pgn.Game, saved game
    1:  Set up the chess.Board based on the given pgn notes from saved file
    2:  If present (usually is), get the last calculated computer move + ponder
    :param saved_game: pgn string
    :return:
    """
    LOG.info('load GAME')
    try:
        moves_string = files.open_move(config.COMPUTER_MOVE)
        move0 = chess.Move.from_uci(moves_string[:4])
        # There is not always a ponder move
        move1 = chess.Move.from_uci(
            moves_string[4:]) if len(moves_string) > 4 else None
        game.computer_move = chess.engine.PlayResult(move=move0, ponder=move1)
    except (TypeError, ValueError):
        LOG.debug('no saved computer_move present')

    try:
        game.board = saved_game.board()
        for move in saved_game.mainline_moves():
            game.board.push(move)
        # load pgn
        game.pgn_headers = saved_game.headers
        update_pgn_notes(game)
        LOG.info('GAME loaded')
    except (TypeError, ValueError):
        LOG.error('save GAME corrupted!')
        run(['mv', config.SAVEGAME, config.SAVEGAME + 'error'])
        new_game(game)
예제 #2
0
 def get_moves(self, next_game: chess.pgn.Game):
     """
     get moves from one game and append to data_buffer
     param pgn.Game next_game: a game
     return int: number of moves in the game
     """
     data_len = 0  #moves processed
     result = self.get_result(next_game.headers["Result"])
     #white_weight = self.elo_val(int(next_game.headers["WhiteElo"]))
     #black_weight = self.elo_val(int(next_game.headers["BlackElo"]))
     board = chess.Board()
     while not next_game.is_end():
         next_game = next_game.variation(0)
         next_move = next_game.move.uci()
         try:
             k = self.move_hash[next_move]
         except KeyError:
             logger.fatal("keyerror % s" % next_move)
             continue
         if (data_len % 2 == 0):  #white move
             self.data_buffer.append({
                 "s": board.fen(),
                 "a": next_move,
                 "r": result
             })
         else:  #black move
             self.data_buffer.append({
                 "s": board.fen(),
                 "a": next_move,
                 "r": -result
             })
         board.push_uci(next_move)
         data_len += 1
     return data_len
예제 #3
0
def progress_game(game: chess.pgn.Game, number_of_moves: int = 0):
    """
    Advance game to end state
    """
    count = 0
    board = game.board()
    for move in game.mainline_moves():
        board.push(move)
        count += 1
        if (count >= number_of_moves) and number_of_moves:
            break
예제 #4
0
    def analyseGame(self, game: chess.pgn.Game):
        if(game is not game.end()):
            evalList = []
            curGame = game
            size = game.end().ply()
            board = curGame.board()

            with open(self.controller.chessWindow.getOpeningFile(True)) as pgn:
                white_open_game = chess.pgn.read_game(pgn)
            is_white_opening = game.headers["White"].lower(
            ) == white_open_game.headers["White"].lower()

            with open(self.controller.chessWindow.getOpeningFile(False)) as pgn:
                black_open_game = chess.pgn.read_game(pgn)
            is_black_opening = game.headers["Black"].lower(
            ) == black_open_game.headers["Black"].lower()
            opening_game = white_open_game if is_white_opening else (
                black_open_game if is_black_opening else None)
            theory_info_dict = {
                "theoric": True,
                "score": chess.engine.PovScore(
                    chess.engine.Cp(0),
                    chess.WHITE)}
            self.wrapper = BoardAnalysisWrapper(board)
            self.wrapper.start()

            self.controller.progressBar.newEval()
            self.controller.progressBar.progressDelta = 1 / size

            while curGame is not None and not self.stopFlag:
                # equivalent to : opening_game is not None and ...
                if((is_white_opening or is_black_opening) and opening_game.next() is not None and curGame.next().move is not None and (opening_game.next().move == curGame.next().move)):
                    evalList.append((curGame.move, theory_info_dict))
                    opening_game = opening_game.next()
                else:
                    self.wrapper.update(curGame.board())
                    while not self.wrapper.hasFinished() and not self.stopFlag:
                        time.sleep(0.1)
                    if(self.wrapper.bestMove() is not None):
                        info_dict = self.wrapper.getEngineAnalysis()
                        # the last theory move need to have analysis (to
                        # qualify next move)
                        if(is_white_opening or is_black_opening):
                            info_dict.update([("theoric", True)])
                        evalList.append((curGame.move, info_dict))
                    is_white_opening = False  # the opening has ended we don't check anymore
                    is_black_opening = False  # the opening has ended we don't check anymore
                self.controller.progressBar.addEval(evalList[-1][1])
                curGame = curGame.next()
            self.wrapper.stop()
            return evalList
        else:
            return []
예제 #5
0
def process_game(game: chess.pgn.Game, number_of_moves: int = 0) \
                -> Tuple[List[Tuple[int, int, int]], List[Tuple[int, int, int]]]:

    board = game.board()
    piece_count = (
        # chess.BLACK
        {
            chess.BISHOP: 2,
            chess.ROOK: 2,
            chess.KNIGHT: 2,
            chess.QUEEN: 1,
            chess.PAWN: 8,
        },
        # chess.WHITE
        {
            chess.BISHOP: 2,
            chess.ROOK: 2,
            chess.KNIGHT: 2,
            chess.QUEEN: 1,
            chess.PAWN: 8,
        })
    lost_pieces = (
        [],  # chess.BLACK
        [])  # chess.WHITE

    for move in game.mainline_moves():
        count = len(board.move_stack)
        board.push(move)
        turn = board.turn

        # Get captures on this turn
        if board.is_capture(board.peek()):
            piece = get_captures(board, board.peek(), count, piece_count[turn])
            # print(board.is_capture(board.peek()))
            if piece[0]:
                lost_pieces[turn].append(piece)
        if (
                count >= number_of_moves
        ) and number_of_moves:  # Stop after moving n times and n is non-zero
            break

    return lost_pieces
예제 #6
0
def game_capture(game: chess.pgn.Game,
                 colour: bool,
                 number_of_moves: int = 0) -> List[Tuple[int, int, int]]:
    """
    Steps through game and checks if a piece has been lost via piece_delta

    Can hanldle en passant :pog:
    """
    count = 0
    lost = []
    board = game.board()
    piece_count = {
        chess.PAWN: 8,
        chess.KNIGHT: 2,
        chess.BISHOP: 2,
        chess.ROOK: 2,
        chess.QUEEN: 1
    }
    for move in game.mainline_moves():
        if board.turn == colour:  # is our colour
            if board.is_capture(move):  # move is capture, including en passnat
                if not board.is_en_passant(
                        move):  # is it not en passant, the norm
                    board.push(move)
                    piece = piece_delta(board, count, piece_count, board.turn)
                else:  # needs seperate code path
                    piece = (1, uci_to_1d_array_index(move.uci()), count)
                    board.push(move)
                lost.append(piece)

            else:
                board.push(move)

        else:
            board.push(move)

        count += 1
        if (
                count >= number_of_moves
        ) and number_of_moves:  # Stop after moving n times and n is non-zero
            break
    return lost
예제 #7
0
 def get_moves(self, next_game: chess.pgn.Game):
     """
     get moves from one game and append to data_buffer
     param pgn.Game next_game: a game
     return int: number of moves in the game
     """
     data_len = 0  #moves processed
     result = self.get_result(next_game.headers["Result"])
     white_weight = self.elo_val(int(next_game.headers["WhiteElo"]))
     black_weight = self.elo_val(int(next_game.headers["BlackElo"]))
     board = chess.Board()
     while not next_game.is_end():
         next_game = next_game.variation(0)
         next_move = next_game.move.uci()
         if (data_len % 2 == 0):  #white move
             self.data_buffer.append(
                 self.solve_move(board, next_move, white_weight, result))
         else:  #black move
             self.data_buffer.append(
                 self.solve_move(board, next_move, black_weight, -result))
         board.push_uci(next_move)
         data_len += 1
     return data_len
예제 #8
0
 def display_moves(self, game: chess.pgn.Game):
     """
     動きからゲームをディスプレイ上で再現します
     :param game: pgn.game データ
     :return:
     """
     for move in game.mainline_moves():
         self.check_move(move)
         route = self.piece_move(move)
         print(str(route))
         self.board.push(move)
         self.check_state()
         print("---------------")
         print(self.board)
         print("---------------")
         print("\n")
def get_single_games_states(
    game: chess.pgn.Game, return_legal_moves: bool
) -> Union[Tuple[List[np.ndarray], LegalMovesT], List[np.ndarray]]:
    """Create new chess.Board instance and plays game till the end. Returns list of array of all
    states along the way.
    Can also return list of legal moves per state"""
    board = Board()
    game_states: List[np.ndarray] = []
    game_legal_moves: LegalMovesT = []
    white_turn = True  # Keep track of who's turn it is

    for move_i, move in enumerate(game.mainline_moves()):

        if return_legal_moves:
            board_to_save = board if white_turn else board.mirror()

            # Only add board position to data if it hasn't been observed
            add_if_known(board=board_to_save,
                         game_legal_moves=game_legal_moves,
                         game_states=game_states)

            # Next player's turn
            white_turn = not white_turn

        else:
            # Add board position to data irrespective of whether it's been observed
            add_board_state_to_list(board=board, in_list=game_states)

        board.push(move)

    if return_legal_moves:
        return game_states, game_legal_moves

    else:
        # Get last state
        # (As it's only relevant when not looking at legal moves as there are no more moves)
        add_board_state_to_list(board=board, in_list=game_states)

        return game_states
예제 #10
0
    def _build_game_header(self, pgn_game: chess.pgn.Game):
        # pgn_game.headers['Result'] = '*'
        pgn_game.headers['Event'] = 'PicoChess game'
        pgn_game.headers['Site'] = 'picochess.org'
        pgn_game.headers['Date'] = datetime.datetime.today().strftime('%Y.%m.%d')
        pgn_game.headers['Round'] = '?'
        pgn_game.headers['White'] = '?'
        pgn_game.headers['Black'] = '?'

        user_name = 'User'
        engine_name = 'Picochess'
        user_elo = '-'
        comp_elo = 2500
        if 'system_info' in self.shared:
            if 'user_name' in self.shared['system_info']:
                user_name = self.shared['system_info']['user_name']
            if 'engine_name' in self.shared['system_info']:
                engine_name = self.shared['system_info']['engine_name']
            if 'user_elo' in self.shared['system_info']:
                user_elo = self.shared['system_info']['user_elo']
            if 'engine_elo' in self.shared['system_info']:
                comp_elo = self.shared['system_info']['engine_elo']

        if 'game_info' in self.shared:
            if 'level_text' in self.shared['game_info']:
                engine_level = ' ({0})'.format(self.shared['game_info']['level_text'].m)
            else:
                engine_level = ''
            if 'level_name' in self.shared['game_info']:
                level_name = self.shared['game_info']['level_name']
                if level_name.startswith('Elo@'):
                    comp_elo = int(level_name[4:])
                    engine_level = ''
            if 'play_mode' in self.shared['game_info']:
                if self.shared['game_info']['play_mode'] == PlayMode.USER_WHITE:
                    pgn_game.headers['White'] = user_name
                    pgn_game.headers['Black'] = engine_name + engine_level
                    pgn_game.headers['WhiteElo'] = user_elo
                    pgn_game.headers['BlackElo'] = comp_elo
                else:
                    pgn_game.headers['White'] = engine_name + engine_level
                    pgn_game.headers['Black'] = user_name
                    pgn_game.headers['WhiteElo'] = comp_elo
                    pgn_game.headers['BlackElo'] = user_elo

        if 'ip_info' in self.shared:
            if 'location' in self.shared['ip_info']:
                pgn_game.headers['Site'] = self.shared['ip_info']['location']

        pgn_game.headers['Time'] = self.starttime
예제 #11
0
    def _build_game_header(self, pgn_game: chess.pgn.Game):
        # pgn_game.headers['Result'] = '*'
        pgn_game.headers['Event'] = 'PicoChess game'
        pgn_game.headers['Site'] = 'picochess.org'
        pgn_game.headers['Date'] = datetime.datetime.today().strftime('%Y.%m.%d')
        pgn_game.headers['Round'] = '?'
        pgn_game.headers['White'] = '?'
        pgn_game.headers['Black'] = '?'

        user_name = 'User'
        engine_name = 'Picochess'
        user_elo = '-'
        comp_elo = 2900
        if 'system_info' in self.shared:
            if 'user_name' in self.shared['system_info']:
                user_name = self.shared['system_info']['user_name']
            if 'engine_name' in self.shared['system_info']:
                engine_name = self.shared['system_info']['engine_name']
            if 'user_elo' in self.shared['system_info']:
                user_elo = self.shared['system_info']['user_elo']

        # @todo find a better way to setup engine elo
        engine_elo = {'stockfish': 3360, 'texel': 3050, 'rodent': 2920,
                      'zurichess': 2790, 'wyld': 2630, 'sayuri': 1850}
        for name, elo in engine_elo.items():
            if engine_name.lower().startswith(name):
                comp_elo = elo
                break

        if 'game_info' in self.shared:
            if 'level_text' in self.shared['game_info']:
                engine_level = ' ({0})'.format(self.shared['game_info']['level_text'].m)
            else:
                engine_level = ''
            if 'level_name' in self.shared['game_info']:
                level_name = self.shared['game_info']['level_name']
                if level_name.startswith('Elo@'):
                    comp_elo = int(level_name[4:])
                    engine_level = ''
            if 'play_mode' in self.shared['game_info']:
                if self.shared['game_info']['play_mode'] == PlayMode.USER_WHITE:
                    pgn_game.headers['White'] = user_name
                    pgn_game.headers['Black'] = engine_name + engine_level
                    pgn_game.headers['WhiteElo'] = user_elo
                    pgn_game.headers['BlackElo'] = comp_elo
                else:
                    pgn_game.headers['White'] = engine_name + engine_level
                    pgn_game.headers['Black'] = user_name
                    pgn_game.headers['WhiteElo'] = comp_elo
                    pgn_game.headers['BlackElo'] = user_elo

        if 'ip_info' in self.shared:
            if 'location' in self.shared['ip_info']:
                pgn_game.headers['Site'] = self.shared['ip_info']['location']
예제 #12
0
    def _build_game_header(self, pgn_game: chess.pgn.Game):
        # pgn_game.headers['Result'] = '*'
        pgn_game.headers['Event'] = 'PicoChess game'
        pgn_game.headers['Site'] = 'picochess.org'
        pgn_game.headers['Date'] = datetime.datetime.today().strftime(
            '%Y.%m.%d')
        pgn_game.headers['Round'] = '?'
        pgn_game.headers['White'] = '?'
        pgn_game.headers['Black'] = '?'

        user_name = 'User'
        engine_name = 'Picochess'
        user_elo = '-'
        comp_elo = 2500
        if 'system_info' in self.shared:
            if 'user_name' in self.shared['system_info']:
                user_name = self.shared['system_info']['user_name']
            if 'engine_name' in self.shared['system_info']:
                engine_name = self.shared['system_info']['engine_name']
            if 'user_elo' in self.shared['system_info']:
                user_elo = self.shared['system_info']['user_elo']
            if 'engine_elo' in self.shared['system_info']:
                comp_elo = self.shared['system_info']['engine_elo']

        if 'game_info' in self.shared:
            if 'level_text' in self.shared['game_info']:
                engine_level = ' ({0})'.format(
                    self.shared['game_info']['level_text'].m)
            else:
                engine_level = ''
            if 'level_name' in self.shared['game_info']:
                level_name = self.shared['game_info']['level_name']
                if level_name.startswith('Elo@'):
                    comp_elo = int(level_name[4:])
                    engine_level = ''
            if 'play_mode' in self.shared['game_info']:
                if self.shared['game_info'][
                        'play_mode'] == PlayMode.USER_WHITE:
                    pgn_game.headers['White'] = user_name
                    pgn_game.headers['Black'] = engine_name + engine_level
                    pgn_game.headers['WhiteElo'] = user_elo
                    pgn_game.headers['BlackElo'] = comp_elo
                else:
                    pgn_game.headers['White'] = engine_name + engine_level
                    pgn_game.headers['Black'] = user_name
                    pgn_game.headers['WhiteElo'] = comp_elo
                    pgn_game.headers['BlackElo'] = user_elo

        if 'ip_info' in self.shared:
            if 'location' in self.shared['ip_info']:
                pgn_game.headers['Site'] = self.shared['ip_info']['location']

        pgn_game.headers['Time'] = self.starttime
예제 #13
0
    def _build_game_header(self, pgn_game: chess.pgn.Game):
        # pgn_game.headers['Result'] = '*'
        pgn_game.headers['Event'] = 'PicoChess game'
        pgn_game.headers['Site'] = 'picochess.org'
        pgn_game.headers['Date'] = datetime.datetime.today().strftime(
            '%Y.%m.%d')
        pgn_game.headers['Round'] = '?'
        pgn_game.headers['White'] = '?'
        pgn_game.headers['Black'] = '?'

        user_name = 'User'
        engine_name = 'Picochess'
        user_elo = '-'
        comp_elo = 2900
        if 'system_info' in self.shared:
            if 'user_name' in self.shared['system_info']:
                user_name = self.shared['system_info']['user_name']
            if 'engine_name' in self.shared['system_info']:
                engine_name = self.shared['system_info']['engine_name']
            if 'user_elo' in self.shared['system_info']:
                user_elo = self.shared['system_info']['user_elo']

        # @todo find a better way to setup engine elo
        engine_elo = {
            'stockfish': 3360,
            'texel': 3050,
            'rodent': 2920,
            'zurichess': 2790,
            'wyld': 2630,
            'sayuri': 1850
        }
        for name, elo in engine_elo.items():
            if engine_name.lower().startswith(name):
                comp_elo = elo
                break

        if 'game_info' in self.shared:
            if 'level_text' in self.shared['game_info']:
                engine_level = ' ({0})'.format(
                    self.shared['game_info']['level_text'].m)
            else:
                engine_level = ''
            if 'level_name' in self.shared['game_info']:
                level_name = self.shared['game_info']['level_name']
                if level_name.startswith('Elo@'):
                    comp_elo = int(level_name[4:])
                    engine_level = ''
            if 'play_mode' in self.shared['game_info']:
                if self.shared['game_info'][
                        'play_mode'] == PlayMode.USER_WHITE:
                    pgn_game.headers['White'] = user_name
                    pgn_game.headers['Black'] = engine_name + engine_level
                    pgn_game.headers['WhiteElo'] = user_elo
                    pgn_game.headers['BlackElo'] = comp_elo
                else:
                    pgn_game.headers['White'] = engine_name + engine_level
                    pgn_game.headers['Black'] = user_name
                    pgn_game.headers['WhiteElo'] = comp_elo
                    pgn_game.headers['BlackElo'] = user_elo

        if 'ip_info' in self.shared:
            if 'location' in self.shared['ip_info']:
                pgn_game.headers['Site'] = self.shared['ip_info']['location']