ai/heuristics/config/ttt-heuristics-config.js

/**
 * @fileoverview Bewertungskonfigurationen für TTT-Heuristiken (regular, 3d, ultimate).
 * Definiert je 7 Profile pro Variante:
 *   - v1_baseline: Sieg/Verlust-Erkennung, minimale Linienbewertung
 *   - v2_positional: Positionelle Kontrolle (Zentrum, Ecken, strategische Felder)
 *   - v3_aggressive: Gabel-Erkennung, Druckmaximierung, Mobilitätseinschränkung
 *   - v4_defensive: Asymmetrisches loss/win, Block-Fokus, Remis akzeptiert
 *   - v5_offensive: Schnellsieg, hoher Fork-Bonus, Druckmaximierung
 *   - v6_local: Unmittelbare Linienbildung, keine Positionsgewichte
 *   - v7_global: Feldqualität dominiert, Raumkontrolle
 *
 * Alle Werte sind Schema-validiert via heuristic-config-schema.js.
 * @author Alexander Wolf
 */

/**
 * Validiert Config falls Schema-Validator verfügbar ist (Load-Order-sicher).
 * @param {Object} config - Rohkonfiguration.
 * @returns {Object} Validierte oder unveränderte Konfiguration.
 */
function _tttValidateConfig(config) {
    if (typeof validateHeuristicConfig === 'function') {
        try {
            return validateHeuristicConfig(config);
        } catch (e) {
            if (typeof DebugConfig !== 'undefined' && typeof DEBUG_DOMAINS !== 'undefined') {
                DebugConfig.log(DEBUG_DOMAINS.AI_HEURISTICS, 'warn',
                    `TTT-Config Validierung fehlgeschlagen für ${config.profile}: ${e.message}. Nutze unvalidierte Config.`);
            }
        }
    }
    return config;
}

// ═══════════════════════════════════════════════════════════════
//  TTT REGULAR — 3×3 Klassik
// ═══════════════════════════════════════════════════════════════

const TTT_REGULAR_PROFILES = {
    v1_baseline: _tttValidateConfig({
        game: 'ttt', variant: 'regular', profile: 'v1_baseline',
        name: 'TTT Regular (Baseline)',
        description: 'Minimax-Grundlage: Nur Sieg/Verlust und einfache Linien-Zählung.',
        weights: {
            win: 1000, loss: -1000, draw: 0,
            twoInLine: 10, oneInLine: 1
        }
    }),
    v2_positional: _tttValidateConfig({
        game: 'ttt', variant: 'regular', profile: 'v2_positional',
        name: 'TTT Regular (Positional)',
        description: 'Bewertet Feldqualität: Zentrum (+15), Ecken (+3), Kanten (+1).',
        weights: {
            win: 1000, loss: -1000, draw: 0,
            twoInLine: 10, oneInLine: 1,
            centerBonus: 15, cornerBonus: 3, edgeBonus: 1
        }
    }),
    v3_aggressive: _tttValidateConfig({
        game: 'ttt', variant: 'regular', profile: 'v3_aggressive',
        name: 'TTT Regular (Aggressive)',
        description: 'Erzwingt Gabeln (fork +50) und bestraft gegnerische Mobilität.',
        weights: {
            win: 1000, loss: -1000, draw: 0,
            twoInLine: 15, oneInLine: 2,
            centerBonus: 10, forkBonus: 50, opponentForkPenalty: -50,
            pressureWeight: 15
        }
    }),

    // ═══ OPTIMIERTE STRATEGISCHE PROFILE ═══

    v4_defensive: _tttValidateConfig({
        game: 'ttt', variant: 'regular', profile: 'v4_defensive',
        name: 'TTT Regular (Defensiv)',
        description: 'Maximale Verlust-Vermeidung: loss=-1500 (asym.), Gegner-Fork=-80, Remis=+100.',
        weights: {
            win: 1000, loss: -1500, draw: 100,
            twoInLine: 8, oneInLine: 1,
            centerBonus: 5, cornerBonus: 3, edgeBonus: 2,
            forkBonus: 5, opponentForkPenalty: -80, blockUrgency: 30
        }
    }),
    v5_offensive: _tttValidateConfig({
        game: 'ttt', variant: 'regular', profile: 'v5_offensive',
        name: 'TTT Regular (Offensiv)',
        description: 'Schnellsieg: loss=-800 (Risiko), draw=-50, Fork=+40, Druck=20.',
        weights: {
            win: 1000, loss: -800, draw: -50,
            twoInLine: 25, oneInLine: 3,
            centerBonus: 5,
            forkBonus: 40, opponentForkPenalty: -15, pressureWeight: 20
        }
    }),
    v6_local: _tttValidateConfig({
        game: 'ttt', variant: 'regular', profile: 'v6_local',
        name: 'TTT Regular (Lokal)',
        description: 'Unmittelbare Linienbildung: twoInLine=20, oneInLine=5, keine Positionsgewichte.',
        weights: {
            win: 1000, loss: -1000, draw: 0,
            twoInLine: 20, oneInLine: 5,
            forkBonus: 15, opponentForkPenalty: -30, pressureWeight: 10
        }
    }),
    v7_global: _tttValidateConfig({
        game: 'ttt', variant: 'regular', profile: 'v7_global',
        name: 'TTT Regular (Global)',
        description: 'Feldqualität dominiert: Zentrum=20, Ecken=10, Kanten=5, minimale Linienwerte.',
        weights: {
            win: 1000, loss: -1000, draw: 0,
            twoInLine: 5, oneInLine: 1,
            centerBonus: 20, cornerBonus: 10, edgeBonus: 5,
            forkBonus: 10, opponentForkPenalty: -30
        }
    })
};

// ═══════════════════════════════════════════════════════════════
//  TTT 3D — 3×3×3 Raum
// ═══════════════════════════════════════════════════════════════

const TTT_3D_PROFILES = {
    v1_baseline: _tttValidateConfig({
        game: 'ttt', variant: '3d', profile: 'v1_baseline',
        name: 'TTT 3D (Baseline)',
        description: 'Raumlinien + einfacher Zentrumsbonus.',
        weights: {
            win: 10000, loss: -10000, draw: 0,
            twoInLine: 10, oneInLine: 1, centerBonus: 20
        }
    }),
    v2_positional: _tttValidateConfig({
        game: 'ttt', variant: '3d', profile: 'v2_positional',
        name: 'TTT 3D (Positional)',
        description: 'Starke Zentrums- und Raumkontrolle. Ecken und Kernexpansion.',
        weights: {
            win: 10000, loss: -10000, draw: 0,
            twoInLine: 12, oneInLine: 2,
            centerBonus: 40, spatialControl: 5, cornerBonus: 8
        }
    }),
    v3_aggressive: _tttValidateConfig({
        game: 'ttt', variant: '3d', profile: 'v3_aggressive',
        name: 'TTT 3D (Aggressive)',
        description: 'Maximierung von Multi-Linien-Druck und Raumdiagonalen-Kontrolle.',
        weights: {
            win: 10000, loss: -10000, draw: 0,
            twoInLine: 20, oneInLine: 3,
            centerBonus: 30, forkBonus: 80, opponentForkPenalty: -70,
            pressureWeight: 25, threatMultiplier: 5
        }
    }),

    // ═══ OPTIMIERTE STRATEGISCHE PROFILE (3D) ═══

    v4_defensive: _tttValidateConfig({
        game: 'ttt', variant: '3d', profile: 'v4_defensive',
        name: 'TTT 3D (Defensiv)',
        description: 'Raumdefensive: loss=-15000 (1.5×win), starke Gegner-Fork-Bestrafung, Remis akzeptabel.',
        weights: {
            win: 10000, loss: -15000, draw: 500,
            twoInLine: 15, oneInLine: 2,
            centerBonus: 25, spatialControl: 3, cornerBonus: 6,
            forkBonus: 20, opponentForkPenalty: -120, blockUrgency: 80
        }
    }),
    v5_offensive: _tttValidateConfig({
        game: 'ttt', variant: '3d', profile: 'v5_offensive',
        name: 'TTT 3D (Offensiv)',
        description: 'Aggressive Raumexpansion: loss=-8000, Fork-Fokus, Multi-Achsen-Druck.',
        weights: {
            win: 10000, loss: -8000, draw: -200,
            twoInLine: 30, oneInLine: 4,
            centerBonus: 20,
            forkBonus: 100, opponentForkPenalty: -30, pressureWeight: 30,
            threatMultiplier: 8
        }
    }),
    v6_local: _tttValidateConfig({
        game: 'ttt', variant: '3d', profile: 'v6_local',
        name: 'TTT 3D (Lokal)',
        description: 'Unmittelbare 3D-Linienbildung: Hohe Linienwerte, keine Positionsgewichte.',
        weights: {
            win: 10000, loss: -10000, draw: 0,
            twoInLine: 30, oneInLine: 5,
            forkBonus: 50, opponentForkPenalty: -60, pressureWeight: 20
        }
    }),
    v7_global: _tttValidateConfig({
        game: 'ttt', variant: '3d', profile: 'v7_global',
        name: 'TTT 3D (Global)',
        description: 'Raumkontrolle dominiert: Zentrum=50, spatialControl=10, Ecken=15, niedrige Linien.',
        weights: {
            win: 10000, loss: -10000, draw: 0,
            twoInLine: 8, oneInLine: 1,
            centerBonus: 50, spatialControl: 10, cornerBonus: 15,
            forkBonus: 30, opponentForkPenalty: -40
        }
    })
};

// ═══════════════════════════════════════════════════════════════
//  TTT ULTIMATE — 9 verschachtelte Boards
// ═══════════════════════════════════════════════════════════════

const TTT_ULTIMATE_PROFILES = {
    v1_baseline: _tttValidateConfig({
        game: 'ttt', variant: 'ultimate', profile: 'v1_baseline',
        name: 'TTT Ultimate (Baseline)',
        description: 'Makro-Board-Bewertung + einfache lokale Linienzählung.',
        weights: {
            win: 100000, loss: -100000, draw: 0,
            macroWeight: 50, boardWonBonus: 20,
            twoInLine: 10, oneInLine: 1
        }
    }),
    v2_positional: _tttValidateConfig({
        game: 'ttt', variant: 'ultimate', profile: 'v2_positional',
        name: 'TTT Ultimate (Positional)',
        description: 'Hoher Wert für Makro-Zentrum und strategische Board-Kontrolle.',
        weights: {
            win: 100000, loss: -100000, draw: 0,
            macroWeight: 80, boardWonBonus: 30,
            twoInLine: 12, oneInLine: 2,
            centerBonus: 25
        }
    }),
    v3_aggressive: _tttValidateConfig({
        game: 'ttt', variant: 'ultimate', profile: 'v3_aggressive',
        name: 'TTT Ultimate (Aggressive)',
        description: 'Maximiert Board-Gewinne im Makro und sendet Gegner in tote Boards.',
        weights: {
            win: 100000, loss: -100000, draw: 0,
            macroWeight: 60, boardWonBonus: 40,
            twoInLine: 20, oneInLine: 3,
            pressureWeight: 20, blockUrgency: 80
        }
    }),

    // ═══ OPTIMIERTE STRATEGISCHE PROFILE (Ultimate) ═══

    v4_defensive: _tttValidateConfig({
        game: 'ttt', variant: 'ultimate', profile: 'v4_defensive',
        name: 'TTT Ultimate (Defensiv)',
        description: 'Makro-Defense: loss=-150000 (1.5×win), hoher Makro-Gewicht für sichere Board-Kontrolle.',
        weights: {
            win: 100000, loss: -150000, draw: 5000,
            macroWeight: 90, boardWonBonus: 25,
            twoInLine: 8, oneInLine: 1,
            centerBonus: 15,
            blockUrgency: 100, pressureWeight: 5
        }
    }),
    v5_offensive: _tttValidateConfig({
        game: 'ttt', variant: 'ultimate', profile: 'v5_offensive',
        name: 'TTT Ultimate (Offensiv)',
        description: 'Aggressive Board-Gewinne: loss=-80000, hoher boardWonBonus, Druck auf Makro-Linien.',
        weights: {
            win: 100000, loss: -80000, draw: -2000,
            macroWeight: 50, boardWonBonus: 60,
            twoInLine: 25, oneInLine: 3,
            centerBonus: 10,
            pressureWeight: 30, blockUrgency: 40
        }
    }),
    v6_local: _tttValidateConfig({
        game: 'ttt', variant: 'ultimate', profile: 'v6_local',
        name: 'TTT Ultimate (Lokal)',
        description: 'Fokus auf lokale Teilboard-Gewinne: Hohe Linienwerte, niedriger Makro-Gewicht.',
        weights: {
            win: 100000, loss: -100000, draw: 0,
            macroWeight: 30, boardWonBonus: 50,
            twoInLine: 25, oneInLine: 5,
            pressureWeight: 15, blockUrgency: 60
        }
    }),
    v7_global: _tttValidateConfig({
        game: 'ttt', variant: 'ultimate', profile: 'v7_global',
        name: 'TTT Ultimate (Global)',
        description: 'Makro-Struktur dominiert: macroWeight=100, centerBonus=30, niedrige lokale Werte.',
        weights: {
            win: 100000, loss: -100000, draw: 0,
            macroWeight: 100, boardWonBonus: 15,
            twoInLine: 5, oneInLine: 1,
            centerBonus: 30
        }
    })
};

/**
 * Zentrales Konfigurations-Verzeichnis aller TTT-Profile.
 * Schlüssel: variant → profile → config.
 * @type {Object<string, Object<string, Object>>}
 */
const TTT_HEURISTICS_CONFIGS = {
    regular: TTT_REGULAR_PROFILES,
    '3d': TTT_3D_PROFILES,
    ultimate: TTT_ULTIMATE_PROFILES
};

/**
 * Factory-Funktion: Lädt die Konfiguration für eine TTT-Variante und ein Profil.
 * @param {string} [variant='regular'] - 'regular', '3d' oder 'ultimate'.
 * @param {string} [profile='v1_baseline'] - Profil-ID: v1_baseline bis v7_global.
 * @returns {Object} Validierte Heuristik-Konfiguration.
 */
function getTTTHeuristicsConfig(variant = 'regular', profile = 'v1_baseline') {
    const normalizedVariant = variant === '_3d' ? '3d' : variant;
    const variantConfigs = TTT_HEURISTICS_CONFIGS[normalizedVariant];

    if (!variantConfigs) {
        if (typeof DebugConfig !== 'undefined' && typeof DEBUG_DOMAINS !== 'undefined') {
            DebugConfig.log(DEBUG_DOMAINS.AI_HEURISTICS, 'warn',
                `Unbekannte TTT-Variante: ${variant}. Fallback auf 'regular'.`);
        }
        return TTT_HEURISTICS_CONFIGS.regular.v1_baseline;
    }

    const config = variantConfigs[profile];
    if (!config) {
        if (typeof DebugConfig !== 'undefined' && typeof DEBUG_DOMAINS !== 'undefined') {
            DebugConfig.log(DEBUG_DOMAINS.AI_HEURISTICS, 'warn',
                `Unbekanntes Profil: ${profile} für ${variant}. Fallback auf 'v1_baseline'.`);
        }
        return variantConfigs.v1_baseline;
    }

    return config;
}

/**
 * Gibt alle verfügbaren Profile für eine TTT-Variante zurück.
 * @param {string} [variant='regular'] - Spielvariante.
 * @returns {Array<{id: string, name: string, description: string}>}
 */
function getTTTProfileList(variant = 'regular') {
    const variantConfigs = TTT_HEURISTICS_CONFIGS[variant];
    if (!variantConfigs) return [];

    return Object.entries(variantConfigs).map(([id, cfg]) => ({
        id,
        name: cfg.name,
        description: cfg.description || ''
    }));
}