/* --- FILE: js/games/tictactoe/ultimate-controller.js --- */
/**
* @fileoverview Controller für Ultimate Tic-Tac-Toe (9x9 mit Subboards)
*
* Extends BaseGameController mit Ultimate TTT Board-Support.
* Verwaltet Sperr-Logik für deaktivierte Subboards und 2-Level Navigation.
*
* @class UltimateGameController
* @extends BaseGameController
*/
class UltimateGameController extends BaseGameController {
constructor() {
super('ultimate', 'gameCanvas');
}
createGame() {
return new UltimateBoard();
}
reset() {
// ✅ Canvas-Größe für Ultimate anpassen (größer für Details)
this.canvas.width = 600;
this.canvas.height = 600;
super.reset();
}
drawGame() {
TTTRenderer.drawUltimate(this.canvas, this.game);
}
coordsToMove(mx, my) {
const bigS = this.canvas.width / 3;
const smallS = bigS / 3;
const bX = Math.floor(mx / bigS);
const bY = Math.floor(my / bigS);
const sX = Math.floor((mx % bigS) / smallS);
const sY = Math.floor((my % bigS) / smallS);
if (bX >= 0 && bX < 3 && bY >= 0 && bY < 3) {
return { big: bY * 3 + bX, small: sY * 3 + sX };
}
return null;
}
createAIAgent(type) {
if (type === 'random') {
return new RandomAgent();
} else if (type === 'rulebased' || type === 'rulebased_elementary') {
return new RuleBasedAgent(createStrategyTree('ultimate', 'elementary'));
} else if (type === 'rulebased_advanced') {
return new RuleBasedAgent(createStrategyTree('ultimate', 'advanced'));
} else if (type.startsWith('minimax')) {
const profileMap = { minimax: 'v1_baseline', minimax_positional: 'v2_positional', minimax_aggressive: 'v3_aggressive' };
const profile = profileMap[type] || 'v1_baseline';
const regKey = `ttt:ultimate:${profile}`;
const heuristicFn = (typeof HeuristicRegistry !== 'undefined' && HeuristicRegistry.has(regKey))
? HeuristicRegistry.get(regKey).evaluate.bind(HeuristicRegistry.get(regKey))
: (typeof HeuristicRegistry !== 'undefined' && HeuristicRegistry.has('ttt', 'ultimate'))
? HeuristicRegistry.get('ttt', 'ultimate').evaluate.bind(HeuristicRegistry.get('ttt', 'ultimate'))
: ((gameState, player) => {
if (gameState.winner === player) return 100000;
if (gameState.winner !== NONE && gameState.winner !== DRAW) return -100000;
return 0;
});
return new MinimaxAgent({
name: `Minimax Ultimate (${profile})`,
maxDepth: 4,
useAlphaBeta: true,
heuristicFn
});
}
return null;
}
}
// ===== WICHTIG: Die alte draw() Methode wurde entfernt =====
// Sie wird jetzt über drawGame() aufgerufen, die in der Basisklasse definiert ist.
// Fallback für HTML-inline onclick="..."
const draw = () => UltimateController?.drawGame?.();