Source code for chipiron.players.move_selector.treevalue.nodes.utils

"""
This module contains utility functions for working with tree nodes in the move selector.

Functions:
- are_all_moves_and_children_opened(tree_node: TreeNode) -> bool: Checks if all moves and children of a tree node are opened.
- a_move_sequence_from_root(tree_node: ITreeNode) -> list[str]: Returns a list of move sequences from the root node to a given tree node.
- print_a_move_sequence_from_root(tree_node: TreeNode) -> None: Prints the move sequence from the root node to a given tree node.
- is_winning(node_minmax_evaluation: NodeMinmaxEvaluation, color: chess.Color) -> bool: Checks if the color to play in the node is winning.
"""

from typing import Any

import chess

from chipiron.environments.chess_env.move import moveUci
from chipiron.environments.chess_env.move.imove import moveKey
from chipiron.players.move_selector.treevalue.nodes.algorithm_node.algorithm_node import (
    AlgorithmNode,
)
from chipiron.players.move_selector.treevalue.nodes.algorithm_node.node_minmax_evaluation import (
    NodeMinmaxEvaluation,
)

from .itree_node import ITreeNode
from .tree_node import TreeNode


[docs]def are_all_moves_and_children_opened(tree_node: TreeNode[Any]) -> bool: """ Checks if all moves and children of a tree node are opened. Args: tree_node (TreeNode): The tree node to check. Returns: bool: True if all moves and children are opened, False otherwise. """ return ( tree_node.all_legal_moves_generated and tree_node.non_opened_legal_moves == set() )
[docs]def a_move_key_sequence_from_root(tree_node: ITreeNode[Any]) -> list[str]: """ Returns a list of move sequences from the root node to a given tree node. Args: tree_node (ITreeNode): The tree node to get the move sequence for. Returns: list[str]: A list of move sequences from the root node to the given tree node. """ move_sequence_from_root: list[moveKey] = [] child: ITreeNode[Any] = tree_node while child.parent_nodes: parent: ITreeNode[Any] = next(iter(child.parent_nodes)) move: moveKey = child.parent_nodes[parent] move_sequence_from_root.append(move) child = parent move_sequence_from_root.reverse() return [str(i) for i in move_sequence_from_root]
[docs]def a_move_uci_sequence_from_root(tree_node: ITreeNode[Any]) -> list[str]: """ Returns a list of move sequences from the root node to a given tree node. Args: tree_node (ITreeNode): The tree node to get the move sequence for. Returns: list[str]: A list of move sequences from the root node to the given tree node. """ move_sequence_from_root: list[moveUci] = [] child: ITreeNode[Any] = tree_node while child.parent_nodes: parent: ITreeNode[Any] = next(iter(child.parent_nodes)) move: moveKey = child.parent_nodes[parent] move_uci: moveUci = parent.board.get_uci_from_move_key(move) move_sequence_from_root.append(move_uci) child = parent move_sequence_from_root.reverse() return [str(i) for i in move_sequence_from_root]
[docs]def best_node_sequence_from_node( tree_node: AlgorithmNode, ) -> list[ITreeNode[Any]]: """ """ best_move_seq: list[moveKey] = tree_node.minmax_evaluation.best_move_sequence index = 0 move_sequence: list[ITreeNode[Any]] = [tree_node] child: ITreeNode[Any] = tree_node while child.moves_children: move: moveKey = best_move_seq[index] child_ = child.moves_children[move] assert child_ is not None child = child_ move_sequence.append(child) index = index + 1 return move_sequence
[docs]def is_winning( node_minmax_evaluation: NodeMinmaxEvaluation, color: chess.Color ) -> bool: """ Checks if the color to play in the node is winning. Args: node_minmax_evaluation (NodeMinmaxEvaluation): The evaluation of the node. color (chess.Color): The color to check. Returns: bool: True if the color is winning, False otherwise. """ assert node_minmax_evaluation.value_white_minmax is not None winning_if_color_white: bool = ( node_minmax_evaluation.value_white_minmax > 0.98 and color ) winning_if_color_black: bool = ( node_minmax_evaluation.value_white_minmax < -0.98 and not color ) return winning_if_color_white or winning_if_color_black