User prompt
Aİcevap hızını yavaşlat
User prompt
325 adlı müzik arkada sürekli olarak tekrar etsin
User prompt
arkada neşeli bir müzik çalsın sosuz
Code edit (1 edits merged)
Please save this source code
User prompt
sıra:Kırmızının yazısını sıra:O'nun diye değiştir
User prompt
sıra:Mavinin yazısını Sıra:X'in diye değiştir
Remix started
Copy Tic Tac Toe
/**** * 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; // 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(); } } } }, 50); // Reduced from 100ms to 50ms for better responsiveness } function findBestMove() { var emptyCells = []; // First pass: collect empty cells and check for immediate win/block opportunities for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { var cell = grid[row][col]; // Only consider cells that are empty and not reserved by player if (cell.value === 0 && !cell.isPlayerReserved) { emptyCells.push(cell); // Check if AI can win immediately cell.value = 2; if (checkWinCondition(2)) { cell.value = 0; return cell; } cell.value = 0; } } } // Second pass: check if AI needs to block player (only if no winning move found) for (var i = 0; i < emptyCells.length; i++) { var cell = emptyCells[i]; // Double check cell is still valid and not reserved if (cell.value === 0 && !cell.isPlayerReserved) { cell.value = 1; if (checkWinCondition(1)) { cell.value = 0; return cell; } cell.value = 0; } } // Play center if available and not reserved if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) { return grid[1][1]; } // Play randomly from available cells that are not reserved var validCells = []; for (var i = 0; i < emptyCells.length; i++) { if (!emptyCells[i].isPlayerReserved) { validCells.push(emptyCells[i]); } } if (validCells.length > 0) { return validCells[Math.floor(Math.random() * validCells.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
/****
* 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;
// 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();
}
}
}
}, 50); // Reduced from 100ms to 50ms for better responsiveness
}
function findBestMove() {
var emptyCells = [];
// First pass: collect empty cells and check for immediate win/block opportunities
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 3; col++) {
var cell = grid[row][col];
// Only consider cells that are empty and not reserved by player
if (cell.value === 0 && !cell.isPlayerReserved) {
emptyCells.push(cell);
// Check if AI can win immediately
cell.value = 2;
if (checkWinCondition(2)) {
cell.value = 0;
return cell;
}
cell.value = 0;
}
}
}
// Second pass: check if AI needs to block player (only if no winning move found)
for (var i = 0; i < emptyCells.length; i++) {
var cell = emptyCells[i];
// Double check cell is still valid and not reserved
if (cell.value === 0 && !cell.isPlayerReserved) {
cell.value = 1;
if (checkWinCondition(1)) {
cell.value = 0;
return cell;
}
cell.value = 0;
}
}
// Play center if available and not reserved
if (grid[1][1].value === 0 && !grid[1][1].isPlayerReserved) {
return grid[1][1];
}
// Play randomly from available cells that are not reserved
var validCells = [];
for (var i = 0; i < emptyCells.length; i++) {
if (!emptyCells[i].isPlayerReserved) {
validCells.push(emptyCells[i]);
}
}
if (validCells.length > 0) {
return validCells[Math.floor(Math.random() * validCells.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