User prompt
rewrite the ai completely and make it advanced and smart
User prompt
fix the erros
User prompt
improve the training feature
User prompt
fix it
User prompt
create a new class called Training this class is so that everytime the ai looses or wins or it's a tie the ai learns from it's mistake and will overall get better at the game
User prompt
fix the game
User prompt
make the ai more advanced at choosing
User prompt
fix the implementation
User prompt
for the rethink add a realtime delay for choosing and instead of choosing random cells it also tries to block the player from winning
User prompt
make sure to add a seperate class for the rethink feature
User prompt
add 1 one new feature to the ai called Rethink which will allow the ai to think where to pick a cell like if it's a real player
User prompt
game it now broken
User prompt
fix a bug that doesn't allow the player to go again after ai's turn
User prompt
rewrite the whole entire game with more improved features
User prompt
fix a bug where x can't go again
User prompt
optimize the code and refine it
User prompt
Decrease the delay for when the ai chooses
User prompt
add 2 new features
User prompt
Please fix the bug: 'TypeError: originalTick is not a function' in or related to this line: 'originalTick();' Line Number: 632
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'now')' in or related to this line: 'var startTime = performance.now();' Line Number: 624
User prompt
make 2 new systems for performance and another one for the game itself
User prompt
make a feature where the ai can predict what cell block the player inputs
User prompt
Migrate to the latest version of LK
User prompt
add a failsafe feature where if the game ever softlocks or has problems make sure to cause a game over
User prompt
Please fix the bug: 'Timeout.tick error: self.analyzePlayerPatterns is not a function' in or related to this line: 'var patternAnalysis = self.analyzePlayerPatterns();' Line Number: 280
/****
* Classes
****/
var AIPlayer = Container.expand(function () {
var self = Container.call(this);
self.decision = new Decision();
self.observePlayer = function (playerMoveIndex) {
// AI logic to observe player's move and decide next move
self.decision.playerMoves.push(playerMoveIndex);
self.decision.availableCells.splice(self.decision.availableCells.indexOf(playerMoveIndex), 1);
};
self.makeMove = function () {
// Use the Decision class to choose the best cell for the AI's move
if (!game.gameOver && !game.aiCooldownActive) {
LK.setTimeout(function () {
// Disable player input
grid.forEach(function (cell) {
cell.interactive = false;
});
// Add a slight delay before making the AI move visible and interactive to ensure AI has "reserved" the cell
LK.setTimeout(function () {
// AI decision-making logic to choose the best cell
var chosenIndex = self.decision.decide();
if (chosenIndex !== undefined && !grid[chosenIndex].taken) {
var indicatorShape = grid[chosenIndex].attachAsset('indicator', {
anchorX: 0.5,
anchorY: 0.5
});
LK.setTimeout(function () {
indicatorShape.destroy();
grid[chosenIndex].setPlayerValue('O');
self.decision.aiMoves.push(chosenIndex);
self.decision.availableCells.splice(self.decision.availableCells.indexOf(chosenIndex), 1);
game.checkGameState();
if (!game.gameOver) {
game.aiTurn = false;
} else {
// Reset decision state for next game
self.decision.playerMoves = [];
self.decision.aiMoves = [];
self.decision.availableCells = Array.from({
length: 9
}, function (_, i) {
return i;
});
}
}, game.aiCooldown);
} else {
game.aiTurn = false; // Ensure AI turn is ended if no valid move is made
}
}, game.aiCooldown);
self.decision.decide(function (chosenIndex) {
if (chosenIndex !== undefined && !grid[chosenIndex].taken) {
var indicatorShape = grid[chosenIndex].attachAsset('indicator', {
anchorX: 0.5,
anchorY: 0.5
});
LK.setTimeout(function () {
indicatorShape.destroy();
grid[chosenIndex].setPlayerValue('O');
self.decision.aiMoves.push(chosenIndex);
self.decision.availableCells.splice(self.decision.availableCells.indexOf(chosenIndex), 1);
game.checkGameState();
if (!game.gameOver) {
game.aiTurn = false;
} else {
// Removed reset of playerMoves and aiMoves to allow AI to learn from previous games
for (var i = 0; i < 9; i++) {
if (!self.decision.availableCells.includes(i)) {
self.decision.availableCells.push(i);
}
}
}
}, game.aiCooldown);
} else {
game.aiTurn = false; // Ensure AI turn is ended if no valid move is made
}
// Increase delay enabling player input to prevent immediate selection after AI's choice
LK.setTimeout(function () {
grid.forEach(function (cell) {
if (!cell.taken) {
cell.interactive = true;
}
});
game.aiTurn = false;
}, 1000); // Increase delay to 1000ms before player can interact again
game.checkGameState();
if (game.gameOver) {
self.decision.playerMoves = [];
self.decision.aiMoves = [];
for (var i = 0; i < 9; i++) {
self.decision.availableCells[i] = i;
}
}
});
}, game.aiCooldown);
game.aiCooldownActive = true;
LK.setTimeout(function () {
game.aiCooldownActive = false;
}, game.aiCooldown);
}
};
// Add a method to undo the last move
self.undoLastMove = function () {
if (self.decision.aiMoves.length > 0) {
var lastMoveIndex = self.decision.aiMoves.pop();
grid[lastMoveIndex].taken = false;
grid[lastMoveIndex].value = null;
grid[lastMoveIndex].removeChildren();
self.decision.availableCells.push(lastMoveIndex);
}
};
});
// Define the Cell class for the tic tac toe grid
var Cell = Container.expand(function (x, y, index) {
var self = Container.call(this);
self.index = index;
self.taken = false;
self.value = null;
var cellGraphics = self.attachAsset('cell', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.interactive = true;
self.on('down', function () {
if (!self.taken && !game.aiTurn && !game.gameOver) {
self.setPlayerValue('X');
game.checkGameState();
if (!game.gameOver) {
game.aiPlayer.observePlayer(self.index);
game.aiTurn = true;
game.aiPlay();
}
}
});
self.setPlayerValue = function (value) {
self.taken = true;
self.value = value;
var shape = value === 'X' ? 'xShape' : 'oShape';
var color = value === 'X' ? 0xFF0000 : 0x0000FF;
var playerShape = self.attachAsset(shape, {
anchorX: 0.5,
anchorY: 0.5,
color: color
});
};
});
// Initialize power-up assets
var Decision = Container.expand(function () {
var self = Container.call(this);
self.decide = function (callback) {
// AI decision-making logic to choose the best cell
// First, check if the player is about to win and block them
// Enhanced AI decision-making process
var winningMoveIndex = -1;
var blockMoveIndex = -1;
winConditions.forEach(function (condition) {
var aiCount = condition.filter(function (index) {
return self.aiMoves.includes(index);
}).length;
var playerCount = condition.filter(function (index) {
return self.playerMoves.includes(index);
}).length;
var availableCount = condition.filter(function (index) {
return self.availableCells.includes(index);
}).length;
if (aiCount === 2 && availableCount === 1) {
// If AI can win in the next move, prioritize that move
winningMoveIndex = condition.find(function (index) {
return self.availableCells.includes(index);
});
}
if (playerCount === 2 && availableCount === 1) {
// If player is about to win, find and block that move
blockMoveIndex = condition.find(function (index) {
return self.availableCells.includes(index);
});
// Additionally, check if blocking this move creates a potential win condition for AI in future turns
var potentialWinAfterBlock = winConditions.some(function (winCondition) {
return winCondition.includes(blockMoveIndex) && winCondition.filter(function (i) {
return self.aiMoves.includes(i);
}).length === 2;
});
if (potentialWinAfterBlock) {
// Prioritize blocking moves that could lead to a win
blockMoveIndex = condition.find(function (index) {
return self.availableCells.includes(index) && winConditions.some(function (winCondition) {
return winCondition.includes(index) && winCondition.filter(function (i) {
return self.aiMoves.includes(i);
}).length === 2;
});
});
}
}
});
// Prioritize AI's winning move over blocking
if (winningMoveIndex !== -1) {
if (typeof callback === 'function') {
callback(winningMoveIndex);
}
return;
}
// Use blocking move if no winning move is available
if (blockMoveIndex !== -1) {
if (typeof callback === 'function') {
callback(blockMoveIndex);
}
return;
}
// Find and execute fork opportunities for AI
var forkMove = self.findForkMove();
if (forkMove !== -1) {
if (typeof callback === 'function') {
callback(forkMove);
}
return;
}
// If no fork opportunity, proceed with strategic move
var strategicMove = self.findStrategicMove();
if (strategicMove !== -1) {
if (typeof callback === 'function') {
callback(strategicMove);
}
return;
}
// As a last resort, choose a random available cell
var randomIndex = self.availableCells[Math.floor(Math.random() * self.availableCells.length)];
if (typeof callback === 'function') {
callback(randomIndex);
}
};
self.findEmptySide = function () {
var sideIndices = [1, 3, 5, 7];
var emptySides = sideIndices.filter(function (index) {
return self.availableCells.includes(index);
});
return emptySides.length > 0 ? emptySides[Math.floor(Math.random() * emptySides.length)] : -1;
};
self.findOppositeCorner = function () {
var playerCorners = [0, 2, 6, 8].filter(function (index) {
return self.playerMoves.includes(index);
});
var oppositeCorners = {
0: 8,
2: 6,
6: 2,
8: 0
};
var availableOppositeCorners = playerCorners.map(function (index) {
return oppositeCorners[index];
}).filter(function (index) {
return self.availableCells.includes(index);
});
return availableOppositeCorners.length > 0 ? availableOppositeCorners[0] : -1;
};
self.availableCells = [];
self.playerMoves = [];
self.aiMoves = [];
self.observe = function (playerMoveIndex) {
self.playerMoves.push(playerMoveIndex);
self.availableCells.splice(self.availableCells.indexOf(playerMoveIndex), 1);
};
// Method to analyze player's move patterns and adjust strategy
self.analyzePlayerPatterns = function () {
// Placeholder for pattern analysis logic
// Analyze player's moves to identify any recurring patterns or strategies
// Return analysis result that can be used to adjust AI strategy
return {}; // Return an empty object as a placeholder
};
self.decide = function (callback) {
// Enhanced AI decision-making with pattern recognition
// This AI will analyze the player's recent moves to identify patterns and adjust its strategy accordingly.
// For example, if the player tends to favor corners, the AI might prioritize taking the center cell.
var patternAnalysis = self.analyzePlayerPatterns();
var strategicMoveIndex = self.findStrategicMoveBasedOnPattern(patternAnalysis);
var chosenIndex = strategicMoveIndex !== -1 ? strategicMoveIndex : self.availableCells[Math.floor(Math.random() * self.availableCells.length)];
var winningMoveIndex = -1;
var blockMoveIndex = -1;
winConditions.forEach(function (condition) {
var aiCount = condition.filter(function (index) {
return self.aiMoves.includes(index);
}).length;
var playerCount = condition.filter(function (index) {
return self.playerMoves.includes(index);
}).length;
var availableCount = condition.filter(function (index) {
return self.availableCells.includes(index);
}).length;
if (aiCount === 2 && availableCount === 1) {
winningMoveIndex = condition.find(function (index) {
return self.availableCells.includes(index);
});
if (winningMoveIndex !== -1) {
if (typeof callback === 'function') {
callback(winningMoveIndex);
}
return;
}
}
if (aiCount === 2 && availableCount === 1) {
winningMoveIndex = condition.find(function (index) {
return self.availableCells.includes(index);
});
if (winningMoveIndex !== -1) {
if (typeof callback === 'function') {
callback(winningMoveIndex);
}
return;
}
}
if (playerCount === 2 && availableCount === 1) {
blockMoveIndex = condition.find(function (index) {
return self.availableCells.includes(index);
});
}
});
self.findTrapMove = function () {
var trapMoveIndex = -1;
var potentialTraps = winConditions.filter(function (condition) {
var aiCount = condition.filter(function (index) {
return self.aiMoves.includes(index);
}).length;
var availableCount = condition.filter(function (index) {
return self.availableCells.includes(index);
}).length;
return aiCount === 1 && availableCount === 2;
});
if (potentialTraps.length >= 2) {
var intersections = potentialTraps.reduce(function (acc, condition) {
return acc.concat(condition.filter(function (index) {
return self.availableCells.includes(index);
}));
}, []);
var counts = intersections.reduce(function (acc, index) {
acc[index] = (acc[index] || 0) + 1;
return acc;
}, {});
var maxCount = Math.max.apply(null, Object.values(counts));
if (maxCount === 2) {
trapMoveIndex = parseInt(Object.keys(counts).find(function (key) {
return counts[key] === maxCount;
}), 10);
}
}
return trapMoveIndex;
};
self.findForkBlock = function (playerType) {
var moves = playerType === 'ai' ? self.aiMoves : self.playerMoves;
var forkBlockIndex = -1;
self.availableCells.some(function (cellIndex) {
var forkCount = 0;
winConditions.forEach(function (condition) {
if (condition.includes(cellIndex)) {
var playerCount = condition.filter(function (index) {
return moves.includes(index);
}).length;
var availableCount = condition.filter(function (index) {
return self.availableCells.includes(index) && index !== cellIndex;
}).length;
if (playerCount === 1 && availableCount === 1) {
forkCount++;
if (forkCount > 1) {
forkBlockIndex = cellIndex;
return true;
}
}
}
});
if (forkCount > 1) {
forkBlockIndex = cellIndex;
return true;
}
return false;
});
return forkBlockIndex;
};
var centerIndex = 4;
var cornerIndices = [0, 2, 6, 8];
var oppositeCornerIndex = self.findOppositeCorner();
var emptyCornerIndex = cornerIndices.find(function (index) {
return self.availableCells.includes(index);
});
var emptySideIndex = self.findEmptySide();
var centerIndex = 4;
var isFirstMove = self.aiMoves.length === 0 && self.playerMoves.length === 0;
var aiForkMoveIndex = self.findForkMove('ai');
var playerForkMoveIndex = self.findForkMove('player');
var isFirstMove = self.aiMoves.length === 0 && self.playerMoves.length === 0;
var centerIndex = 4;
var isFirstMoveCenterAvailable = isFirstMove && self.availableCells.includes(centerIndex);
var chosenCell = winningMoveIndex !== -1 ? winningMoveIndex : blockMoveIndex !== -1 ? blockMoveIndex : aiForkMoveIndex !== -1 ? aiForkMoveIndex : playerForkMoveIndex !== -1 ? playerForkMoveIndex : isFirstMoveCenterAvailable ? centerIndex : emptyCornerIndex !== undefined ? emptyCornerIndex : oppositeCornerIndex !== -1 ? oppositeCornerIndex : emptySideIndex !== -1 ? emptySideIndex : self.availableCells.sort(function (a, b) {
return a - b;
})[0];
if (typeof callback === 'function') {
callback(chosenCell);
}
};
self.findForkMove = function (playerType) {
var moves = playerType === 'ai' ? self.aiMoves : self.playerMoves;
var forkMoveIndex = -1;
self.availableCells.some(function (cellIndex) {
var forkCount = 0;
winConditions.forEach(function (condition) {
if (condition.includes(cellIndex)) {
var playerCount = condition.filter(function (index) {
return moves.includes(index);
}).length;
var availableCount = condition.filter(function (index) {
return self.availableCells.includes(index) && index !== cellIndex;
}).length;
if (playerCount === 1 && availableCount === 2) {
forkCount++;
if (forkCount > 1) {
forkMoveIndex = cellIndex;
return true;
}
}
}
});
if (forkCount > 1) {
forkMoveIndex = cellIndex;
return true;
}
return false;
});
return forkMoveIndex;
};
for (var i = 0; i < 9; i++) {
self.availableCells.push(i);
}
// Method to adjust AI difficulty
self.adjustDifficulty = function (level) {
switch (level) {
case 1:
// Easy
this.predictPlayerMove = function () {
return this.availableCells[Math.floor(Math.random() * this.availableCells.length)];
};
break;
case 2:
// Medium
// Implement medium difficulty logic here
break;
case 3:
// Hard
// Implement hard difficulty logic here, possibly using more advanced strategies
break;
case 4:
// Extreme
// Implement extreme difficulty logic, making the AI nearly unbeatable
// Implement extreme difficulty logic, making the AI nearly unbeatable
this.decide = function (callback) {
// Enhanced AI decision-making logic for extreme difficulty
// Utilize a more sophisticated algorithm to evaluate and choose the best move
// This could involve analyzing multiple future moves ahead (like in chess algorithms)
// and considering both offensive and defensive strategies based on the current state of the game.
// Placeholder for advanced decision-making algorithm
// Example placeholder logic
if (typeof callback === 'function') {
callback(chosenIndex);
}
};
// Enhanced method for predicting and countering the player's next move based on common tic-tac-toe strategies
self.predictAndCounterPlayerMove = function () {
// Analyze the game state to predict the player's next move
var predictedPlayerMove = self.predictPlayerNextMove();
var counterMoveIndex = -1;
// Decide on a counter strategy based on the predicted player move
if (predictedPlayerMove !== -1) {
counterMoveIndex = self.counterPredictedPlayerMove(predictedPlayerMove);
} else {
// If unable to predict player's move, choose a strategic move
counterMoveIndex = self.findStrategicMove();
}
// If no strategic move is found, fallback to a random available cell
return counterMoveIndex !== -1 ? counterMoveIndex : self.availableCells[Math.floor(Math.random() * self.availableCells.length)];
};
// Method to analyze player's move tendencies and return an analysis object
self.analyzePlayerTendencies = function () {
var tendencies = {
favorCorners: false,
favorCenter: false
// Additional tendencies can be added here
};
// Analyze the player's moves to identify tendencies
var cornerMoves = [0, 2, 6, 8];
var centerMove = 4;
var playerCornerMoves = self.playerMoves.filter(function (move) {
return cornerMoves.includes(move);
}).length;
var playerCenterMoves = self.playerMoves.includes(centerMove) ? 1 : 0;
// Determine tendencies based on move history
tendencies.favorCorners = playerCornerMoves > playerCenterMoves;
tendencies.favorCenter = playerCenterMoves > 0;
return tendencies;
};
// Method to find an empty corner, prioritizing corners not adjacent to the player's last move
self.findEmptyCorner = function () {
var cornerIndices = [0, 2, 6, 8];
var emptyCorners = cornerIndices.filter(function (index) {
return self.availableCells.includes(index);
});
return emptyCorners.length > 0 ? emptyCorners[Math.floor(Math.random() * emptyCorners.length)] : -1;
};
// Method to find the center or an empty side, based on availability
self.findCenterOrSide = function () {
var centerIndex = 4;
var sideIndices = [1, 3, 5, 7];
var emptySides = sideIndices.filter(function (index) {
return self.availableCells.includes(index);
});
if (self.availableCells.includes(centerIndex)) {
return centerIndex;
} else if (emptySides.length > 0) {
return emptySides[Math.floor(Math.random() * emptySides.length)];
} else {
return -1;
}
};
break;
default:
// Default to medium difficulty if an unknown level is provided
break;
}
};
});
// Initialize star asset
// Define the PowerUp class for special abilities on the board
var PowerUp = Container.expand(function (x, y, type) {
var self = Container.call(this);
self.x = x;
self.y = y;
self.type = type; // 'extraTurn' or 'removeAIMove'
var powerUpGraphics = self.attachAsset(type === 'extraTurn' ? 'extraTurnShape' : 'removeAIMoveShape', {
anchorX: 0.5,
anchorY: 0.5
});
self.interactive = true;
self.on('down', function () {
if (self.type === 'extraTurn') {
game.playerExtraTurn = true;
} else if (self.type === 'removeAIMove') {
game.aiPlayer.undoLastMove();
}
self.destroy();
});
});
// Define the Star class for the dynamic background
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('starShape', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1; // Random speed for each star
self.move = function () {
self.y += self.speed;
if (self.y > 2732) {
// Reset star position when it goes off-screen
self.y = -50;
self.x = Math.random() * 2048;
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Init game with black background
});
/****
* Game Code
****/
// Initialize AI decision indicator
var aiDecisionIndicator = new Text2('AI deciding...', {
size: 50,
fill: "#ffffff"
});
aiDecisionIndicator.anchor.set(0.5, 0);
aiDecisionIndicator.x = 2048 / 2;
aiDecisionIndicator.y = 100;
LK.gui.top.addChild(aiDecisionIndicator);
// Function to update AI decision indicator with countdown
function updateAIDecisionIndicator(countdown) {
aiDecisionIndicator.setText('AI decides in: ' + countdown + 's');
}
// Countdown logic for AI decision indicator
var countdown = 3; // AI decision countdown in seconds
var countdownInterval = LK.setInterval(function () {
if (countdown > 0) {
updateAIDecisionIndicator(countdown);
countdown--;
} else {
LK.clearInterval(countdownInterval);
aiDecisionIndicator.setText('AI deciding...');
}
}, 1000);
// Initialize power-up assets
var stars = [];
for (var i = 0; i < 100; i++) {
var star = new Star();
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
game.addChild(star);
stars.push(star);
}
// Animate stars
LK.on('tick', function () {
stars.forEach(function (star) {
star.move();
});
});
// Initialize star asset
var grid = [];
// Initialize the tic tac toe grid
function initializeGrid() {
var gridSize = 3;
var cellSize = 400;
var startX = (2048 - gridSize * cellSize) / 2 + cellSize / 2;
var startY = (2732 - gridSize * cellSize) / 2 + cellSize / 2;
for (var i = 0; i < gridSize; i++) {
for (var j = 0; j < gridSize; j++) {
var index = i * gridSize + j;
var cell = new Cell(startX + j * cellSize, startY + i * cellSize, index);
game.addChild(cell);
grid.push(cell);
}
}
}
game.aiPlayer = new AIPlayer();
initializeGrid();
// Define win conditions
var winConditions = [[0, 1, 2], [3, 4, 5], [6, 7, 8],
// Rows
[0, 3, 6], [1, 4, 7], [2, 5, 8],
// Columns
[0, 4, 8], [2, 4, 6] // Diagonals
];
// Define game logic
// Initialize dynamic difficulty adjustment
game.level = 1; // Start at level 1
game.playerWins = 0;
game.aiWins = 0;
game.adjustDifficulty = function () {
// Adjust difficulty based on player's win rate
var winRate = game.playerWins / (game.playerWins + game.aiWins);
if (winRate < 0.3) {
game.level = 1; // Easy
} else if (winRate >= 0.3 && winRate < 0.6) {
game.level = 2; // Medium
} else if (winRate >= 0.6 && winRate < 0.8) {
game.level = 3; // Hard
} else {
game.level = 4; // Extreme
}
game.aiPlayer.decision.adjustDifficulty(game.level);
// Update level display
levelCounter.setText('Level: ' + game.level);
};
game.playerWins = 0;
game.aiWins = 0;
var levelCounter = new Text2('Level: ' + game.level, {
size: 50,
fill: "#ffffff"
});
levelCounter.anchor.set(0.5, 0);
levelCounter.x = 2048 / 2;
levelCounter.y = 50;
LK.gui.top.addChild(levelCounter);
game.aiTurn = false;
game.aiCooldown = 1000; // Cooldown time in milliseconds
game.gameOver = false;
game.checkGameState = function () {
// Check for win conditions
var winConditions = [[0, 1, 2], [3, 4, 5], [6, 7, 8],
// Rows
[0, 3, 6], [1, 4, 7], [2, 5, 8],
// Columns
[0, 4, 8], [2, 4, 6] // Diagonals
];
for (var i = 0; i < winConditions.length; i++) {
var condition = winConditions[i];
if (grid[condition[0]].value && grid[condition[0]].value === grid[condition[1]].value && grid[condition[0]].value === grid[condition[2]].value) {
game.gameOver = true;
for (var i = 0; i < 3; i++) {
LK.setTimeout(function () {
LK.effects.flashScreen(0x00FF00, 300);
}, i * 600);
}
var winner = grid[condition[0]].value === 'X' ? 'You Win!' : 'AI Wins!';
var winText = new Text2(winner, {
size: 150,
fill: "#ffffff"
});
winText.anchor.set(0.5, 0.5);
winText.x = 2048 / 2;
winText.y = 2732 / 2;
LK.gui.center.addChild(winText);
if (grid[condition[0]].value === 'O') {
for (var i = 0; i < 3; i++) {
LK.setTimeout(function () {
LK.effects.flashScreen(0xFF0000, 300);
}, i * 600);
}
LK.setTimeout(function () {
LK.showGameOver();
game.level = 1; // Reset level to 1
levelCounter.setText('Level: ' + game.level);
}, 1800);
} else {
LK.setTimeout(function () {
grid.forEach(function (cell) {
cell.destroy();
});
grid = [];
game.aiPlayer.decision = new Decision(); // Reset AI decision state
game.aiTurn = false; // Reset AI turn state
game.gameOver = false; // Reset game over state
initializeGrid();
grid.forEach(function (cell) {
cell.interactive = true; // Re-enable player input
});
game.level++; // Increase the level
levelCounter.setText('Level: ' + game.level);
}, 2000);
}
return;
}
}
// Check for draw
var draw = grid.every(function (cell) {
return cell.taken;
});
if (draw) {
game.gameOver = true;
var flashCount = 0;
var flashInterval = LK.setInterval(function () {
LK.effects.flashScreen(0xA52A2A, 300);
flashCount++;
if (flashCount >= 4) {
LK.clearInterval(flashInterval);
grid.forEach(function (cell) {
cell.destroy();
});
grid = [];
game.aiPlayer.decision = new Decision();
game.aiTurn = false; // Reset AI turn state
game.gameOver = false; // Reset game over state
initializeGrid();
}
}, 600);
}
};
game.aiPlay = function () {
if (game.aiTurn) {
LK.setTimeout(function () {
game.aiPlayer.makeMove();
}, game.aiCooldown);
}
};
// Start the game with the player's turn
game.aiTurn = false;