Skip to content

engine

chessapp.controller.engine.MoveDescriptor

a descriptor for a move, containing the evaluation, depth, whether it is a mate, the pv (array of chess.Move) and the fen of the board before the move was made

Source code in chessapp\controller\engine.py
class MoveDescriptor:
    """a descriptor for a move, containing the evaluation, depth, whether it is a mate, the pv (array of chess.Move) and the fen of the board before the move was made
    """

    def __init__(self, eval: float, depth: int, is_mate: bool, pv, origin_fen: str):
        """_summary_

        Args:
            eval (float): evaluation of the move (which is the resulting positon after the move was made) in centipawns/100 or as 100 if mate
            depth (int): depth of the evaluation
            is_mate (bool): whether the move is a mate
            pv ([chess.Move]): array of chess.Move in the principal variation (pv)
            origin_fen (str): the fen of the board before the move was made
        """
        self.eval: float = eval
        self.depth: int = depth
        self.is_mate: bool = is_mate
        self.pv = pv
        self.origin_fen: str = origin_fen

__init__(eval, depth, is_mate, pv, origin_fen)

summary

Parameters:

Name Type Description Default
eval float

evaluation of the move (which is the resulting positon after the move was made) in centipawns/100 or as 100 if mate

required
depth int

depth of the evaluation

required
is_mate bool

whether the move is a mate

required
pv [Move]

array of chess.Move in the principal variation (pv)

required
origin_fen str

the fen of the board before the move was made

required
Source code in chessapp\controller\engine.py
def __init__(self, eval: float, depth: int, is_mate: bool, pv, origin_fen: str):
    """_summary_

    Args:
        eval (float): evaluation of the move (which is the resulting positon after the move was made) in centipawns/100 or as 100 if mate
        depth (int): depth of the evaluation
        is_mate (bool): whether the move is a mate
        pv ([chess.Move]): array of chess.Move in the principal variation (pv)
        origin_fen (str): the fen of the board before the move was made
    """
    self.eval: float = eval
    self.depth: int = depth
    self.is_mate: bool = is_mate
    self.pv = pv
    self.origin_fen: str = origin_fen

chessapp.controller.engine.Engine

a wrapper for the stockfish engine

Source code in chessapp\controller\engine.py
class Engine:
    """a wrapper for the stockfish engine
    """

    def __init__(self) -> None:
        """ initializes the engine (e.g. opens stockfish)
        """
        self.engine = SimpleEngine.popen_uci(get_stockfish_exe())

    def find_best_moves(self, board: Board, time: int = s_analyse_desired_time_seconds, depth: int = s_analyse_desired_depth, multipv: int = s_multi_pv) -> [MoveDescriptor]:
        """finds the best moves for the given board

        Args:
            board (Board): the board to find the best moves for
            time (int, optional): Defaults to s_analyse_desired_time_seconds. the time in seconds the engine is given to analyse the position.
            depth (int, optional): Defaults to s_analyse_desired_depth. the depth the engine is given to analyse the position.
            multipv (int, optional): Defaults to s_multi_pv. the number of principal variations to return (e.g. the number of best moves + their specific variations)

        Returns:
            [MoveDescriptor]: array of MoveDescriptor for the best moves
        """
        result = self.engine.analyse(board, Limit(
            time=time, depth=depth), options={"Threads": s_engine_number_of_threads}, multipv=multipv)
        best_moves = []
        for i in range(0, len(result)):
            eval = 0
            pov_score = result[i]["score"]
            if pov_score.is_mate():
                eval = float(100)
                if not pov_score.turn:
                    eval = -eval
            else:
                eval = pov_score.white().score() / 100.0
            best_moves.append(MoveDescriptor(
                eval, result[i]["depth"], pov_score.is_mate(), result[i]["pv"], get_reduced_fen_from_board(board)))
        return best_moves

    def score(self, board: Board, time: int = s_analyse_desired_time_seconds, depth: int = s_analyse_desired_depth):
        """scores the given board. @see https://stackoverflow.com/questions/58556338/python-evaluating-a-board-position-using-stockfish-from-the-python-chess-librar

        Args:
            board (Board): the board to score
            time (int, optional): Defaults to s_analyse_desired_time_seconds. the time in seconds the engine is given to analyse the position.
            depth (int, optional): Defaults to s_analyse_desired_depth. the depth the engine is given to analyse the position.

        Returns:
            tuple: (eval, depth, is_mate) where eval is the evaluation of the board in centipawns/100 or as 100 if mate, depth is the depth of the evaluation and is_mate is whether the board is a mate
        """
        result = self.engine.analyse(board, Limit(
            time=time, depth=depth), options={"Threads": s_engine_number_of_threads}, multipv=s_multi_pv)
        best_eval = 0
        is_mate = False
        for i in range(0, len(result)):
            eval = 0
            pov_score = result[i]["score"]
            if pov_score.is_mate():
                is_mate = True
                eval = float(100)
                if not pov_score.turn:
                    eval = -eval
            else:
                eval = pov_score.white().score() / 100.0
            # best move is first entry in result array
            if i == 0:
                best_eval = eval
        return best_eval, result[0]["depth"], is_mate

    def close(self):
        """closes the engine (closes stockfish)
        """
        self.engine.close()

__init__()

initializes the engine (e.g. opens stockfish)

Source code in chessapp\controller\engine.py
def __init__(self) -> None:
    """ initializes the engine (e.g. opens stockfish)
    """
    self.engine = SimpleEngine.popen_uci(get_stockfish_exe())

close()

closes the engine (closes stockfish)

Source code in chessapp\controller\engine.py
def close(self):
    """closes the engine (closes stockfish)
    """
    self.engine.close()

find_best_moves(board, time=s_analyse_desired_time_seconds, depth=s_analyse_desired_depth, multipv=s_multi_pv)

finds the best moves for the given board

Parameters:

Name Type Description Default
board Board

the board to find the best moves for

required
time int

Defaults to s_analyse_desired_time_seconds. the time in seconds the engine is given to analyse the position.

s_analyse_desired_time_seconds
depth int

Defaults to s_analyse_desired_depth. the depth the engine is given to analyse the position.

s_analyse_desired_depth
multipv int

Defaults to s_multi_pv. the number of principal variations to return (e.g. the number of best moves + their specific variations)

s_multi_pv

Returns:

Type Description
[MoveDescriptor]

[MoveDescriptor]: array of MoveDescriptor for the best moves

Source code in chessapp\controller\engine.py
def find_best_moves(self, board: Board, time: int = s_analyse_desired_time_seconds, depth: int = s_analyse_desired_depth, multipv: int = s_multi_pv) -> [MoveDescriptor]:
    """finds the best moves for the given board

    Args:
        board (Board): the board to find the best moves for
        time (int, optional): Defaults to s_analyse_desired_time_seconds. the time in seconds the engine is given to analyse the position.
        depth (int, optional): Defaults to s_analyse_desired_depth. the depth the engine is given to analyse the position.
        multipv (int, optional): Defaults to s_multi_pv. the number of principal variations to return (e.g. the number of best moves + their specific variations)

    Returns:
        [MoveDescriptor]: array of MoveDescriptor for the best moves
    """
    result = self.engine.analyse(board, Limit(
        time=time, depth=depth), options={"Threads": s_engine_number_of_threads}, multipv=multipv)
    best_moves = []
    for i in range(0, len(result)):
        eval = 0
        pov_score = result[i]["score"]
        if pov_score.is_mate():
            eval = float(100)
            if not pov_score.turn:
                eval = -eval
        else:
            eval = pov_score.white().score() / 100.0
        best_moves.append(MoveDescriptor(
            eval, result[i]["depth"], pov_score.is_mate(), result[i]["pv"], get_reduced_fen_from_board(board)))
    return best_moves

score(board, time=s_analyse_desired_time_seconds, depth=s_analyse_desired_depth)

scores the given board. @see https://stackoverflow.com/questions/58556338/python-evaluating-a-board-position-using-stockfish-from-the-python-chess-librar

Parameters:

Name Type Description Default
board Board

the board to score

required
time int

Defaults to s_analyse_desired_time_seconds. the time in seconds the engine is given to analyse the position.

s_analyse_desired_time_seconds
depth int

Defaults to s_analyse_desired_depth. the depth the engine is given to analyse the position.

s_analyse_desired_depth

Returns:

Name Type Description
tuple

(eval, depth, is_mate) where eval is the evaluation of the board in centipawns/100 or as 100 if mate, depth is the depth of the evaluation and is_mate is whether the board is a mate

Source code in chessapp\controller\engine.py
def score(self, board: Board, time: int = s_analyse_desired_time_seconds, depth: int = s_analyse_desired_depth):
    """scores the given board. @see https://stackoverflow.com/questions/58556338/python-evaluating-a-board-position-using-stockfish-from-the-python-chess-librar

    Args:
        board (Board): the board to score
        time (int, optional): Defaults to s_analyse_desired_time_seconds. the time in seconds the engine is given to analyse the position.
        depth (int, optional): Defaults to s_analyse_desired_depth. the depth the engine is given to analyse the position.

    Returns:
        tuple: (eval, depth, is_mate) where eval is the evaluation of the board in centipawns/100 or as 100 if mate, depth is the depth of the evaluation and is_mate is whether the board is a mate
    """
    result = self.engine.analyse(board, Limit(
        time=time, depth=depth), options={"Threads": s_engine_number_of_threads}, multipv=s_multi_pv)
    best_eval = 0
    is_mate = False
    for i in range(0, len(result)):
        eval = 0
        pov_score = result[i]["score"]
        if pov_score.is_mate():
            is_mate = True
            eval = float(100)
            if not pov_score.turn:
                eval = -eval
        else:
            eval = pov_score.white().score() / 100.0
        # best move is first entry in result array
        if i == 0:
            best_eval = eval
    return best_eval, result[0]["depth"], is_mate

Source

from chess import Board
from chess.engine import Limit, SimpleEngine
from chessapp.model.chesstree import get_reduced_fen_from_board
from chessapp.util.paths import get_stockfish_exe

s_analyse_desired_time_seconds: int = 30
s_analyse_desired_depth: int = 30
s_engine_number_of_threads: int = 14
s_multi_pv: int = 1


class MoveDescriptor:
    """a descriptor for a move, containing the evaluation, depth, whether it is a mate, the pv (array of chess.Move) and the fen of the board before the move was made
    """

    def __init__(self, eval: float, depth: int, is_mate: bool, pv, origin_fen: str):
        """_summary_

        Args:
            eval (float): evaluation of the move (which is the resulting positon after the move was made) in centipawns/100 or as 100 if mate
            depth (int): depth of the evaluation
            is_mate (bool): whether the move is a mate
            pv ([chess.Move]): array of chess.Move in the principal variation (pv)
            origin_fen (str): the fen of the board before the move was made
        """
        self.eval: float = eval
        self.depth: int = depth
        self.is_mate: bool = is_mate
        self.pv = pv
        self.origin_fen: str = origin_fen


class Engine:
    """a wrapper for the stockfish engine
    """

    def __init__(self) -> None:
        """ initializes the engine (e.g. opens stockfish)
        """
        self.engine = SimpleEngine.popen_uci(get_stockfish_exe())

    def find_best_moves(self, board: Board, time: int = s_analyse_desired_time_seconds, depth: int = s_analyse_desired_depth, multipv: int = s_multi_pv) -> [MoveDescriptor]:
        """finds the best moves for the given board

        Args:
            board (Board): the board to find the best moves for
            time (int, optional): Defaults to s_analyse_desired_time_seconds. the time in seconds the engine is given to analyse the position.
            depth (int, optional): Defaults to s_analyse_desired_depth. the depth the engine is given to analyse the position.
            multipv (int, optional): Defaults to s_multi_pv. the number of principal variations to return (e.g. the number of best moves + their specific variations)

        Returns:
            [MoveDescriptor]: array of MoveDescriptor for the best moves
        """
        result = self.engine.analyse(board, Limit(
            time=time, depth=depth), options={"Threads": s_engine_number_of_threads}, multipv=multipv)
        best_moves = []
        for i in range(0, len(result)):
            eval = 0
            pov_score = result[i]["score"]
            if pov_score.is_mate():
                eval = float(100)
                if not pov_score.turn:
                    eval = -eval
            else:
                eval = pov_score.white().score() / 100.0
            best_moves.append(MoveDescriptor(
                eval, result[i]["depth"], pov_score.is_mate(), result[i]["pv"], get_reduced_fen_from_board(board)))
        return best_moves

    def score(self, board: Board, time: int = s_analyse_desired_time_seconds, depth: int = s_analyse_desired_depth):
        """scores the given board. @see https://stackoverflow.com/questions/58556338/python-evaluating-a-board-position-using-stockfish-from-the-python-chess-librar

        Args:
            board (Board): the board to score
            time (int, optional): Defaults to s_analyse_desired_time_seconds. the time in seconds the engine is given to analyse the position.
            depth (int, optional): Defaults to s_analyse_desired_depth. the depth the engine is given to analyse the position.

        Returns:
            tuple: (eval, depth, is_mate) where eval is the evaluation of the board in centipawns/100 or as 100 if mate, depth is the depth of the evaluation and is_mate is whether the board is a mate
        """
        result = self.engine.analyse(board, Limit(
            time=time, depth=depth), options={"Threads": s_engine_number_of_threads}, multipv=s_multi_pv)
        best_eval = 0
        is_mate = False
        for i in range(0, len(result)):
            eval = 0
            pov_score = result[i]["score"]
            if pov_score.is_mate():
                is_mate = True
                eval = float(100)
                if not pov_score.turn:
                    eval = -eval
            else:
                eval = pov_score.white().score() / 100.0
            # best move is first entry in result array
            if i == 0:
                best_eval = eval
        return best_eval, result[0]["depth"], is_mate

    def close(self):
        """closes the engine (closes stockfish)
        """
        self.engine.close()