/**** * 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, 2 = O var background = self.attachAsset('cellBackground', { anchorX: 0.5, anchorY: 0.5 }); var symbol = null; self.placeSymbol = function (playerSymbol) { if (self.value !== 0) return false; self.value = playerSymbol; if (playerSymbol === 1) { symbol = self.attachAsset('xSymbol', { anchorX: 0.5, anchorY: 0.5, scaleX: 0, scaleY: 0 }); } else { symbol = self.attachAsset('oSymbol', { anchorX: 0.5, anchorY: 0.5, scaleX: 0, scaleY: 0 }); } tween(symbol, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.elasticOut }); LK.getSound('placeSymbol').play(); return true; }; self.down = function (x, y, obj) { if (gameState === 'playing' && currentPlayer === 1 && self.value === 0) { if (self.placeSymbol(1)) { currentPlayer = 2; checkGameEnd(); if (gameState === 'playing') { LK.setTimeout(function () { aiMove(); }, 500); } } } }; return self; }); var GameBoard = Container.expand(function () { var self = Container.call(this); self.cells = []; self.winLine = null; // Create 3x3 grid for (var row = 0; row < 3; row++) { self.cells[row] = []; for (var col = 0; col < 3; col++) { var cell = new Cell(row, col); cell.x = (col - 1) * 220; cell.y = (row - 1) * 220; self.cells[row][col] = cell; self.addChild(cell); } } // Create grid lines // Vertical lines for (var i = 0; i < 2; i++) { var vLine = self.attachAsset('gridLine', { anchorX: 0.5, anchorY: 0.5, x: (i - 0.5) * 220, y: 0 }); } // Horizontal lines for (var i = 0; i < 2; i++) { var hLine = self.attachAsset('gridLine', { anchorX: 0.5, anchorY: 0.5, x: 0, y: (i - 0.5) * 220, rotation: Math.PI / 2 }); } self.getCell = function (row, col) { return self.cells[row][col]; }; self.getBoardState = function () { var state = []; for (var row = 0; row < 3; row++) { state[row] = []; for (var col = 0; col < 3; col++) { state[row][col] = self.cells[row][col].value; } } return state; }; self.checkWin = function (player) { var board = self.getBoardState(); // Check rows for (var row = 0; row < 3; row++) { if (board[row][0] === player && board[row][1] === player && board[row][2] === player) { return { type: 'row', index: row }; } } // Check columns for (var col = 0; col < 3; col++) { if (board[0][col] === player && board[1][col] === player && board[2][col] === player) { return { type: 'col', index: col }; } } // Check diagonals if (board[0][0] === player && board[1][1] === player && board[2][2] === player) { return { type: 'diag', index: 0 }; } if (board[0][2] === player && board[1][1] === player && board[2][0] === player) { return { type: 'diag', index: 1 }; } return null; }; self.isBoardFull = function () { var board = self.getBoardState(); for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { if (board[row][col] === 0) return false; } } return true; }; self.showWinLine = function (winInfo) { self.winLine = self.attachAsset('winLine', { anchorX: 0.5, anchorY: 0.5, scaleX: 0, alpha: 0.8 }); if (winInfo.type === 'row') { self.winLine.x = 0; self.winLine.y = (winInfo.index - 1) * 220; self.winLine.rotation = 0; } else if (winInfo.type === 'col') { self.winLine.x = (winInfo.index - 1) * 220; self.winLine.y = 0; self.winLine.rotation = Math.PI / 2; } else if (winInfo.type === 'diag') { self.winLine.x = 0; self.winLine.y = 0; if (winInfo.index === 0) { self.winLine.rotation = Math.PI / 4; self.winLine.width = 650; } else { self.winLine.rotation = -Math.PI / 4; self.winLine.width = 650; } } tween(self.winLine, { scaleX: 1 }, { duration: 500, easing: tween.easeOut }); }; self.reset = function () { for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { var cell = self.cells[row][col]; cell.value = 0; if (cell.children.length > 1) { cell.removeChild(cell.children[cell.children.length - 1]); } } } if (self.winLine) { self.removeChild(self.winLine); self.winLine = null; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xF5F5F5 }); /**** * Game Code ****/ var gameBoard = null; var gameState = 'playing'; // 'playing', 'won', 'lost', 'draw' var currentPlayer = 1; // 1 = X (human), 2 = O (AI) // Score tracking var wins = storage.wins || 0; var losses = storage.losses || 0; var draws = storage.draws || 0; // UI Elements var statusText = new Text2('Your Turn (X)', { size: 80, fill: 0x333333 }); statusText.anchor.set(0.5, 0); LK.gui.top.addChild(statusText); statusText.y = 150; var scoreText = new Text2('Wins: ' + wins + ' | Losses: ' + losses + ' | Draws: ' + draws, { size: 50, fill: 0x666666 }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); scoreText.y = 250; var restartButton = new Text2('Play Again', { size: 60, fill: 0x4CAF50 }); restartButton.anchor.set(0.5, 1); LK.gui.bottom.addChild(restartButton); restartButton.y = -100; restartButton.alpha = 0; // Initialize game board gameBoard = new GameBoard(); gameBoard.x = 2048 / 2; gameBoard.y = 2732 / 2; game.addChild(gameBoard); function checkGameEnd() { var playerWin = gameBoard.checkWin(1); var aiWin = gameBoard.checkWin(2); if (playerWin) { gameState = 'won'; statusText.setText('You Win!'); gameBoard.showWinLine(playerWin); wins++; storage.wins = wins; LK.getSound('gameWin').play(); showRestartButton(); } else if (aiWin) { gameState = 'lost'; statusText.setText('AI Wins!'); gameBoard.showWinLine(aiWin); losses++; storage.losses = losses; LK.getSound('gameLose').play(); showRestartButton(); } else if (gameBoard.isBoardFull()) { gameState = 'draw'; statusText.setText('Draw!'); draws++; storage.draws = draws; LK.getSound('gameDraw').play(); showRestartButton(); } if (gameState !== 'playing') { scoreText.setText('Wins: ' + wins + ' | Losses: ' + losses + ' | Draws: ' + draws); } } function showRestartButton() { tween(restartButton, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); } function minimax(board, depth, isMaximizing) { var aiWin = checkWinOnBoard(board, 2); var playerWin = checkWinOnBoard(board, 1); if (aiWin) return 10 - depth; if (playerWin) return depth - 10; if (isBoardFullArray(board)) return 0; if (isMaximizing) { var bestScore = -1000; for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { if (board[row][col] === 0) { board[row][col] = 2; var score = minimax(board, depth + 1, false); board[row][col] = 0; if (score > bestScore) { bestScore = score; } } } } return bestScore; } else { var bestScore = 1000; for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { if (board[row][col] === 0) { board[row][col] = 1; var score = minimax(board, depth + 1, true); board[row][col] = 0; if (score < bestScore) { bestScore = score; } } } } return bestScore; } } function checkWinOnBoard(board, player) { // Check rows for (var row = 0; row < 3; row++) { if (board[row][0] === player && board[row][1] === player && board[row][2] === player) { return true; } } // Check columns for (var col = 0; col < 3; col++) { if (board[0][col] === player && board[1][col] === player && board[2][col] === player) { return true; } } // Check diagonals if (board[0][0] === player && board[1][1] === player && board[2][2] === player) { return true; } if (board[0][2] === player && board[1][1] === player && board[2][0] === player) { return true; } return false; } function isBoardFullArray(board) { for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { if (board[row][col] === 0) return false; } } return true; } function aiMove() { if (gameState !== 'playing' || currentPlayer !== 2) return; var board = gameBoard.getBoardState(); var bestScore = -1000; var bestMove = null; for (var row = 0; row < 3; row++) { for (var col = 0; col < 3; col++) { if (board[row][col] === 0) { board[row][col] = 2; var score = minimax(board, 0, false); board[row][col] = 0; if (score > bestScore) { bestScore = score; bestMove = { row: row, col: col }; } } } } if (bestMove) { var cell = gameBoard.getCell(bestMove.row, bestMove.col); cell.placeSymbol(2); currentPlayer = 1; checkGameEnd(); if (gameState === 'playing') { statusText.setText('Your Turn (X)'); } } } function resetGame() { gameBoard.reset(); gameState = 'playing'; currentPlayer = 1; statusText.setText('Your Turn (X)'); tween(restartButton, { alpha: 0 }, { duration: 300, easing: tween.easeIn }); } restartButton.down = function (x, y, obj) { if (gameState !== 'playing') { resetGame(); } }; game.update = function () { if (gameState === 'playing' && currentPlayer === 1) { statusText.setText('Your Turn (X)'); } else if (gameState === 'playing' && currentPlayer === 2) { statusText.setText('AI Turn (O)'); } };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,412 @@
-/****
+/****
+* 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, 2 = O
+ var background = self.attachAsset('cellBackground', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var symbol = null;
+ self.placeSymbol = function (playerSymbol) {
+ if (self.value !== 0) return false;
+ self.value = playerSymbol;
+ if (playerSymbol === 1) {
+ symbol = self.attachAsset('xSymbol', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0,
+ scaleY: 0
+ });
+ } else {
+ symbol = self.attachAsset('oSymbol', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0,
+ scaleY: 0
+ });
+ }
+ tween(symbol, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 300,
+ easing: tween.elasticOut
+ });
+ LK.getSound('placeSymbol').play();
+ return true;
+ };
+ self.down = function (x, y, obj) {
+ if (gameState === 'playing' && currentPlayer === 1 && self.value === 0) {
+ if (self.placeSymbol(1)) {
+ currentPlayer = 2;
+ checkGameEnd();
+ if (gameState === 'playing') {
+ LK.setTimeout(function () {
+ aiMove();
+ }, 500);
+ }
+ }
+ }
+ };
+ return self;
+});
+var GameBoard = Container.expand(function () {
+ var self = Container.call(this);
+ self.cells = [];
+ self.winLine = null;
+ // Create 3x3 grid
+ for (var row = 0; row < 3; row++) {
+ self.cells[row] = [];
+ for (var col = 0; col < 3; col++) {
+ var cell = new Cell(row, col);
+ cell.x = (col - 1) * 220;
+ cell.y = (row - 1) * 220;
+ self.cells[row][col] = cell;
+ self.addChild(cell);
+ }
+ }
+ // Create grid lines
+ // Vertical lines
+ for (var i = 0; i < 2; i++) {
+ var vLine = self.attachAsset('gridLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: (i - 0.5) * 220,
+ y: 0
+ });
+ }
+ // Horizontal lines
+ for (var i = 0; i < 2; i++) {
+ var hLine = self.attachAsset('gridLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: (i - 0.5) * 220,
+ rotation: Math.PI / 2
+ });
+ }
+ self.getCell = function (row, col) {
+ return self.cells[row][col];
+ };
+ self.getBoardState = function () {
+ var state = [];
+ for (var row = 0; row < 3; row++) {
+ state[row] = [];
+ for (var col = 0; col < 3; col++) {
+ state[row][col] = self.cells[row][col].value;
+ }
+ }
+ return state;
+ };
+ self.checkWin = function (player) {
+ var board = self.getBoardState();
+ // Check rows
+ for (var row = 0; row < 3; row++) {
+ if (board[row][0] === player && board[row][1] === player && board[row][2] === player) {
+ return {
+ type: 'row',
+ index: row
+ };
+ }
+ }
+ // Check columns
+ for (var col = 0; col < 3; col++) {
+ if (board[0][col] === player && board[1][col] === player && board[2][col] === player) {
+ return {
+ type: 'col',
+ index: col
+ };
+ }
+ }
+ // Check diagonals
+ if (board[0][0] === player && board[1][1] === player && board[2][2] === player) {
+ return {
+ type: 'diag',
+ index: 0
+ };
+ }
+ if (board[0][2] === player && board[1][1] === player && board[2][0] === player) {
+ return {
+ type: 'diag',
+ index: 1
+ };
+ }
+ return null;
+ };
+ self.isBoardFull = function () {
+ var board = self.getBoardState();
+ for (var row = 0; row < 3; row++) {
+ for (var col = 0; col < 3; col++) {
+ if (board[row][col] === 0) return false;
+ }
+ }
+ return true;
+ };
+ self.showWinLine = function (winInfo) {
+ self.winLine = self.attachAsset('winLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0,
+ alpha: 0.8
+ });
+ if (winInfo.type === 'row') {
+ self.winLine.x = 0;
+ self.winLine.y = (winInfo.index - 1) * 220;
+ self.winLine.rotation = 0;
+ } else if (winInfo.type === 'col') {
+ self.winLine.x = (winInfo.index - 1) * 220;
+ self.winLine.y = 0;
+ self.winLine.rotation = Math.PI / 2;
+ } else if (winInfo.type === 'diag') {
+ self.winLine.x = 0;
+ self.winLine.y = 0;
+ if (winInfo.index === 0) {
+ self.winLine.rotation = Math.PI / 4;
+ self.winLine.width = 650;
+ } else {
+ self.winLine.rotation = -Math.PI / 4;
+ self.winLine.width = 650;
+ }
+ }
+ tween(self.winLine, {
+ scaleX: 1
+ }, {
+ duration: 500,
+ easing: tween.easeOut
+ });
+ };
+ self.reset = function () {
+ for (var row = 0; row < 3; row++) {
+ for (var col = 0; col < 3; col++) {
+ var cell = self.cells[row][col];
+ cell.value = 0;
+ if (cell.children.length > 1) {
+ cell.removeChild(cell.children[cell.children.length - 1]);
+ }
+ }
+ }
+ if (self.winLine) {
+ self.removeChild(self.winLine);
+ self.winLine = null;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0xF5F5F5
+});
+
+/****
+* Game Code
+****/
+var gameBoard = null;
+var gameState = 'playing'; // 'playing', 'won', 'lost', 'draw'
+var currentPlayer = 1; // 1 = X (human), 2 = O (AI)
+// Score tracking
+var wins = storage.wins || 0;
+var losses = storage.losses || 0;
+var draws = storage.draws || 0;
+// UI Elements
+var statusText = new Text2('Your Turn (X)', {
+ size: 80,
+ fill: 0x333333
+});
+statusText.anchor.set(0.5, 0);
+LK.gui.top.addChild(statusText);
+statusText.y = 150;
+var scoreText = new Text2('Wins: ' + wins + ' | Losses: ' + losses + ' | Draws: ' + draws, {
+ size: 50,
+ fill: 0x666666
+});
+scoreText.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreText);
+scoreText.y = 250;
+var restartButton = new Text2('Play Again', {
+ size: 60,
+ fill: 0x4CAF50
+});
+restartButton.anchor.set(0.5, 1);
+LK.gui.bottom.addChild(restartButton);
+restartButton.y = -100;
+restartButton.alpha = 0;
+// Initialize game board
+gameBoard = new GameBoard();
+gameBoard.x = 2048 / 2;
+gameBoard.y = 2732 / 2;
+game.addChild(gameBoard);
+function checkGameEnd() {
+ var playerWin = gameBoard.checkWin(1);
+ var aiWin = gameBoard.checkWin(2);
+ if (playerWin) {
+ gameState = 'won';
+ statusText.setText('You Win!');
+ gameBoard.showWinLine(playerWin);
+ wins++;
+ storage.wins = wins;
+ LK.getSound('gameWin').play();
+ showRestartButton();
+ } else if (aiWin) {
+ gameState = 'lost';
+ statusText.setText('AI Wins!');
+ gameBoard.showWinLine(aiWin);
+ losses++;
+ storage.losses = losses;
+ LK.getSound('gameLose').play();
+ showRestartButton();
+ } else if (gameBoard.isBoardFull()) {
+ gameState = 'draw';
+ statusText.setText('Draw!');
+ draws++;
+ storage.draws = draws;
+ LK.getSound('gameDraw').play();
+ showRestartButton();
+ }
+ if (gameState !== 'playing') {
+ scoreText.setText('Wins: ' + wins + ' | Losses: ' + losses + ' | Draws: ' + draws);
+ }
+}
+function showRestartButton() {
+ tween(restartButton, {
+ alpha: 1
+ }, {
+ duration: 500,
+ easing: tween.easeOut
+ });
+}
+function minimax(board, depth, isMaximizing) {
+ var aiWin = checkWinOnBoard(board, 2);
+ var playerWin = checkWinOnBoard(board, 1);
+ if (aiWin) return 10 - depth;
+ if (playerWin) return depth - 10;
+ if (isBoardFullArray(board)) return 0;
+ if (isMaximizing) {
+ var bestScore = -1000;
+ for (var row = 0; row < 3; row++) {
+ for (var col = 0; col < 3; col++) {
+ if (board[row][col] === 0) {
+ board[row][col] = 2;
+ var score = minimax(board, depth + 1, false);
+ board[row][col] = 0;
+ if (score > bestScore) {
+ bestScore = score;
+ }
+ }
+ }
+ }
+ return bestScore;
+ } else {
+ var bestScore = 1000;
+ for (var row = 0; row < 3; row++) {
+ for (var col = 0; col < 3; col++) {
+ if (board[row][col] === 0) {
+ board[row][col] = 1;
+ var score = minimax(board, depth + 1, true);
+ board[row][col] = 0;
+ if (score < bestScore) {
+ bestScore = score;
+ }
+ }
+ }
+ }
+ return bestScore;
+ }
+}
+function checkWinOnBoard(board, player) {
+ // Check rows
+ for (var row = 0; row < 3; row++) {
+ if (board[row][0] === player && board[row][1] === player && board[row][2] === player) {
+ return true;
+ }
+ }
+ // Check columns
+ for (var col = 0; col < 3; col++) {
+ if (board[0][col] === player && board[1][col] === player && board[2][col] === player) {
+ return true;
+ }
+ }
+ // Check diagonals
+ if (board[0][0] === player && board[1][1] === player && board[2][2] === player) {
+ return true;
+ }
+ if (board[0][2] === player && board[1][1] === player && board[2][0] === player) {
+ return true;
+ }
+ return false;
+}
+function isBoardFullArray(board) {
+ for (var row = 0; row < 3; row++) {
+ for (var col = 0; col < 3; col++) {
+ if (board[row][col] === 0) return false;
+ }
+ }
+ return true;
+}
+function aiMove() {
+ if (gameState !== 'playing' || currentPlayer !== 2) return;
+ var board = gameBoard.getBoardState();
+ var bestScore = -1000;
+ var bestMove = null;
+ for (var row = 0; row < 3; row++) {
+ for (var col = 0; col < 3; col++) {
+ if (board[row][col] === 0) {
+ board[row][col] = 2;
+ var score = minimax(board, 0, false);
+ board[row][col] = 0;
+ if (score > bestScore) {
+ bestScore = score;
+ bestMove = {
+ row: row,
+ col: col
+ };
+ }
+ }
+ }
+ }
+ if (bestMove) {
+ var cell = gameBoard.getCell(bestMove.row, bestMove.col);
+ cell.placeSymbol(2);
+ currentPlayer = 1;
+ checkGameEnd();
+ if (gameState === 'playing') {
+ statusText.setText('Your Turn (X)');
+ }
+ }
+}
+function resetGame() {
+ gameBoard.reset();
+ gameState = 'playing';
+ currentPlayer = 1;
+ statusText.setText('Your Turn (X)');
+ tween(restartButton, {
+ alpha: 0
+ }, {
+ duration: 300,
+ easing: tween.easeIn
+ });
+}
+restartButton.down = function (x, y, obj) {
+ if (gameState !== 'playing') {
+ resetGame();
+ }
+};
+game.update = function () {
+ if (gameState === 'playing' && currentPlayer === 1) {
+ statusText.setText('Your Turn (X)');
+ } else if (gameState === 'playing' && currentPlayer === 2) {
+ statusText.setText('AI Turn (O)');
+ }
+};
\ No newline at end of file