diff --git a/public/ai-bot.js b/public/ai-bot.js index 16eba89..aa777af 100644 --- a/public/ai-bot.js +++ b/public/ai-bot.js @@ -14,19 +14,30 @@ export class AIBot { } /** - * Execute AI turn + * Execute AI turn - makes ONE move then ends turn */ async playTurn() { + console.log(`AI Player ${this.playerId} thinking...`); + // Get all player cells const playerCells = this.map.getPlayerCells(this.playerId); - if (playerCells.length === 0) return; + console.log(`AI Player ${this.playerId} has ${playerCells.length} cells`); + + if (playerCells.length === 0) { + console.log(`AI Player ${this.playerId} has no cells, ending turn`); + this.gameUI.endTurn(); + return; + } // Find all possible moves const moves = this.findPossibleMoves(playerCells); + console.log(`AI Player ${this.playerId} found ${moves.length} possible moves`); + if (moves.length === 0) { // No moves available, end turn + console.log(`AI Player ${this.playerId} has no moves, ending turn`); this.gameUI.endTurn(); return; } @@ -36,12 +47,20 @@ export class AIBot { // Execute best move const bestMove = moves[0]; - + console.log(`AI Player ${this.playerId} selected move: from (${bestMove.from.q},${bestMove.from.r}) to (${bestMove.to.q},${bestMove.to.r}), type=${bestMove.type}`); + // Wait for thinking time await this.wait(this.thinkingTime); + + // Execute the move directly without using executeMove helper + this.gameUI.selectedCell = bestMove.from; + this.gameUI.currentTarget = bestMove.to; + this.gameUI.executeAttack(); - // Execute the move - this.executeMove(bestMove); + console.log(`AI Player ${this.playerId} executed move`); + + // End turn after executing move + this.gameUI.endTurn(); } /** diff --git a/public/game.js b/public/game.js index d0c9b78..1237638 100644 --- a/public/game.js +++ b/public/game.js @@ -98,10 +98,6 @@ class GameUI { for (let i = 1; i <= this.playerCount; i++) { const typeSelect = document.getElementById(`player${i}-type`); this.playerTypes[i] = typeSelect.value; - - if (this.playerTypes[i] === 'ai') { - this.aiBots[i] = new AIBot(i, this.map, this); - } } // Show game screen @@ -120,6 +116,14 @@ class GameUI { this.hasMoved = false; this.isAIThinking = false; + // Initialize AI bots AFTER map is created + this.aiBots = {}; + for (let i = 1; i <= this.playerCount; i++) { + if (this.playerTypes[i] === 'ai') { + this.aiBots[i] = new AIBot(i, this.map, this); + } + } + // Initialize starting positions for all players this.initializePlayers(); @@ -193,11 +197,18 @@ class GameUI { const canvasHeight = this.canvas.height; const sqrt3 = Math.sqrt(3); - const mapWidth = HEX_SIZE * sqrt3 * (MAP_SIZE + MAP_SIZE/2); - const mapHeight = HEX_SIZE * 1.5 * (MAP_SIZE - 1) + HEX_SIZE * 2; + // Calculate map bounds with proper padding for hex visibility + // For pointy-top hex: width = sqrt(3) * size, height = 2 * size + // Rightmost hex (q=19, r=19): x = HEX_SIZE * sqrt3 * (19 + 19/2) = HEX_SIZE * sqrt3 * 28.5 + // Leftmost hex (q=0, r=0): x = 0 + // Add padding for full hex visibility (hex radius on each side) + const hexPadding = HEX_SIZE * 1.5; // Extra padding for hex radius + + const mapWidth = HEX_SIZE * sqrt3 * ((MAP_SIZE - 1) + (MAP_SIZE - 1) / 2); + const mapHeight = HEX_SIZE * 1.5 * (MAP_SIZE - 1); - this.offsetX = (canvasWidth - mapWidth) / 2 + HEX_SIZE * sqrt3; - this.offsetY = (canvasHeight - mapHeight) / 2 + HEX_SIZE; + this.offsetX = hexPadding; + this.offsetY = hexPadding; } setupEventListeners() {