User prompt
Oyunu hiç bozmadan, dokunmadan hataları düzelt.
User prompt
Bu modumu seçmek istiyorsun diye uyarı veren yerde Evet veya Hayır'a tıklayınca tepki vermiyor.
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'down')' in or related to this line: 'yesBtn.down = function (x, y, obj) {' Line Number: 397
User prompt
Bir Zorluk Modu Seçince Bu Zorluk Modunu Mu Seçmek İstiyorsun Diye Uyarsın
User prompt
kolay, normal ve zor düğmelerin altında blok olsun renk yanıyor
User prompt
Oyun oynarken bazı yerlere tıklayınca algılamıyor, bir boşluğa tıklayınca hepsini algılasın. Hataları düzelt.
User prompt
kolay, normal ve zor modlar arasında boşluklar olsun yoksa yanlışla yanlış modu seçebiliyoruz
User prompt
Yapay zeka modunda bazı yerleri kendimiz koyamıyoruz.
User prompt
yapay zeka modunu seçince kolay, normal ve zor modlar olsun
User prompt
Yapay ZK'ya daha çok taktik öğret.
User prompt
Algılama sistemini ve hataları düzelt.
User prompt
Yapay Zeka Hep Aynı Hareketleri Yapmasın Aynı Stratejileri Yapmasın Farklı Farklı
User prompt
Yapay zeka, bizim tıkladığımız yere göre hep belirli yerlere tıklıyor. Farklı yerlere ama mantıklı, saçma yerlere dokunmadan düzgün bir oyun oynasın. Bizim tıkladığımız yere göre belirli yerlere dokunmadan.
User prompt
Bazən bizim tıxladığımız yerə yapay zeka qoyuyor. O yüzden bizim tıxladığımız yerlə yapay zekanın tıxladığı yeri algıla və doğru konumlandır.
User prompt
Bazen oyundaki düğmeler çalışmıyor.
User prompt
Oyun oynarken arada küçük donmalar kesilmeler oluyor.
User prompt
oyuna ilk girdiğimizde küçük bir donma yaşanıyor o yüzden tıklayamıyoruz
User prompt
Oyun bazen yapay zekayı ilk oyuncu olarak görüyor bu yüzden ilk yapay zekanın tıklamasına izin veriyor ama ilk bizim tıklamamız gerekiyor.
User prompt
oyuna girdiğimizde menüde yani oyunun içerisinde tıklamak için bekleme süresi aşırı uzun yapay zekayı etkilemeyecek şekilde
User prompt
ekrana çok hızlı tıklayarak yapay zekanın yapay zekayı da kontrol edebiliyoruz yapay zekanın yerine bir yere bir şey koyabiliyoruz
User prompt
kazandıktan sonra çıkan çizgi oyunu baştan başlatsak bile duruyor
User prompt
oyunda fark ettiğin hataları düzelt
User prompt
çizgileri eşit karelere böl ve 9 boşluk olsun yani oyunu bozmadan çizgileri eşite böl
User prompt
Oyundan herhangi bir şey çıkarmadan hataları düzelt.
User prompt
çıkış tuşunu biraz büyüt ve biraz daha sağa çek
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Cell = Container.expand(function (row, col) { var self = Container.call(this); self.row = row; self.col = col; self.value = 0; // 0 = empty, 1 = X (blue), 2 = O (red) var cellBg = self.attachAsset('cell', { anchorX: 0.5, anchorY: 0.5, alpha: 0.1 }); self.marker = null; self.placeMarker = function (type) { if (self.value !== 0) return false; self.value = type; if (type === 1) { // Blue X self.marker = self.attachAsset('xMarker', { anchorX: 0.5, anchorY: 0.5, alpha: 0, scaleX: 0.1, scaleY: 0.1 }); tween(self.marker, { alpha: 0.9, scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeOut }); } else { // Red O self.marker = self.attachAsset('oMarker', { anchorX: 0.5, anchorY: 0.5, alpha: 0, scaleX: 0.1, scaleY: 0.1 }); tween(self.marker, { alpha: 0.9, scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeOut }); } LK.getSound('place').play(); return true; }; self.down = function (x, y, obj) { if (!gameReady || gameOver || self.value !== 0 || gameMode === 'menu') return; // In AI mode, only allow player clicks during player's turn (currentPlayer === 1) if (isAIMode && currentPlayer !== 1) return; // Prevent rapid clicking by adding a small delay check if (self.lastClickTime && Date.now() - self.lastClickTime < 100) return; self.lastClickTime = Date.now(); // Store player's intended move before placing marker var playerRow = self.row; var playerCol = self.col; // Mark this cell as reserved for player to prevent AI interference self.isPlayerReserved = true; if (self.placeMarker(currentPlayer)) { // Clear reservation after successful placement self.isPlayerReserved = false; checkWin(); if (!gameOver) { if (isAIMode && currentPlayer === 1) { // AI mode - player played, now AI plays currentPlayer = 2; updateTurnDisplay(); makeAIMove(); } else if (isAIMode && currentPlayer === 2) { // This shouldn't happen in AI mode since AI doesn't click currentPlayer = 1; updateTurnDisplay(); } else { // Two player mode - switch players normally currentPlayer = currentPlayer === 1 ? 2 : 1; updateTurnDisplay(); } } } else { // Clear reservation if placement failed self.isPlayerReserved = false; } }; return self; }); var WinLine = Container.expand(function () { var self = Container.call(this); self.line = self.attachAsset('winLine', { anchorX: 0.5, anchorY: 0.5, alpha: 0, scaleX: 0 }); self.showWinLine = function (startX, startY, endX, endY, color) { var deltaX = endX - startX; var deltaY = endY - startY; var angle = Math.atan2(deltaY, deltaX); var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); self.x = startX + deltaX / 2; self.y = startY + deltaY / 2; self.line.rotation = angle; self.line.tint = color; self.line.width = distance; tween(self.line, { alpha: 1, scaleX: 1 }, { duration: 500, easing: tween.easeOut }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ var grid = []; var currentPlayer = 1; // 1 = Blue X, 2 = Red O var gameOver = false; var winLine = null; var gameMode = 'menu'; // 'menu', 'ai', 'twoPlayer' var isAIMode = false; var currentLanguage = storage.language || 'tr'; // 'tr' for Turkish, 'en' for English var languageTexts = { tr: { blueTurn: 'Sıra: Mavinin', redTurn: 'Sıra: Kırmızının', blueWin: 'MAVİ TAKIM KAZANDI!', redWin: 'KIRMIZI TAKIM KAZANDI!', draw: 'BERABERE!', playAgain: 'Tekrar Oyna', language: 'Türkçe', vsAI: 'Yapay Zeka ile Oyna', twoPlayer: 'İki Kişilik Oyna', selectMode: 'Oyun Modunu Seçin', back: '← Geri', exit: 'Çıkış' }, en: { blueTurn: 'Turn: Blue', redTurn: 'Turn: Red', blueWin: 'BLUE TEAM WON!', redWin: 'RED TEAM WON!', draw: 'DRAW!', playAgain: 'Play Again', language: 'English', vsAI: 'Play vs AI', twoPlayer: 'Two Player', selectMode: 'Select Game Mode', back: '← Back', exit: 'Exit' } }; // Game setup var gameBoard = game.addChild(new Container()); gameBoard.x = 2048 / 2; gameBoard.y = 2732 / 2; gameBoard.scaleX = 1.2; gameBoard.scaleY = 1.2; gameBoard.alpha = 0; // Hidden initially // Create background var background = gameBoard.attachAsset('gridBackground', { anchorX: 0.5, anchorY: 0.5 }); // Create grid lines var verticalLine1 = gameBoard.attachAsset('gridLine', { anchorX: 0.5, anchorY: 0.5, x: -300, height: 1800 }); var verticalLine2 = gameBoard.attachAsset('gridLine', { anchorX: 0.5, anchorY: 0.5, x: 300, height: 1800 }); var horizontalLine1 = gameBoard.attachAsset('gridLine', { anchorX: 0.5, anchorY: 0.5, y: -300, width: 1800, height: 8 }); var horizontalLine2 = gameBoard.attachAsset('gridLine', { anchorX: 0.5, anchorY: 0.5, y: 300, width: 1800, height: 8 }); // Create cells for (var row = 0; row < 3; row++) { grid[row] = []; for (var col = 0; col < 3; col++) { var cell = gameBoard.addChild(new Cell(row, col)); cell.x = (col - 1) * 600; cell.y = (row - 1) * 600; grid[row][col] = cell; } } // UI Elements var blueTurnText = new Text2(languageTexts[currentLanguage].blueTurn, { size: 120, fill: 0x00AAFF }); blueTurnText.anchor.set(0.5, 0); LK.gui.top.addChild(blueTurnText); blueTurnText.y = 150; var redTurnText = new Text2(languageTexts[currentLanguage].redTurn, { size: 120, fill: 0xff0000 }); redTurnText.anchor.set(0.5, 0); LK.gui.top.addChild(redTurnText); redTurnText.y = 150; var languageBtn = new Text2(languageTexts[currentLanguage === 'tr' ? 'en' : 'tr'].language, { size: 60, fill: 0xFFFFFF }); languageBtn.anchor.set(0.5, 0); LK.gui.top.addChild(languageBtn); languageBtn.y = 80; var statusText = new Text2('', { size: 100, fill: 0xFFFFFF }); statusText.anchor.set(0.5, 0.5); LK.gui.center.addChild(statusText); statusText.y = 400; var playAgainBtn = new Text2(languageTexts[currentLanguage].playAgain, { size: 80, fill: 0xFFFFFF }); playAgainBtn.anchor.set(0.5, 0.5); LK.gui.center.addChild(playAgainBtn); playAgainBtn.y = 550; playAgainBtn.alpha = 0; // Menu UI elements var menuTitle = new Text2(languageTexts[currentLanguage].selectMode, { size: 120, fill: 0xFFFFFF }); menuTitle.anchor.set(0.5, 0.5); LK.gui.center.addChild(menuTitle); menuTitle.y = -200; var vsAIBtn = new Text2(languageTexts[currentLanguage].vsAI, { size: 100, fill: 0x00AAFF }); vsAIBtn.anchor.set(0.5, 0.5); LK.gui.center.addChild(vsAIBtn); vsAIBtn.y = 0; var twoPlayerBtn = new Text2(languageTexts[currentLanguage].twoPlayer, { size: 100, fill: 0xFF4444 }); twoPlayerBtn.anchor.set(0.5, 0.5); LK.gui.center.addChild(twoPlayerBtn); twoPlayerBtn.y = 150; var backBtn = new Text2(languageTexts[currentLanguage].back, { size: 80, fill: 0xFFFFFF }); backBtn.anchor.set(0.5, 0.5); LK.gui.center.addChild(backBtn); backBtn.x = -800; backBtn.y = -300; backBtn.alpha = 0; var exitBtn = new Text2(languageTexts[currentLanguage].exit, { size: 80, fill: 0xFF0000 }); exitBtn.anchor.set(0.5, 0); LK.gui.top.addChild(exitBtn); exitBtn.y = 80; exitBtn.x = 450; exitBtn.alpha = 0; // Language toggle functionality languageBtn.down = function (x, y, obj) { // Always allow language switching regardless of game state currentLanguage = currentLanguage === 'tr' ? 'en' : 'tr'; storage.language = currentLanguage; updateLanguageTexts(); }; // Menu button handlers vsAIBtn.down = function (x, y, obj) { if (gameMode === 'menu') { startGame('ai'); } }; twoPlayerBtn.down = function (x, y, obj) { if (gameMode === 'menu') { startGame('twoPlayer'); } }; backBtn.down = function (x, y, obj) { if (gameMode !== 'menu') { resetGame(); showMenu(); } }; exitBtn.down = function (x, y, obj) { if (gameMode !== 'menu') { resetGame(); showMenu(); } }; function updateLanguageTexts() { blueTurnText.setText(languageTexts[currentLanguage].blueTurn); redTurnText.setText(languageTexts[currentLanguage].redTurn); playAgainBtn.setText(languageTexts[currentLanguage].playAgain); languageBtn.setText(languageTexts[currentLanguage === 'tr' ? 'en' : 'tr'].language); menuTitle.setText(languageTexts[currentLanguage].selectMode); vsAIBtn.setText(languageTexts[currentLanguage].vsAI); twoPlayerBtn.setText(languageTexts[currentLanguage].twoPlayer); backBtn.setText(languageTexts[currentLanguage].back); exitBtn.setText(languageTexts[currentLanguage].exit); } // Start in menu mode showMenu(); function updateTurnDisplay() { if (gameMode === 'menu' || gameOver) { blueTurnText.alpha = 0; redTurnText.alpha = 0; } else if (currentPlayer === 1) { blueTurnText.alpha = 1; redTurnText.alpha = 0; } else { blueTurnText.alpha = 0; redTurnText.alpha = 1; } } function showMenu() { gameMode = 'menu'; gameBoard.alpha = 0; menuTitle.alpha = 1; vsAIBtn.alpha = 1; twoPlayerBtn.alpha = 1; blueTurnText.alpha = 0; redTurnText.alpha = 0; statusText.alpha = 0; playAgainBtn.alpha = 0; backBtn.alpha = 0; exitBtn.alpha = 0; } function startGame(mode) { gameMode = mode; isAIMode = mode === 'ai'; gameBoard.alpha = 1; menuTitle.alpha = 0; vsAIBtn.alpha = 0; twoPlayerBtn.alpha = 0; backBtn.alpha = 1; exitBtn.alpha = 1; // In AI mode, player (1) always starts first if (isAIMode) { currentPlayer = 1; } else { // In two player mode, random start currentPlayer = Math.random() < 0.5 ? 1 : 2; } updateTurnDisplay(); } function checkWin() { var winner = 0; var winPositions = []; // Check rows for (var row = 0; row < 3; row++) { if (grid[row][0].value !== 0 && grid[row][0].value === grid[row][1].value && grid[row][1].value === grid[row][2].value) { winner = grid[row][0].value; winPositions = [{ row: row, col: 0 }, { row: row, col: 1 }, { row: row, col: 2 }]; break; } } // Check columns if (winner === 0) { for (var col = 0; col < 3; col++) { if (grid[0][col].value !== 0 && grid[0][col].value === grid[1][col].value && grid[1][col].value === grid[2][col].value) { winner = grid[0][col].value; winPositions = [{ row: 0, col: col }, { row: 1, col: col }, { row: 2, col: col }]; break; } } } // Check diagonals if (winner === 0) { if (grid[0][0].value !== 0 && grid[0][0].value === grid[1][1].value && grid[1][1].value === grid[2][2].value) { winner = grid[0][0].value; winPositions = [{ row: 0, col: 0 }, { row: 1, col: 1 }, { row: 2, col: 2 }]; } else if (grid[0][2].value !== 0 && grid[0][2].value === grid[1][1].value && grid[1][1].value === grid[2][0].value) { winner = grid[0][2].value; winPositions = [{ row: 0, col: 2 }, { row: 1, col: 1 }, { row: 2, col: 0 }]; } } if (winner !== 0) { gameOver = true; showWinner(winner, winPositions); return; } // Check for draw var isDraw = true; for (var r = 0; r < 3; r++) { for (var c = 0; c < 3; c++) { if (grid[r][c].value === 0) { isDraw = false; break; } } if (!isDraw) break; } if (isDraw) { gameOver = true; showDraw(); } } function showWinner(winner, positions) { LK.getSound('win').play(); var winnerText = winner === 1 ? languageTexts[currentLanguage].blueWin : languageTexts[currentLanguage].redWin; var winnerColor = 0x000000; // Black color statusText.setText(winnerText); statusText.fill = winnerColor; statusText.alpha = 1; blueTurnText.alpha = 0; redTurnText.alpha = 0; // Show win line winLine = gameBoard.addChild(new WinLine()); var startPos = grid[positions[0].row][positions[0].col]; var endPos = grid[positions[2].row][positions[2].col]; var lineColor = winner === 1 ? 0x00aaff : 0xff4444; winLine.showWinLine(startPos.x, startPos.y, endPos.x, endPos.y, lineColor); // Show play again button tween(playAgainBtn, { alpha: 1 }, { duration: 500 }); } function showDraw() { statusText.setText(languageTexts[currentLanguage].draw); statusText.fill = 0x000000; // Black color statusText.alpha = 1; blueTurnText.alpha = 0; redTurnText.alpha = 0; // Show play again button tween(playAgainBtn, { alpha: 1 }, { duration: 500 }); } function makeAIMove() { if (gameOver) return; // Variable thinking time to make AI feel more natural and less predictable var thinkingTime = 200 + Math.floor(Math.random() * 800); // 200-1000ms random delay // Use setTimeout to yield frame and prevent blocking LK.setTimeout(function () { // Simple AI strategy: try to win, block player, or play randomly var bestMove = findBestMove(); if (bestMove && bestMove.value === 0 && !bestMove.isPlayerReserved) { // Double check the cell is still valid before AI places marker if (bestMove.placeMarker(2)) { checkWin(); if (!gameOver) { currentPlayer = 1; updateTurnDisplay(); } } } }, thinkingTime); } function findBestMove() { var emptyCells = []; var winningMoves = []; var blockingMoves = []; var strategicMoves = []; var cornerCells = []; var edgeCells = []; var validCells = []; // Collect all valid empty cells for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { var cell = grid[row][col]; if (cell.value === 0 && !cell.isPlayerReserved) { emptyCells.push(cell); validCells.push(cell); // Categorize cell positions if ((row === 0 || row === 2) && (col === 0 || col === 2)) { cornerCells.push(cell); } else if (row === 1 && col === 1) { // Center cell - handled separately } else { edgeCells.push(cell); } } } } // Randomly select AI personality/strategy for this move var aiPersonality = Math.floor(Math.random() * 5); var randomnessFactor = Math.random(); // Priority 1: Check if AI can win immediately (always do this, but with some variation) for (var i = 0; i < emptyCells.length; i++) { var cell = emptyCells[i]; cell.value = 2; if (checkWinCondition(2)) { cell.value = 0; winningMoves.push(cell); } cell.value = 0; } // Sometimes make a suboptimal move instead of winning (5% chance for unpredictability) if (winningMoves.length > 0 && randomnessFactor > 0.05) { return winningMoves[Math.floor(Math.random() * winningMoves.length)]; } // Priority 2: Block player from winning (with some variation) for (var i = 0; i < emptyCells.length; i++) { var cell = emptyCells[i]; cell.value = 1; if (checkWinCondition(1)) { cell.value = 0; blockingMoves.push(cell); } cell.value = 0; } // Sometimes fail to block (10% chance for less predictable play) if (blockingMoves.length > 0 && randomnessFactor > 0.1) { return blockingMoves[Math.floor(Math.random() * blockingMoves.length)]; } // Priority 3: Different AI personalities with varying strategies var moveChoices = []; if (aiPersonality === 0) { // Aggressive corner player if (cornerCells.length > 0) { moveChoices = cornerCells.slice(); if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved && Math.random() < 0.3) { moveChoices.push(grid[1][1]); } } } else if (aiPersonality === 1) { // Center-focused player if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) { moveChoices.push(grid[1][1]); moveChoices.push(grid[1][1]); // Double weight for center } if (cornerCells.length > 0 && Math.random() < 0.4) { moveChoices.push(cornerCells[Math.floor(Math.random() * cornerCells.length)]); } } else if (aiPersonality === 2) { // Edge-preferring player (unusual strategy) if (edgeCells.length > 0) { moveChoices = edgeCells.slice(); } if (Math.random() < 0.3 && cornerCells.length > 0) { moveChoices.push(cornerCells[0]); } } else if (aiPersonality === 3) { // Anti-pattern player (opposite corner strategy) var hasOppositeCorner = false; if (grid[0][0].value === 1 && grid[2][2].value === 0 && !grid[2][2].isPlayerReserved) { moveChoices.push(grid[2][2]); hasOppositeCorner = true; } if (grid[0][2].value === 1 && grid[2][0].value === 0 && !grid[2][0].isPlayerReserved) { moveChoices.push(grid[2][0]); hasOppositeCorner = true; } if (grid[2][0].value === 1 && grid[0][2].value === 0 && !grid[0][2].isPlayerReserved) { moveChoices.push(grid[0][2]); hasOppositeCorner = true; } if (grid[2][2].value === 1 && grid[0][0].value === 0 && !grid[0][0].isPlayerReserved) { moveChoices.push(grid[0][0]); hasOppositeCorner = true; } if (!hasOppositeCorner) { // Fallback to center or corner if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) { moveChoices.push(grid[1][1]); } if (cornerCells.length > 0) { moveChoices.push(cornerCells[Math.floor(Math.random() * cornerCells.length)]); } } } else { // Random balanced player var choices = []; if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) { choices.push(grid[1][1]); } if (cornerCells.length > 0) { choices = choices.concat(cornerCells); } if (edgeCells.length > 0 && Math.random() < 0.3) { choices.push(edgeCells[Math.floor(Math.random() * edgeCells.length)]); } moveChoices = choices; } // Add some randomness to choices regardless of personality if (Math.random() < 0.15) { // 15% chance to add a completely random valid move if (validCells.length > 0) { moveChoices.push(validCells[Math.floor(Math.random() * validCells.length)]); } } // If we have strategic choices, pick randomly from them if (moveChoices.length > 0) { return moveChoices[Math.floor(Math.random() * moveChoices.length)]; } // Priority 4: Intelligent fallback with variation var fallbackChoices = []; var fallbackStrategy = Math.floor(Math.random() * 3); if (fallbackStrategy === 0) { // Corner-first strategy if (cornerCells.length > 0) { fallbackChoices = cornerCells.slice(); } if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved && Math.random() < 0.5) { fallbackChoices.push(grid[1][1]); } } else if (fallbackStrategy === 1) { // Center-first strategy if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) { fallbackChoices.push(grid[1][1]); } if (cornerCells.length > 0) { fallbackChoices = fallbackChoices.concat(cornerCells); } } else { // Mixed strategy if (cornerCells.length > 0) { fallbackChoices.push(cornerCells[Math.floor(Math.random() * cornerCells.length)]); } if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) { fallbackChoices.push(grid[1][1]); } if (edgeCells.length > 0 && Math.random() < 0.4) { fallbackChoices.push(edgeCells[Math.floor(Math.random() * edgeCells.length)]); } } // Final fallback: any valid cell if (fallbackChoices.length === 0) { fallbackChoices = validCells; } if (fallbackChoices.length > 0) { return fallbackChoices[Math.floor(Math.random() * fallbackChoices.length)]; } return null; } function checkWinCondition(player) { // Check rows for (var row = 0; row < 3; row++) { if (grid[row][0].value === player && grid[row][1].value === player && grid[row][2].value === player) { return true; } } // Check columns for (var col = 0; col < 3; col++) { if (grid[0][col].value === player && grid[1][col].value === player && grid[2][col].value === player) { return true; } } // Check diagonals if (grid[0][0].value === player && grid[1][1].value === player && grid[2][2].value === player) { return true; } if (grid[0][2].value === player && grid[1][1].value === player && grid[2][0].value === player) { return true; } return false; } function resetGame() { gameOver = false; // Start according to game mode if (gameMode === 'ai') { currentPlayer = 1; // Player always starts in AI mode isAIMode = true; } else if (gameMode === 'twoPlayer') { currentPlayer = Math.random() < 0.5 ? 1 : 2; isAIMode = false; } else { // Menu mode currentPlayer = 1; isAIMode = false; } // Clear grid for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { var cell = grid[row][col]; cell.value = 0; if (cell.marker) { cell.marker.destroy(); cell.marker = null; } } } // Clear UI statusText.setText(''); statusText.alpha = 0; playAgainBtn.alpha = 0; // Remove win line if (winLine) { // Reset line properties before destroying winLine.line.alpha = 0; winLine.line.scaleX = 0; winLine.destroy(); winLine = null; } updateTurnDisplay(); } // Save current version function function saveCurrentVersion() { storage.savedVersion = { timestamp: Date.now(), version: 'TicTacToe_TurkishEnglish_v1.0' }; } // Play again button handler playAgainBtn.down = function (x, y, obj) { if (gameOver) { resetGame(); } }; // Save the current version on game initialization saveCurrentVersion(); // Add small delay to prevent initial freeze when entering game var gameReady = false; LK.setTimeout(function () { gameReady = true; }, 50); // Reduced delay for better responsiveness
===================================================================
--- original.js
+++ change.js
@@ -510,8 +510,10 @@
});
}
function makeAIMove() {
if (gameOver) return;
+ // Variable thinking time to make AI feel more natural and less predictable
+ var thinkingTime = 200 + Math.floor(Math.random() * 800); // 200-1000ms random delay
// Use setTimeout to yield frame and prevent blocking
LK.setTimeout(function () {
// Simple AI strategy: try to win, block player, or play randomly
var bestMove = findBestMove();
@@ -524,9 +526,9 @@
updateTurnDisplay();
}
}
}
- }, 50); // Reduced from 100ms to 50ms for better responsiveness
+ }, thinkingTime);
}
function findBestMove() {
var emptyCells = [];
var winningMoves = [];
@@ -552,9 +554,12 @@
}
}
}
}
- // Priority 1: Check if AI can win immediately
+ // Randomly select AI personality/strategy for this move
+ var aiPersonality = Math.floor(Math.random() * 5);
+ var randomnessFactor = Math.random();
+ // Priority 1: Check if AI can win immediately (always do this, but with some variation)
for (var i = 0; i < emptyCells.length; i++) {
var cell = emptyCells[i];
cell.value = 2;
if (checkWinCondition(2)) {
@@ -562,13 +567,13 @@
winningMoves.push(cell);
}
cell.value = 0;
}
- // If we can win, do it (but add some randomness if multiple winning moves)
- if (winningMoves.length > 0) {
+ // Sometimes make a suboptimal move instead of winning (5% chance for unpredictability)
+ if (winningMoves.length > 0 && randomnessFactor > 0.05) {
return winningMoves[Math.floor(Math.random() * winningMoves.length)];
}
- // Priority 2: Block player from winning
+ // Priority 2: Block player from winning (with some variation)
for (var i = 0; i < emptyCells.length; i++) {
var cell = emptyCells[i];
cell.value = 1;
if (checkWinCondition(1)) {
@@ -576,63 +581,123 @@
blockingMoves.push(cell);
}
cell.value = 0;
}
- // If we need to block, do it (but add randomness if multiple blocking moves)
- if (blockingMoves.length > 0) {
+ // Sometimes fail to block (10% chance for less predictable play)
+ if (blockingMoves.length > 0 && randomnessFactor > 0.1) {
return blockingMoves[Math.floor(Math.random() * blockingMoves.length)];
}
- // Priority 3: Strategic moves with randomization
+ // Priority 3: Different AI personalities with varying strategies
var moveChoices = [];
- // Center is good if available (60% chance to prioritize)
- if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved && Math.random() < 0.6) {
- moveChoices.push(grid[1][1]);
- }
- // Corners are strategic (40% chance to prioritize over center)
- if (cornerCells.length > 0 && Math.random() < 0.4) {
- // Add some corners to choices
- for (var i = 0; i < cornerCells.length && i < 2; i++) {
- moveChoices.push(cornerCells[i]);
+ if (aiPersonality === 0) {
+ // Aggressive corner player
+ if (cornerCells.length > 0) {
+ moveChoices = cornerCells.slice();
+ if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved && Math.random() < 0.3) {
+ moveChoices.push(grid[1][1]);
+ }
}
- }
- // Sometimes prefer opposite corner strategy
- if (cornerCells.length > 0) {
- // If player took a corner, sometimes take opposite corner
+ } else if (aiPersonality === 1) {
+ // Center-focused player
+ if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) {
+ moveChoices.push(grid[1][1]);
+ moveChoices.push(grid[1][1]); // Double weight for center
+ }
+ if (cornerCells.length > 0 && Math.random() < 0.4) {
+ moveChoices.push(cornerCells[Math.floor(Math.random() * cornerCells.length)]);
+ }
+ } else if (aiPersonality === 2) {
+ // Edge-preferring player (unusual strategy)
+ if (edgeCells.length > 0) {
+ moveChoices = edgeCells.slice();
+ }
+ if (Math.random() < 0.3 && cornerCells.length > 0) {
+ moveChoices.push(cornerCells[0]);
+ }
+ } else if (aiPersonality === 3) {
+ // Anti-pattern player (opposite corner strategy)
+ var hasOppositeCorner = false;
if (grid[0][0].value === 1 && grid[2][2].value === 0 && !grid[2][2].isPlayerReserved) {
moveChoices.push(grid[2][2]);
+ hasOppositeCorner = true;
}
if (grid[0][2].value === 1 && grid[2][0].value === 0 && !grid[2][0].isPlayerReserved) {
moveChoices.push(grid[2][0]);
+ hasOppositeCorner = true;
}
if (grid[2][0].value === 1 && grid[0][2].value === 0 && !grid[0][2].isPlayerReserved) {
moveChoices.push(grid[0][2]);
+ hasOppositeCorner = true;
}
if (grid[2][2].value === 1 && grid[0][0].value === 0 && !grid[0][0].isPlayerReserved) {
moveChoices.push(grid[0][0]);
+ hasOppositeCorner = true;
}
+ if (!hasOppositeCorner) {
+ // Fallback to center or corner
+ if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) {
+ moveChoices.push(grid[1][1]);
+ }
+ if (cornerCells.length > 0) {
+ moveChoices.push(cornerCells[Math.floor(Math.random() * cornerCells.length)]);
+ }
+ }
+ } else {
+ // Random balanced player
+ var choices = [];
+ if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) {
+ choices.push(grid[1][1]);
+ }
+ if (cornerCells.length > 0) {
+ choices = choices.concat(cornerCells);
+ }
+ if (edgeCells.length > 0 && Math.random() < 0.3) {
+ choices.push(edgeCells[Math.floor(Math.random() * edgeCells.length)]);
+ }
+ moveChoices = choices;
}
+ // Add some randomness to choices regardless of personality
+ if (Math.random() < 0.15) {
+ // 15% chance to add a completely random valid move
+ if (validCells.length > 0) {
+ moveChoices.push(validCells[Math.floor(Math.random() * validCells.length)]);
+ }
+ }
// If we have strategic choices, pick randomly from them
if (moveChoices.length > 0) {
return moveChoices[Math.floor(Math.random() * moveChoices.length)];
}
- // Priority 4: Fallback - corners first, then edges, with randomization
+ // Priority 4: Intelligent fallback with variation
var fallbackChoices = [];
- // Add corners with higher probability
- if (cornerCells.length > 0) {
- fallbackChoices = fallbackChoices.concat(cornerCells);
- // Add corners again to increase their probability
- if (cornerCells.length > 1) {
- fallbackChoices.push(cornerCells[0]);
+ var fallbackStrategy = Math.floor(Math.random() * 3);
+ if (fallbackStrategy === 0) {
+ // Corner-first strategy
+ if (cornerCells.length > 0) {
+ fallbackChoices = cornerCells.slice();
}
+ if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved && Math.random() < 0.5) {
+ fallbackChoices.push(grid[1][1]);
+ }
+ } else if (fallbackStrategy === 1) {
+ // Center-first strategy
+ if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) {
+ fallbackChoices.push(grid[1][1]);
+ }
+ if (cornerCells.length > 0) {
+ fallbackChoices = fallbackChoices.concat(cornerCells);
+ }
+ } else {
+ // Mixed strategy
+ if (cornerCells.length > 0) {
+ fallbackChoices.push(cornerCells[Math.floor(Math.random() * cornerCells.length)]);
+ }
+ if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) {
+ fallbackChoices.push(grid[1][1]);
+ }
+ if (edgeCells.length > 0 && Math.random() < 0.4) {
+ fallbackChoices.push(edgeCells[Math.floor(Math.random() * edgeCells.length)]);
+ }
}
- // Add center if still available
- if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) {
- fallbackChoices.push(grid[1][1]);
- }
- // Add some edges
- if (edgeCells.length > 0) {
- fallbackChoices.push(edgeCells[Math.floor(Math.random() * edgeCells.length)]);
- }
// Final fallback: any valid cell
if (fallbackChoices.length === 0) {
fallbackChoices = validCells;
}