Exemplo n.º 1
0
def get_planes_from_game(game, mate_in_one=False):
    """
    Returns all plane descriptions of a given game and their corresponding target values:
    - the game outcome (-1, 0, 1)
    - the next move which will be played in each position

    :param game: Game handle which is a python-chess object
    (e.g. mv_hist_len = 8 means that the current position and the 7 previous positions are exported)
    :param mate_in_one: Decide weather only to export the position before the last mate-in-one move
                        (this option is for evaluation and DEBUG purposes)
    :return: x - the position description of all moves in the game
             y_value - the target values of the scene description. Here the game outcome.
                  returns -1 if the current player lost, +1 if the current player won, 0 for draw
             y_policy - the policy vector one-hot encoded indicating the next move the player current player chose
              in this position
    """

    fen_dic = {
    }  # A dictionary which maps the fen description to its number of occurrences
    x = []
    y_value = []
    y_policy = []
    board = game.board()  # get the initial board state
    # update the y value accordingly
    if board.turn == chess.WHITE:
        y_init = 1
    else:
        y_init = -1
    if game.headers["Result"] == "0-1":
        y_init *= -1
    elif game.headers["Result"] == "1/2-1/2":
        y_init = 0

    all_moves = []  # Extract all moves first and save them into a list
    for move in game.main_line():
        all_moves.append(move)
    # Iterate through all moves (except the last one) and play them on a board.
    # you don't want to push the last move on the board because you had no movement policy to learn from in this case
    # The moves get pushed at the end of the for-loop and is only used in the next loop.
    # Therefore we can iterate over 'all' moves
    for i, move in enumerate(all_moves):
        board_occ = 0  # by default the positions hasn't occurred before
        fen = board.fen()
        # remove the halfmove counter & move counter from this fen to make repetitions possible
        fen = fen[:fen.find(" ") + 2]
        # save the board state to the fen dictionary
        if fen in list(fen_dic.keys()):
            fen_dic[fen] += 1
            board_occ = fen_dic[fen]
        else:
            fen_dic[fen] = 1  # create a new entry
        # we insert the move i (and not i+1), because the start is the empty board position
        next_move = all_moves[i]

        # check if you need to export a mate_in_one_scenario
        if not mate_in_one or i == len(all_moves) - 1:
            # receive the board and the evaluation of the current position in plane representation
            # We don't want to store float values because the integer datatype is cheaper,
            #  that's why normalize is set to false
            x_cur = board_to_planes(board, board_occ, normalize=False)
            # add the evaluation of 1 position to the list
            x.append(x_cur)
            y_value.append(y_init)
            # add the next move defined in policy vector notation to the policy list
            # the network always sees the board as if he's the white player, that's the move is mirrored fro black
            y_policy.append(
                move_to_policy(next_move, is_white_to_move=board.turn))

        y_init *= -1  # flip the y_init value after each move
        board.push(move)  # push the next move on the board

    # check if there has been any moves
    if x and y_value and y_policy:
        x = np.stack(x, axis=0)
        y_value = np.stack(y_value, axis=0)
        y_policy = np.stack(y_policy, axis=0)
    else:
        print("game.headers:")
        print(game.headers)
        raise Exception("The given pgn file's mainline is empty!")

    return x, y_value, y_policy
Exemplo n.º 2
0
 def get_state_planes(self):
     return board_to_planes(self.board,
                            board_occ=self._board_occ,
                            normalize=True)
Exemplo n.º 3
0
 def get_state_planes(self):
     """Transform the current board state to a plane"""
     return board_to_planes(self.board,
                            board_occ=self._board_occ,
                            normalize=True)