<commit_before>"""
csa : Chess Surprise analysis
author : <NAME>
e-mail : <EMAIL>
github : https://github.com/CYHSM/chess-surprise-analysis
"""
import chess.pgn
import chess.uci
import numpy as np
import pandas as pd
import pickle
import os


###############################################################################
#####################LOAD GAME AND BOARD#######################################
###############################################################################
def load_engine():
    """Load engine for analysing games"""
    # Use the open-soure engine Stockfish
    engine = chess.uci.popen_engine('stockfish')
    # Important to use UCI (Universal Chess Interface)
    engine.uci()
    # Use an InfoHandler to save information about the analysis
    info_handler = chess.uci.InfoHandler()
    engine.info_handlers.append(info_handler)

    return engine


def reset_present_engine(engine):
    """Reset the engine to avoid usage of hashtables in evaluation.

    Problem: After first analysis a lot of possible moves are stored in
        the hashtable so a re-run on low depths will lead to evaluations
        based on higher depths

    """
    engine.quit()
    engine = load_engine()
    return engine


def load_game_from_pgn(path_to_pgn):
    """Read a chess game from PGN"""
    # Open PGN
    pgn_file = open(path_to_pgn)
    # Read game information
    chess_game = chess.pgn.read_game(pgn_file)
    # Close
    pgn_file.close()

    return chess_game


def get_board_at_position(chess_game, halfmove_number):
    """
    Given a chess game, returns the board at given halfmove_number
    """
    halfmove_counter = 1
    while not chess_game.is_end() and halfmove_counter - 1 < halfmove_number:
        board = chess_game.board()
        next_node = chess_game.variation(0)
        chess_game = next_node
        halfmove_counter += 1<commit_msg>Use with statement to ensure file always gets closed<commit_after>"""
csa : Chess Surprise analysis
author : <NAME>
e-mail : <EMAIL>
github : https://github.com/CYHSM/chess-surprise-analysis
"""
import chess.pgn
import chess.uci
import numpy as np
import pandas as pd
import pickle
import os


###############################################################################
#####################LOAD GAME AND BOARD#######################################
###############################################################################
def load_engine():
    """Load engine for analysing games"""
    # Use the open-soure engine Stockfish
    engine = chess.uci.popen_engine('stockfish')
    # Important to use UCI (Universal Chess Interface)
    engine.uci()
    # Use an InfoHandler to save information about the analysis
    info_handler = chess.uci.InfoHandler()
    engine.info_handlers.append(info_handler)

    return engine


def reset_present_engine(engine):
    """Reset the engine to avoid usage of hashtables in evaluation.

    Problem: After first analysis a lot of possible moves are stored in
        the hashtable so a re-run on low depths will lead to evaluations
        based on higher depths

    """
    engine.quit()
    engine = load_engine()
    return engine


def load_game_from_pgn(path_to_pgn):
    """Read a chess game from PGN"""
    # Open and close PGN file
    with open(path_to_pgn) as pgn_file:
        # Read game information
        chess_game = chess.pgn.read_game(pgn_file)

    return chess_game


def get_board_at_position(chess_game, halfmove_number):
    """
    Given a chess game, returns the board at given halfmove_number
    """
    halfmove_counter = 1
    while not chess_game.is_end() and halfmove_counter - 1 < halfmove_number:
        board = chess_game.board()
        next_node = chess_game.variation(0)
        chess_game = next_node
        halfmove_counter += 1
{'fraction_non_alphanumeric': 0.1831578947368421, 'fraction_numerical': 0.002105263157894737, 'mean_word_length': 3.817490494296578, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '554815', 'n_tokens_mistral': 1125, 'n_tokens_neox': 1048, 'n_words': 336}