/* --- FILE: js/games/tictactoe/regular-controller.js --- */
/**
* @fileoverview Controller für 3x3 Tic-Tac-Toe
*
* Extends BaseGameController mit regularem 3x3 Board-Support.
* Verwaltet Spielstatus, Benutzer-Input und Rendering für klassisches TTT.
*
* @class RegularGameController
* @extends BaseGameController
*/
class RegularGameController extends BaseGameController {
/**
* Erstellt einen neuen Regular Controller.
* @constructor
*/
constructor() {
super('regular', 'gameCanvas');
}
/**
* Erzeugt ein neues Regular Board.
* @returns {TTTRegularBoard} Ein neues 3x3 Tic-Tac-Toe Board
*/
createGame() {
return new TTTRegularBoard();
}
/**
* Setzt das Spiel zurück und konfiguriert Canvas-Größe.
* @override
* @returns {void}
*/
reset() {
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", '🔄 RegularGameController.reset() wird aufgerufen');
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", ' - Canvas vor Resize:', this.canvas?.width, 'x', this.canvas?.height);
if (!this.canvas) {
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "error", '❌ KRITISCHER FEHLER: Canvas ist null!');
return;
}
// ✅ Canvas-Größe für Regular anpassen
this.canvas.width = 400;
this.canvas.height = 400;
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", '✅ Canvas resized zu 400x400');
super.reset();
}
/**
* Zeichnet das Regular TTT Board auf Canvas.
* @override
* @returns {void}
*/
drawGame() {
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", '🎨 drawGame() - Zeichne Regular TTT Board');
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", ' - Canvas:', this.canvas.width, 'x', this.canvas.height);
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", ' - game.grid:', this.game.grid);
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", ' - game.winner:', this.game.winner);
TTTRenderer.drawRegular(this.canvas, this.game);
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", '✅ Zeichnen abgeschlossen');
}
/**
* Konvertiert Mauskoordinaten zu Board-Move-Index.
* @param {number} mx - Maus X-Koordinate
* @param {number} my - Maus Y-Koordinate
* @returns {number|null} Move als 0-8 Index oder null wenn invalid
*/
coordsToMove(mx, my) {
const s = this.canvas.width / 3;
const c = Math.floor(mx / s);
const r = Math.floor(my / s);
if (c >= 0 && c < 3 && r >= 0 && r < 3) {
return r * 3 + c;
}
return null;
}
createAIAgent(type) {
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", '🤖 RegularGameController.createAIAgent() aufgerufen mit type:', type);
try {
if (type === 'random') {
const agent = new RandomAgent();
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "debug", '✅ RandomAgent erstellt');
return agent;
} else if (type === 'rulebased' || type === 'rulebased_elementary') {
const tree = createStrategyTree('regular', 'elementary');
return new RuleBasedAgent(tree);
} else if (type === 'rulebased_advanced') {
const tree = createStrategyTree('regular', 'advanced');
return new RuleBasedAgent(tree);
} else if (type.startsWith('minimax')) {
// Profile-Mapping: minimax → v1_baseline, minimax_positional → v2_positional, etc.
const profileMap = { minimax: 'v1_baseline', minimax_positional: 'v2_positional', minimax_aggressive: 'v3_aggressive' };
const profile = profileMap[type] || 'v1_baseline';
const regKey = `ttt:regular:${profile}`;
const heuristicFn = (typeof HeuristicRegistry !== 'undefined' && HeuristicRegistry.has(regKey))
? HeuristicRegistry.get(regKey).evaluate.bind(HeuristicRegistry.get(regKey))
: (typeof HeuristicRegistry !== 'undefined' && HeuristicRegistry.has('ttt', 'regular'))
? HeuristicRegistry.get('ttt', 'regular').evaluate.bind(HeuristicRegistry.get('ttt', 'regular'))
: ((gameState, player) => {
if (gameState.winner === player) return 1000;
if (gameState.winner !== NONE && gameState.winner !== DRAW) return -1000;
return 0;
});
return new MinimaxAgent({
name: `Minimax (${profile})`,
maxDepth: 9,
useAlphaBeta: true,
heuristicFn
});
}
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "warn", '⚠️ Unbekannter Agent-Typ:', type);
return null;
} catch (error) {
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "error", `❌ FEHLER beim Erstellen des ${type} Agents:`, error);
DebugConfig.log(DEBUG_DOMAINS.GAMES_TTT_REGULAR, "error", ' Stack:', error.stack);
return null;
}
}
}