Source code for lczerolens.concepts.material

"""All concepts related to material."""

from typing import Dict, Optional

import chess

from lczerolens.board import LczeroBoard
from lczerolens.concept import BinaryConcept


[docs] class HasPiece(BinaryConcept): """Class for material concept-based XAI methods.""" def __init__( self, piece: str, relative: bool = True, ): """Initialize the class."""
[docs] self.piece = chess.Piece.from_symbol(piece)
[docs] self.relative = relative
[docs] def compute_label( self, board: LczeroBoard, ) -> int: """Compute the label for a given model and input.""" if self.relative: color = self.piece.color if board.turn else not self.piece.color else: color = self.piece.color squares = board.pieces(self.piece.piece_type, color) return 1 if len(squares) > 0 else 0
[docs] class HasMaterialAdvantage(BinaryConcept): """Class for material concept-based XAI methods. Attributes ---------- piece_values : Dict[int, int] The piece values. """
[docs] piece_values = { chess.PAWN: 1, chess.KNIGHT: 3, chess.BISHOP: 3, chess.ROOK: 5, chess.QUEEN: 9, chess.KING: 0, }
def __init__( self, relative: bool = True, ): """ Initialize the class. """
[docs] self.relative = relative
[docs] def compute_label( self, board: LczeroBoard, piece_values: Optional[Dict[int, int]] = None, ) -> int: """ Compute the label for a given model and input. """ if piece_values is None: piece_values = self.piece_values if self.relative: us, them = board.turn, not board.turn else: us, them = chess.WHITE, chess.BLACK our_value = 0 their_value = 0 for piece in range(1, 7): our_value += len(board.pieces(piece, us)) * piece_values[piece] their_value += len(board.pieces(piece, them)) * piece_values[piece] return 1 if our_value > their_value else 0