viz/adapters/tree-factory.js

/**
 * @fileoverview TreeFactory - Generatoren für numerische Beispielbäume
 *
 * Stellt statische und zufällige Baumdefinitionen bereit,
 * die vom GenericTreeAdapter aufgebaut werden können.
 *
 * Trennungsprinzip:
 *   - TreeFactory erzeugt reine Datenstrukturen (Baumdefinitionen)
 *   - GenericTreeAdapter konsumiert diese und baut den visuellen Baum auf
 *
 * Baumdefinitions-Format:
 *   { root: { value: number|null, children: [...] } }
 *   - Blattknoten: { value: <number>, children: [] }   (oder kein children-Feld)
 *   - Innere Knoten: { value: null, children: [...] }
 *
 * @namespace TreeFactory
 * @author Alexander Wolf
 * @version 1.0
 * @see ENGINEERING_CONVENTIONS.md
 */
var TreeFactory = {

    /**
     * Erzeugt den klassischen Wikipedia Alpha-Beta-Pruning Beispielbaum.
     *
     * Struktur (Tiefe 2, Verzweigung 2):
     *   Root (MAX)
     *   ├── L (MIN)
     *   │   ├── L1 = 3
     *   │   └── L2 = 5   → L wird 3 (MIN)
     *   └── R (MIN)
     *       ├── R1 = 2   → Cutoff! (2 < 3, also α ≥ β → R2 wird gepruned)
     *       └── R2 = ?   (wird nicht evaluiert)
     *
     * Ohne AB: Root = MAX(MIN(3,5), MIN(2,?)) → MAX(3, MIN(2,...))
     * Mit AB:  Nach R1=2 gilt α=3 ≥ β=2 → R2 wird gepruned → Root = 3
     *
     * @returns {Object} Baumdefinition für GenericTreeAdapter.visualizeTree()
     */
    generateWikipediaExample() {
        return {
            root: {
                value: null,
                children: [
                    {
                        value: null,
                        children: [
                            { value: 3 },
                            { value: 5 },
                        ]
                    },
                    {
                        value: null,
                        children: [
                            { value: 2 },
                            { value: 8 },
                        ]
                    }
                ]
            }
        };
    },

    /**
     * Erzeugt einen Zufallsbaum mit konfigurierbaren Parametern.
     *
     * Alle Blattknoten erhalten zufällige ganzzahlige Werte im angegebenen Bereich.
     * Innere Knoten haben value: null (werden durch Evaluation bestimmt).
     *
     * @param {number} depth - Maximale Baumtiefe (1 = nur Root + Blätter)
     * @param {number} branching - Verzweigungsgrad (Kinder pro innerem Knoten)
     * @param {number} rangeMin - Minimaler Blattwert (inklusiv)
     * @param {number} rangeMax - Maximaler Blattwert (inklusiv)
     * @returns {Object} Baumdefinition für GenericTreeAdapter.visualizeTree()
     */
    generateRandomTree(depth, branching, rangeMin, rangeMax) {
        if (depth < 1) depth = 1;
        if (branching < 1) branching = 1;
        if (rangeMin > rangeMax) {
            var tmp = rangeMin;
            rangeMin = rangeMax;
            rangeMax = tmp;
        }

        return {
            root: this._generateRandomNode(depth, branching, rangeMin, rangeMax)
        };
    },

    /**
     * Rekursive Helper-Funktion für Zufallsbaum-Generierung.
     *
     * @param {number} remainingDepth - Verbleibende Tiefe
     * @param {number} branching - Verzweigungsgrad
     * @param {number} rangeMin - Minimaler Blattwert
     * @param {number} rangeMax - Maximaler Blattwert
     * @returns {Object} Knoten-Definition
     * @private
     */
    _generateRandomNode(remainingDepth, branching, rangeMin, rangeMax) {
        // Blattknoten: Tiefe 0 = Blatt
        if (remainingDepth <= 0) {
            return {
                value: this._randomInt(rangeMin, rangeMax)
            };
        }

        // Innerer Knoten
        var children = [];
        for (var i = 0; i < branching; i++) {
            children.push(
                this._generateRandomNode(remainingDepth - 1, branching, rangeMin, rangeMax)
            );
        }

        return {
            value: null,
            children: children
        };
    },

    /**
     * Generiert eine zufällige Ganzzahl im Bereich [min, max] (inklusiv).
     *
     * @param {number} min - Untere Grenze (inklusiv)
     * @param {number} max - Obere Grenze (inklusiv)
     * @returns {number} Zufällige Ganzzahl
     * @private
     */
    _randomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    },

    /**
     * Zählt die Gesamtanzahl der Knoten in einer Baumdefinition.
     * Nützlich für UI-Feedback vor dem Aufbau.
     *
     * @param {Object} treeDef - Baumdefinition
     * @returns {number} Gesamtanzahl Knoten
     */
    countNodes(treeDef) {
        if (!treeDef || !treeDef.root) return 0;
        return this._countSubtree(treeDef.root);
    },

    /**
     * Zählt Knoten eines Teilbaums rekursiv.
     *
     * @param {Object} node - Knoten-Definition
     * @returns {number} Knotenanzahl
     * @private
     */
    _countSubtree(node) {
        if (!node) return 0;
        var count = 1;
        if (node.children) {
            for (var i = 0; i < node.children.length; i++) {
                count += this._countSubtree(node.children[i]);
            }
        }
        return count;
    }
};

// Export: Global verfügbar
if (typeof window !== 'undefined') {
    window.TreeFactory = TreeFactory;
}

// Export für Node.js/CommonJS
if (typeof module !== 'undefined' && module.exports) {
    module.exports = TreeFactory;
}