ai/heuristics/base.js

/**
 * @fileoverview Abstrakte Basisklasse für Heuristiken.
 * Definiert die gemeinsame Schnittstelle für alle Heuristik-Evaluatoren.
 * @author Alexander Wolf
 */

/**
 * Abstrakte Basisklasse für Heuristik-Evaluatoren.
 * @abstract
 */
class BaseHeuristic {
    /**
     * @param {Object} config
     * @param {string} config.game
     * @param {string} config.variant
     * @param {string} [config.name]
     * @param {Object} [config.weights]
     */
    constructor(config) {
        if (new.target === BaseHeuristic) {
            throw new Error('BaseHeuristic ist abstrakt und darf nicht direkt instanziiert werden.');
        }

        this.game = config.game;
        this.variant = config.variant;
        this.name = config.name || `${config.game}-${config.variant}`;
        this.weights = { ...this.getDefaultWeights(), ...(config.weights || {}) };
        this.id = `${this.game}:${this.variant}`;

        if (typeof DebugConfig !== 'undefined' && typeof DEBUG_DOMAINS !== 'undefined') {
            DebugConfig.log(DEBUG_DOMAINS.AI_HEURISTICS, 'debug', 'Heuristic created', {
                id: this.id,
                name: this.name
            });
        }
    }

    /**
     * @param {GameState} gameState
     * @param {number} player
     * @returns {number}
     */
    evaluate(gameState, player) {
        throw new Error(`evaluate() muss in ${this.constructor.name} implementiert werden.`);
    }

    /**
     * @returns {Object}
     */
    getDefaultWeights() {
        return {
            win: 1000,
            loss: -1000,
            draw: 0
        };
    }

    /**
     * @returns {Object}
     */
    toConfig() {
        return {
            game: this.game,
            variant: this.variant,
            name: this.name,
            weights: { ...this.weights }
        };
    }

    /**
     * @param {Object} newWeights
     */
    updateWeights(newWeights) {
        this.weights = { ...this.weights, ...newWeights };
        if (typeof DebugConfig !== 'undefined' && typeof DEBUG_DOMAINS !== 'undefined') {
            DebugConfig.log(DEBUG_DOMAINS.AI_HEURISTICS, 'debug', 'Heuristic weights updated', {
                id: this.id,
                weights: this.weights
            });
        }
    }

    /**
     * @param {GameState} gameState
     * @param {number} player
     * @returns {number|null}
     */
    checkTerminal(gameState, player) {
        if (gameState.winner === player) return this.weights.win;
        if (gameState.winner !== NONE && gameState.winner !== DRAW) return this.weights.loss;
        if (gameState.winner === DRAW) return this.weights.draw;
        return null;
    }
}