/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { gameHistory: [], stats: { wins: 0, losses: 0, draws: 0 } }); /**** * Classes ****/ var Button = Container.expand(function () { var self = Container.call(this); self.init = function (text, width, height, color) { self.background = self.attachAsset('whiteSquare', { anchorX: 0, anchorY: 0, width: width, height: height, tint: color || 0x4488FF }); self.label = new Text2(text, { size: 50, //{e} // Increased text size fill: 0xFFFFFF }); self.label.anchor.set(0.5, 0.5); self.label.x = width / 2; self.label.y = height / 2; self.addChild(self.label); return self; }; self.setEnabled = function (enabled) { self.enabled = enabled; self.background.alpha = enabled ? 1 : 0.5; }; self.down = function (x, y, obj) { if (self.enabled !== false) { LK.getSound('movePiece').play(); tween(self, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); } }; self.up = function (x, y, obj) { if (self.enabled !== false) { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100, onFinish: function onFinish() { if (self.onClick) { self.onClick(); } } }); } }; return self; }); var ChessGame = Container.expand(function () { var self = Container.call(this); // Game state self.board = []; self.selectedSquare = null; self.possibleMoves = []; self.currentPlayer = 'white'; self.gameOver = false; self.moveHistory = []; self.lastMovedPiece = null; self.lastMoveFrom = null; self.lastMoveTo = null; self.inCheck = { white: false, black: false }; self.init = function () { self.initializeBoard(); self.setupPieces(); self.createControls(); return self; }; self.initializeBoard = function () { for (var row = 0; row < 8; row++) { self.board[row] = []; for (var col = 0; col < 8; col++) { var color = (row + col) % 2 === 0 ? 'white' : 'black'; var square = new ChessSquare().init(row, col, color); square.x = col * SQUARE_SIZE; square.y = row * SQUARE_SIZE; self.addChild(square); self.board[row][col] = square; } } }; self.setupPieces = function () { // Place pawns for (var col = 0; col < 8; col++) { self.placePiece('pawn', 'white', 6, col); self.placePiece('pawn', 'black', 1, col); } // Place rooks self.placePiece('rook', 'white', 7, 0); self.placePiece('rook', 'white', 7, 7); self.placePiece('rook', 'black', 0, 0); self.placePiece('rook', 'black', 0, 7); // Place knights self.placePiece('knight', 'white', 7, 1); self.placePiece('knight', 'white', 7, 6); self.placePiece('knight', 'black', 0, 1); self.placePiece('knight', 'black', 0, 6); // Place bishops self.placePiece('bishop', 'white', 7, 2); self.placePiece('bishop', 'white', 7, 5); self.placePiece('bishop', 'black', 0, 2); self.placePiece('bishop', 'black', 0, 5); // Place queens self.placePiece('queen', 'white', 7, 3); self.placePiece('queen', 'black', 0, 3); // Place kings self.placePiece('king', 'white', 7, 4); self.placePiece('king', 'black', 0, 4); }; self.createControls = function () { // Undo button self.undoButton = new Button().init("UNDO", 250, 100); // Increased button size self.undoButton.x = BOARD_SIZE / 2 - 270; // Positioned to left of center self.undoButton.y = BOARD_SIZE + 200; // Below indicators self.addChild(self.undoButton); self.undoButton.onClick = function () { self.undoLastMove(); }; self.undoButton.setEnabled(false); // Reset button self.resetButton = new Button().init("RESET", 250, 100); // Increased button size self.resetButton.x = BOARD_SIZE / 2 + 20; // Positioned to right of center self.resetButton.y = BOARD_SIZE + 200; // Below indicators self.addChild(self.resetButton); self.resetButton.onClick = function () { self.resetGame(); }; // Turn indicator self.turnIndicator = new Text2("White's Turn", { size: 60, //{13} // Increased text size fill: 0xFFFFFF }); self.turnIndicator.x = BOARD_SIZE / 2; // Center horizontally on board self.turnIndicator.y = BOARD_SIZE + 50; // Below board self.turnIndicator.anchor.set(0.5, 0); self.addChild(self.turnIndicator); // Check indicator self.checkIndicator = new Text2("", { size: 60, //{16} // Increased text size fill: 0xFF0000 }); self.checkIndicator.x = BOARD_SIZE / 2; // Center horizontally on board self.checkIndicator.y = BOARD_SIZE + 120; // Below turn indicator self.checkIndicator.anchor.set(0.5, 0); self.addChild(self.checkIndicator); }; self.placePiece = function (type, color, row, col) { var piece = new ChessPiece().init(type, color); self.board[row][col].setPiece(piece); }; self.squareClicked = function (square) { if (self.gameOver || self.currentPlayer === 'black' && AI_ENABLED) return; if (self.selectedSquare) { // If selected square is clicked again, deselect it if (self.selectedSquare === square) { self.clearSelection(); return; } // Check if clicked square is a possible move if (self.isPossibleMove(square)) { self.movePiece(self.selectedSquare, square); return; } } // Check if square has a piece of current player's color if (square.piece && square.piece.color === self.currentPlayer) { self.selectSquare(square); } }; self.selectSquare = function (square) { self.clearSelection(); self.selectedSquare = square; square.setSelected(true); self.possibleMoves = self.calculatePossibleMoves(square); // Highlight possible moves for (var i = 0; i < self.possibleMoves.length; i++) { var move = self.possibleMoves[i]; self.board[move.row][move.col].setHighlight(true); } }; self.clearSelection = function () { if (self.selectedSquare) { self.selectedSquare.setSelected(false); self.selectedSquare = null; } // Clear highlights for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { self.board[row][col].setHighlight(false); } } self.possibleMoves = []; }; self.isPossibleMove = function (square) { for (var i = 0; i < self.possibleMoves.length; i++) { var move = self.possibleMoves[i]; if (move.row === square.row && move.col === square.col) { return true; } } return false; }; self.movePiece = function (fromSquare, toSquare) { var piece = fromSquare.piece; var capturedPiece = toSquare.piece; var moveRecord = { piece: piece, from: { row: fromSquare.row, col: fromSquare.col }, to: { row: toSquare.row, col: toSquare.col }, captured: capturedPiece, firstMove: !piece.hasMoved, isCheck: false }; // Clear any previous 'last move' highlights if (self.lastMoveFrom) { self.lastMoveFrom.setLastMove(false); } if (self.lastMoveTo) { self.lastMoveTo.setLastMove(false); } // Handle castling var isCastling = piece.type === 'king' && Math.abs(fromSquare.col - toSquare.col) === 2; if (isCastling) { var rookCol = toSquare.col === 6 ? 7 : 0; var newRookCol = toSquare.col === 6 ? 5 : 3; var rookSquare = self.board[fromSquare.row][rookCol]; var rook = rookSquare.piece; moveRecord.castling = { rook: rook, from: { row: fromSquare.row, col: rookCol }, to: { row: fromSquare.row, col: newRookCol } }; // Move the rook rookSquare.setPiece(null); self.board[fromSquare.row][newRookCol].setPiece(rook); rook.hasMoved = true; LK.getSound('castle').play(); } else if (capturedPiece) { LK.getSound('capture').play(); } else { LK.getSound('movePiece').play(); } // Handle pawn promotion if (piece.type === 'pawn' && (toSquare.row === 0 || toSquare.row === 7)) { // Clear the source square first fromSquare.setPiece(null); // Create new queen var newQueen = new ChessPiece().init('queen', piece.color); // Place the queen on the destination square toSquare.setPiece(newQueen); moveRecord.promotion = { from: 'pawn', to: 'queen' }; piece = newQueen; } else { // Move the piece fromSquare.setPiece(null); toSquare.setPiece(piece); } // Mark the piece as moved piece.hasMoved = true; // Record the last move for highlighting self.lastMoveFrom = fromSquare; self.lastMoveTo = toSquare; fromSquare.setLastMove(true); toSquare.setLastMove(true); // Add move to history self.moveHistory.push(moveRecord); // Clear selection self.clearSelection(); // Switch player self.currentPlayer = self.currentPlayer === 'white' ? 'black' : 'white'; self.turnIndicator.setText("MissPiece's Turn"); // Check for check or checkmate self.checkForCheckAndMate(); // Update undo button state self.undoButton.setEnabled(self.moveHistory.length > 0); // If AI is enabled and it's black's turn, make AI move if (AI_ENABLED && self.currentPlayer === 'black' && !self.gameOver) { LK.setTimeout(function () { self.makeAIMove(); }, 500); } }; self.checkForCheckAndMate = function () { // Check if current player is in check var isInCheck = self.isPlayerInCheck(self.currentPlayer); self.inCheck[self.currentPlayer] = isInCheck; if (isInCheck) { // Check if it's checkmate var hasLegalMoves = self.playerHasLegalMoves(self.currentPlayer); if (!hasLegalMoves) { // Checkmate self.gameOver = true; self.checkIndicator.setText("Checkmate! " + (self.currentPlayer === 'white' ? "Black" : "White") + " wins!"); // Update stats var stats = storage.stats || { wins: 0, losses: 0, draws: 0 }; if (self.currentPlayer === 'white') { stats.losses++; } else { stats.wins++; } storage.stats = stats; } else { // Just check self.checkIndicator.setText(self.currentPlayer.charAt(0).toUpperCase() + self.currentPlayer.slice(1) + " is in check!"); LK.getSound('check').play(); } } else { // Check for stalemate var hasLegalMoves = self.playerHasLegalMoves(self.currentPlayer); if (!hasLegalMoves) { // Stalemate self.gameOver = true; self.checkIndicator.setText("Stalemate! Draw game."); // Update stats var stats = storage.stats || { wins: 0, losses: 0, draws: 0 }; stats.draws++; storage.stats = stats; } else { self.checkIndicator.setText(""); } } }; self.isPlayerInCheck = function (player) { // Find player's king var kingPosition; for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var piece = self.board[row][col].piece; if (piece && piece.type === 'king' && piece.color === player) { kingPosition = { row: row, col: col }; break; } } if (kingPosition) break; } // Check if any opponent piece can capture the king var opponent = player === 'white' ? 'black' : 'white'; for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var piece = self.board[row][col].piece; if (piece && piece.color === opponent) { var moves = self.getRawPieceMoves(self.board[row][col]); for (var i = 0; i < moves.length; i++) { if (moves[i].row === kingPosition.row && moves[i].col === kingPosition.col) { return true; } } } } } return false; }; self.playerHasLegalMoves = function (player) { for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var square = self.board[row][col]; var piece = square.piece; if (piece && piece.color === player) { var moves = self.calculatePossibleMoves(square); if (moves.length > 0) { return true; } } } } return false; }; self.undoLastMove = function () { if (self.moveHistory.length === 0) return; // Get the last move var lastMove = self.moveHistory.pop(); // If AI is enabled and we're undoing our move and AI's move if (AI_ENABLED && self.currentPlayer === 'white' && self.moveHistory.length > 0) { var aiMove = lastMove; lastMove = self.moveHistory.pop(); self.undoSingleMove(aiMove); } self.undoSingleMove(lastMove); // Update undo button state self.undoButton.setEnabled(self.moveHistory.length > 0); // Clear any check status self.inCheck = { white: false, black: false }; self.checkIndicator.setText(""); // Ensure game over flag is reset self.gameOver = false; }; self.undoSingleMove = function (move) { // Undo the move var fromSquare = self.board[move.from.row][move.from.col]; var toSquare = self.board[move.to.row][move.to.col]; var piece = toSquare.piece; // Handle pawn promotion if (move.promotion) { piece = new ChessPiece().init('pawn', piece.color); } // Move piece back toSquare.setPiece(null); fromSquare.setPiece(piece); // Restore captured piece if (move.captured) { toSquare.setPiece(move.captured); } // Undo castling if (move.castling) { var rookTo = self.board[move.castling.to.row][move.castling.to.col]; var rookFrom = self.board[move.castling.from.row][move.castling.from.col]; var rook = rookTo.piece; rookTo.setPiece(null); rookFrom.setPiece(rook); if (move.firstMove) { rook.hasMoved = false; } } // Restore first move status if (move.firstMove) { piece.hasMoved = false; } // Clear last move highlights if (self.lastMoveFrom) { self.lastMoveFrom.setLastMove(false); } if (self.lastMoveTo) { self.lastMoveTo.setLastMove(false); } // Find the previous move for highlighting if (self.moveHistory.length > 0) { var prevMove = self.moveHistory[self.moveHistory.length - 1]; self.lastMoveFrom = self.board[prevMove.from.row][prevMove.from.col]; self.lastMoveTo = self.board[prevMove.to.row][prevMove.to.col]; self.lastMoveFrom.setLastMove(true); self.lastMoveTo.setLastMove(true); } else { self.lastMoveFrom = null; self.lastMoveTo = null; } // Switch player back self.currentPlayer = self.currentPlayer === 'white' ? 'black' : 'white'; self.turnIndicator.setText(self.currentPlayer.charAt(0).toUpperCase() + self.currentPlayer.slice(1) + "'s Turn"); }; self.resetGame = function () { // Clear the entire board for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { if (self.board[row][col].piece) { self.board[row][col].setPiece(null); } // Clear highlights self.board[row][col].setHighlight(false); self.board[row][col].setSelected(false); self.board[row][col].setLastMove(false); } } // Clear game state self.selectedSquare = null; self.possibleMoves = []; self.currentPlayer = 'white'; self.gameOver = false; self.moveHistory = []; self.lastMovedPiece = null; self.lastMoveFrom = null; self.lastMoveTo = null; self.inCheck = { white: false, black: false }; // Reset UI self.turnIndicator.setText("White's Turn"); self.checkIndicator.setText(""); self.undoButton.setEnabled(false); // Re-populate pieces self.setupPieces(); // Play move sound LK.getSound('movePiece').play(); }; self.makeAIMove = function () { // Simple AI - find all possible moves and choose a random one // For a smarter AI, you'd implement minimax with alpha-beta pruning var allMoves = []; for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var square = self.board[row][col]; if (square.piece && square.piece.color === 'black') { var moves = self.calculatePossibleMoves(square); for (var i = 0; i < moves.length; i++) { allMoves.push({ from: square, to: self.board[moves[i].row][moves[i].col] }); } } } } if (allMoves.length > 0) { // Prioritize captures and checks var goodMoves = allMoves.filter(function (move) { // Is this a capture? if (move.to.piece) return true; // Would this move put the opponent in check? // Simulate the move var fromPiece = move.from.piece; var toPiece = move.to.piece; move.from.piece = null; move.to.piece = fromPiece; var wouldCauseCheck = self.isPlayerInCheck('white'); // Undo the simulation move.from.piece = fromPiece; move.to.piece = toPiece; return wouldCauseCheck; }); // If we have any "good" moves, pick from those var finalMoves = goodMoves.length > 0 ? goodMoves : allMoves; // Choose a random move var randomIndex = Math.floor(Math.random() * finalMoves.length); var aiMove = finalMoves[randomIndex]; // Make the move self.movePiece(aiMove.from, aiMove.to); } }; self.calculatePossibleMoves = function (square) { var piece = square.piece; if (!piece) return []; var rawMoves = self.getRawPieceMoves(square); var legalMoves = []; // Filter out moves that would put or leave the king in check for (var i = 0; i < rawMoves.length; i++) { var move = rawMoves[i]; var targetSquare = self.board[move.row][move.col]; // Simulate the move var capturedPiece = targetSquare.piece; square.piece = null; targetSquare.piece = piece; // Check if the move leaves the king in check var inCheck = self.isPlayerInCheck(piece.color); // Undo the simulation square.piece = piece; targetSquare.piece = capturedPiece; if (!inCheck) { legalMoves.push(move); } } return legalMoves; }; self.getRawPieceMoves = function (square) { var piece = square.piece; if (!piece) return []; var moves = []; var row = square.row; var col = square.col; switch (piece.type) { case 'pawn': self.getPawnMoves(piece, row, col, moves); break; case 'rook': self.getRookMoves(piece, row, col, moves); break; case 'knight': self.getKnightMoves(piece, row, col, moves); break; case 'bishop': self.getBishopMoves(piece, row, col, moves); break; case 'queen': self.getQueenMoves(piece, row, col, moves); break; case 'king': self.getKingMoves(piece, row, col, moves); break; } return moves; }; self.getPawnMoves = function (piece, row, col, moves) { var direction = piece.color === 'white' ? -1 : 1; var startRow = piece.color === 'white' ? 6 : 1; // Forward move if (self.isInBounds(row + direction, col) && !self.board[row + direction][col].piece) { moves.push({ row: row + direction, col: col }); // Double move from starting position if (row === startRow && !self.board[row + 2 * direction][col].piece) { moves.push({ row: row + 2 * direction, col: col }); } } // Captures for (var dcol = -1; dcol <= 1; dcol += 2) { if (self.isInBounds(row + direction, col + dcol)) { var targetSquare = self.board[row + direction][col + dcol]; if (targetSquare.piece && targetSquare.piece.color !== piece.color) { moves.push({ row: row + direction, col: col + dcol }); } } } }; self.getRookMoves = function (piece, row, col, moves) { // Horizontal and vertical moves var directions = [{ dr: 0, dc: 1 }, // right { dr: 0, dc: -1 }, // left { dr: 1, dc: 0 }, // down { dr: -1, dc: 0 } // up ]; for (var i = 0; i < directions.length; i++) { var dir = directions[i]; for (var dist = 1; dist < 8; dist++) { var newRow = row + dir.dr * dist; var newCol = col + dir.dc * dist; if (!self.isInBounds(newRow, newCol)) break; var targetSquare = self.board[newRow][newCol]; if (!targetSquare.piece) { moves.push({ row: newRow, col: newCol }); } else { if (targetSquare.piece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } break; } } } }; self.getKnightMoves = function (piece, row, col, moves) { var knightMoves = [{ dr: -2, dc: -1 }, { dr: -2, dc: 1 }, { dr: -1, dc: -2 }, { dr: -1, dc: 2 }, { dr: 1, dc: -2 }, { dr: 1, dc: 2 }, { dr: 2, dc: -1 }, { dr: 2, dc: 1 }]; for (var i = 0; i < knightMoves.length; i++) { var move = knightMoves[i]; var newRow = row + move.dr; var newCol = col + move.dc; if (self.isInBounds(newRow, newCol)) { var targetSquare = self.board[newRow][newCol]; if (!targetSquare.piece || targetSquare.piece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } } } }; self.getBishopMoves = function (piece, row, col, moves) { // Diagonal moves var directions = [{ dr: 1, dc: 1 }, // down-right { dr: 1, dc: -1 }, // down-left { dr: -1, dc: 1 }, // up-right { dr: -1, dc: -1 } // up-left ]; for (var i = 0; i < directions.length; i++) { var dir = directions[i]; for (var dist = 1; dist < 8; dist++) { var newRow = row + dir.dr * dist; var newCol = col + dir.dc * dist; if (!self.isInBounds(newRow, newCol)) break; var targetSquare = self.board[newRow][newCol]; if (!targetSquare.piece) { moves.push({ row: newRow, col: newCol }); } else { if (targetSquare.piece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } break; } } } }; self.getQueenMoves = function (piece, row, col, moves) { // Queen = Rook + Bishop self.getRookMoves(piece, row, col, moves); self.getBishopMoves(piece, row, col, moves); }; self.getKingMoves = function (piece, row, col, moves) { // All 8 directions for (var dr = -1; dr <= 1; dr++) { for (var dc = -1; dc <= 1; dc++) { if (dr === 0 && dc === 0) continue; var newRow = row + dr; var newCol = col + dc; if (self.isInBounds(newRow, newCol)) { var targetSquare = self.board[newRow][newCol]; if (!targetSquare.piece || targetSquare.piece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } } } } // Castling if (!piece.hasMoved && !self.inCheck[piece.color]) { // Kingside castling if (self.canCastle(row, col, 0, 3)) { moves.push({ row: row, col: col + 2 }); } // Queenside castling if (self.canCastle(row, col, 0, -4)) { moves.push({ row: row, col: col - 2 }); } } }; self.canCastle = function (row, col, rowOffset, colOffset) { var direction = colOffset > 0 ? 1 : -1; var distance = Math.abs(colOffset); // Check if the rook is there and hasn't moved var rookCol = direction > 0 ? 7 : 0; var rookSquare = self.board[row][rookCol]; if (!rookSquare.piece || rookSquare.piece.type !== 'rook' || rookSquare.piece.color !== self.currentPlayer || rookSquare.piece.hasMoved) { return false; } // Check if the squares between king and rook are empty for (var i = 1; i < distance; i++) { var checkCol = col + i * direction; if (self.board[row][checkCol].piece) { return false; } } // Check if the king passes through or ends up in check for (var i = 0; i <= 2; i++) { var checkCol = col + i * direction; // Simulate the king at this position var originalSquare = self.board[row][col]; var checkSquare = self.board[row][checkCol]; var kingPiece = originalSquare.piece; var tempPiece = checkSquare.piece; originalSquare.piece = null; checkSquare.piece = kingPiece; var inCheck = self.isPlayerInCheck(self.currentPlayer); // Restore board originalSquare.piece = kingPiece; checkSquare.piece = tempPiece; if (inCheck) { return false; } } return true; }; self.isInBounds = function (row, col) { return row >= 0 && row < 8 && col >= 0 && col < 8; }; return self; }); var ChessPiece = Container.expand(function () { var self = Container.call(this); self.init = function (type, color) { self.type = type; self.color = color; self.hasMoved = false; var assetId = color + type.charAt(0).toUpperCase() + type.slice(1); var pieceAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // No letters on pieces return self; }; return self; }); var ChessSquare = Container.expand(function () { var self = Container.call(this); self.init = function (row, col, color) { self.row = row; self.col = col; self.color = color; self.piece = null; var squareAsset = self.attachAsset(color === 'white' ? 'whiteSquare' : 'blackSquare', { anchorX: 0, anchorY: 0, width: SQUARE_SIZE, height: SQUARE_SIZE }); self.highlight = self.attachAsset('highlight', { anchorX: 0, anchorY: 0, width: SQUARE_SIZE, height: SQUARE_SIZE, alpha: 0 }); self.selected = self.attachAsset('selected', { anchorX: 0, anchorY: 0, width: SQUARE_SIZE, height: SQUARE_SIZE, alpha: 0 }); self.lastMove = self.attachAsset('lastMove', { anchorX: 0, anchorY: 0, width: SQUARE_SIZE, height: SQUARE_SIZE, alpha: 0 }); return self; }; self.setHighlight = function (value) { self.highlight.alpha = value ? 0.5 : 0; }; self.setSelected = function (value) { self.selected.alpha = value ? 0.5 : 0; }; self.setLastMove = function (value) { self.lastMove.alpha = value ? 0.3 : 0; }; self.setPiece = function (piece) { if (self.piece) { self.removeChild(self.piece); } self.piece = piece; if (piece) { self.addChild(piece); piece.x = SQUARE_SIZE / 2; piece.y = SQUARE_SIZE / 2; } }; self.down = function (x, y, obj) { chessGame.squareClicked(self); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x333333 }); /**** * Game Code ****/ // Constants var SQUARE_SIZE = 200; // Increased square size var BOARD_SIZE = SQUARE_SIZE * 8; var AI_ENABLED = true; // Center the board horizontally and vertically var boardOffsetX = (2048 - BOARD_SIZE) / 2; var boardOffsetY = (2732 - BOARD_SIZE) / 2 - 100; // Center vertically with offset for title // Create chess game var chessGame = new ChessGame().init(); chessGame.x = boardOffsetX; chessGame.y = boardOffsetY; game.addChild(chessGame); // Add title var title = new Text2("Play against MissPiece", { size: 120, // Increased text size fill: 0xFFFFFF }); title.anchor.set(0.5, 0); title.x = 2048 / 2; title.y = 50; // Adjusted position game.addChild(title); // No instructions text needed // Play background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.3, duration: 1000 } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
gameHistory: [],
stats: {
wins: 0,
losses: 0,
draws: 0
}
});
/****
* Classes
****/
var Button = Container.expand(function () {
var self = Container.call(this);
self.init = function (text, width, height, color) {
self.background = self.attachAsset('whiteSquare', {
anchorX: 0,
anchorY: 0,
width: width,
height: height,
tint: color || 0x4488FF
});
self.label = new Text2(text, {
size: 50,
//{e} // Increased text size
fill: 0xFFFFFF
});
self.label.anchor.set(0.5, 0.5);
self.label.x = width / 2;
self.label.y = height / 2;
self.addChild(self.label);
return self;
};
self.setEnabled = function (enabled) {
self.enabled = enabled;
self.background.alpha = enabled ? 1 : 0.5;
};
self.down = function (x, y, obj) {
if (self.enabled !== false) {
LK.getSound('movePiece').play();
tween(self, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
}
};
self.up = function (x, y, obj) {
if (self.enabled !== false) {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
onFinish: function onFinish() {
if (self.onClick) {
self.onClick();
}
}
});
}
};
return self;
});
var ChessGame = Container.expand(function () {
var self = Container.call(this);
// Game state
self.board = [];
self.selectedSquare = null;
self.possibleMoves = [];
self.currentPlayer = 'white';
self.gameOver = false;
self.moveHistory = [];
self.lastMovedPiece = null;
self.lastMoveFrom = null;
self.lastMoveTo = null;
self.inCheck = {
white: false,
black: false
};
self.init = function () {
self.initializeBoard();
self.setupPieces();
self.createControls();
return self;
};
self.initializeBoard = function () {
for (var row = 0; row < 8; row++) {
self.board[row] = [];
for (var col = 0; col < 8; col++) {
var color = (row + col) % 2 === 0 ? 'white' : 'black';
var square = new ChessSquare().init(row, col, color);
square.x = col * SQUARE_SIZE;
square.y = row * SQUARE_SIZE;
self.addChild(square);
self.board[row][col] = square;
}
}
};
self.setupPieces = function () {
// Place pawns
for (var col = 0; col < 8; col++) {
self.placePiece('pawn', 'white', 6, col);
self.placePiece('pawn', 'black', 1, col);
}
// Place rooks
self.placePiece('rook', 'white', 7, 0);
self.placePiece('rook', 'white', 7, 7);
self.placePiece('rook', 'black', 0, 0);
self.placePiece('rook', 'black', 0, 7);
// Place knights
self.placePiece('knight', 'white', 7, 1);
self.placePiece('knight', 'white', 7, 6);
self.placePiece('knight', 'black', 0, 1);
self.placePiece('knight', 'black', 0, 6);
// Place bishops
self.placePiece('bishop', 'white', 7, 2);
self.placePiece('bishop', 'white', 7, 5);
self.placePiece('bishop', 'black', 0, 2);
self.placePiece('bishop', 'black', 0, 5);
// Place queens
self.placePiece('queen', 'white', 7, 3);
self.placePiece('queen', 'black', 0, 3);
// Place kings
self.placePiece('king', 'white', 7, 4);
self.placePiece('king', 'black', 0, 4);
};
self.createControls = function () {
// Undo button
self.undoButton = new Button().init("UNDO", 250, 100); // Increased button size
self.undoButton.x = BOARD_SIZE / 2 - 270; // Positioned to left of center
self.undoButton.y = BOARD_SIZE + 200; // Below indicators
self.addChild(self.undoButton);
self.undoButton.onClick = function () {
self.undoLastMove();
};
self.undoButton.setEnabled(false);
// Reset button
self.resetButton = new Button().init("RESET", 250, 100); // Increased button size
self.resetButton.x = BOARD_SIZE / 2 + 20; // Positioned to right of center
self.resetButton.y = BOARD_SIZE + 200; // Below indicators
self.addChild(self.resetButton);
self.resetButton.onClick = function () {
self.resetGame();
};
// Turn indicator
self.turnIndicator = new Text2("White's Turn", {
size: 60,
//{13} // Increased text size
fill: 0xFFFFFF
});
self.turnIndicator.x = BOARD_SIZE / 2; // Center horizontally on board
self.turnIndicator.y = BOARD_SIZE + 50; // Below board
self.turnIndicator.anchor.set(0.5, 0);
self.addChild(self.turnIndicator);
// Check indicator
self.checkIndicator = new Text2("", {
size: 60,
//{16} // Increased text size
fill: 0xFF0000
});
self.checkIndicator.x = BOARD_SIZE / 2; // Center horizontally on board
self.checkIndicator.y = BOARD_SIZE + 120; // Below turn indicator
self.checkIndicator.anchor.set(0.5, 0);
self.addChild(self.checkIndicator);
};
self.placePiece = function (type, color, row, col) {
var piece = new ChessPiece().init(type, color);
self.board[row][col].setPiece(piece);
};
self.squareClicked = function (square) {
if (self.gameOver || self.currentPlayer === 'black' && AI_ENABLED) return;
if (self.selectedSquare) {
// If selected square is clicked again, deselect it
if (self.selectedSquare === square) {
self.clearSelection();
return;
}
// Check if clicked square is a possible move
if (self.isPossibleMove(square)) {
self.movePiece(self.selectedSquare, square);
return;
}
}
// Check if square has a piece of current player's color
if (square.piece && square.piece.color === self.currentPlayer) {
self.selectSquare(square);
}
};
self.selectSquare = function (square) {
self.clearSelection();
self.selectedSquare = square;
square.setSelected(true);
self.possibleMoves = self.calculatePossibleMoves(square);
// Highlight possible moves
for (var i = 0; i < self.possibleMoves.length; i++) {
var move = self.possibleMoves[i];
self.board[move.row][move.col].setHighlight(true);
}
};
self.clearSelection = function () {
if (self.selectedSquare) {
self.selectedSquare.setSelected(false);
self.selectedSquare = null;
}
// Clear highlights
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
self.board[row][col].setHighlight(false);
}
}
self.possibleMoves = [];
};
self.isPossibleMove = function (square) {
for (var i = 0; i < self.possibleMoves.length; i++) {
var move = self.possibleMoves[i];
if (move.row === square.row && move.col === square.col) {
return true;
}
}
return false;
};
self.movePiece = function (fromSquare, toSquare) {
var piece = fromSquare.piece;
var capturedPiece = toSquare.piece;
var moveRecord = {
piece: piece,
from: {
row: fromSquare.row,
col: fromSquare.col
},
to: {
row: toSquare.row,
col: toSquare.col
},
captured: capturedPiece,
firstMove: !piece.hasMoved,
isCheck: false
};
// Clear any previous 'last move' highlights
if (self.lastMoveFrom) {
self.lastMoveFrom.setLastMove(false);
}
if (self.lastMoveTo) {
self.lastMoveTo.setLastMove(false);
}
// Handle castling
var isCastling = piece.type === 'king' && Math.abs(fromSquare.col - toSquare.col) === 2;
if (isCastling) {
var rookCol = toSquare.col === 6 ? 7 : 0;
var newRookCol = toSquare.col === 6 ? 5 : 3;
var rookSquare = self.board[fromSquare.row][rookCol];
var rook = rookSquare.piece;
moveRecord.castling = {
rook: rook,
from: {
row: fromSquare.row,
col: rookCol
},
to: {
row: fromSquare.row,
col: newRookCol
}
};
// Move the rook
rookSquare.setPiece(null);
self.board[fromSquare.row][newRookCol].setPiece(rook);
rook.hasMoved = true;
LK.getSound('castle').play();
} else if (capturedPiece) {
LK.getSound('capture').play();
} else {
LK.getSound('movePiece').play();
}
// Handle pawn promotion
if (piece.type === 'pawn' && (toSquare.row === 0 || toSquare.row === 7)) {
// Clear the source square first
fromSquare.setPiece(null);
// Create new queen
var newQueen = new ChessPiece().init('queen', piece.color);
// Place the queen on the destination square
toSquare.setPiece(newQueen);
moveRecord.promotion = {
from: 'pawn',
to: 'queen'
};
piece = newQueen;
} else {
// Move the piece
fromSquare.setPiece(null);
toSquare.setPiece(piece);
}
// Mark the piece as moved
piece.hasMoved = true;
// Record the last move for highlighting
self.lastMoveFrom = fromSquare;
self.lastMoveTo = toSquare;
fromSquare.setLastMove(true);
toSquare.setLastMove(true);
// Add move to history
self.moveHistory.push(moveRecord);
// Clear selection
self.clearSelection();
// Switch player
self.currentPlayer = self.currentPlayer === 'white' ? 'black' : 'white';
self.turnIndicator.setText("MissPiece's Turn");
// Check for check or checkmate
self.checkForCheckAndMate();
// Update undo button state
self.undoButton.setEnabled(self.moveHistory.length > 0);
// If AI is enabled and it's black's turn, make AI move
if (AI_ENABLED && self.currentPlayer === 'black' && !self.gameOver) {
LK.setTimeout(function () {
self.makeAIMove();
}, 500);
}
};
self.checkForCheckAndMate = function () {
// Check if current player is in check
var isInCheck = self.isPlayerInCheck(self.currentPlayer);
self.inCheck[self.currentPlayer] = isInCheck;
if (isInCheck) {
// Check if it's checkmate
var hasLegalMoves = self.playerHasLegalMoves(self.currentPlayer);
if (!hasLegalMoves) {
// Checkmate
self.gameOver = true;
self.checkIndicator.setText("Checkmate! " + (self.currentPlayer === 'white' ? "Black" : "White") + " wins!");
// Update stats
var stats = storage.stats || {
wins: 0,
losses: 0,
draws: 0
};
if (self.currentPlayer === 'white') {
stats.losses++;
} else {
stats.wins++;
}
storage.stats = stats;
} else {
// Just check
self.checkIndicator.setText(self.currentPlayer.charAt(0).toUpperCase() + self.currentPlayer.slice(1) + " is in check!");
LK.getSound('check').play();
}
} else {
// Check for stalemate
var hasLegalMoves = self.playerHasLegalMoves(self.currentPlayer);
if (!hasLegalMoves) {
// Stalemate
self.gameOver = true;
self.checkIndicator.setText("Stalemate! Draw game.");
// Update stats
var stats = storage.stats || {
wins: 0,
losses: 0,
draws: 0
};
stats.draws++;
storage.stats = stats;
} else {
self.checkIndicator.setText("");
}
}
};
self.isPlayerInCheck = function (player) {
// Find player's king
var kingPosition;
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = self.board[row][col].piece;
if (piece && piece.type === 'king' && piece.color === player) {
kingPosition = {
row: row,
col: col
};
break;
}
}
if (kingPosition) break;
}
// Check if any opponent piece can capture the king
var opponent = player === 'white' ? 'black' : 'white';
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = self.board[row][col].piece;
if (piece && piece.color === opponent) {
var moves = self.getRawPieceMoves(self.board[row][col]);
for (var i = 0; i < moves.length; i++) {
if (moves[i].row === kingPosition.row && moves[i].col === kingPosition.col) {
return true;
}
}
}
}
}
return false;
};
self.playerHasLegalMoves = function (player) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var square = self.board[row][col];
var piece = square.piece;
if (piece && piece.color === player) {
var moves = self.calculatePossibleMoves(square);
if (moves.length > 0) {
return true;
}
}
}
}
return false;
};
self.undoLastMove = function () {
if (self.moveHistory.length === 0) return;
// Get the last move
var lastMove = self.moveHistory.pop();
// If AI is enabled and we're undoing our move and AI's move
if (AI_ENABLED && self.currentPlayer === 'white' && self.moveHistory.length > 0) {
var aiMove = lastMove;
lastMove = self.moveHistory.pop();
self.undoSingleMove(aiMove);
}
self.undoSingleMove(lastMove);
// Update undo button state
self.undoButton.setEnabled(self.moveHistory.length > 0);
// Clear any check status
self.inCheck = {
white: false,
black: false
};
self.checkIndicator.setText("");
// Ensure game over flag is reset
self.gameOver = false;
};
self.undoSingleMove = function (move) {
// Undo the move
var fromSquare = self.board[move.from.row][move.from.col];
var toSquare = self.board[move.to.row][move.to.col];
var piece = toSquare.piece;
// Handle pawn promotion
if (move.promotion) {
piece = new ChessPiece().init('pawn', piece.color);
}
// Move piece back
toSquare.setPiece(null);
fromSquare.setPiece(piece);
// Restore captured piece
if (move.captured) {
toSquare.setPiece(move.captured);
}
// Undo castling
if (move.castling) {
var rookTo = self.board[move.castling.to.row][move.castling.to.col];
var rookFrom = self.board[move.castling.from.row][move.castling.from.col];
var rook = rookTo.piece;
rookTo.setPiece(null);
rookFrom.setPiece(rook);
if (move.firstMove) {
rook.hasMoved = false;
}
}
// Restore first move status
if (move.firstMove) {
piece.hasMoved = false;
}
// Clear last move highlights
if (self.lastMoveFrom) {
self.lastMoveFrom.setLastMove(false);
}
if (self.lastMoveTo) {
self.lastMoveTo.setLastMove(false);
}
// Find the previous move for highlighting
if (self.moveHistory.length > 0) {
var prevMove = self.moveHistory[self.moveHistory.length - 1];
self.lastMoveFrom = self.board[prevMove.from.row][prevMove.from.col];
self.lastMoveTo = self.board[prevMove.to.row][prevMove.to.col];
self.lastMoveFrom.setLastMove(true);
self.lastMoveTo.setLastMove(true);
} else {
self.lastMoveFrom = null;
self.lastMoveTo = null;
}
// Switch player back
self.currentPlayer = self.currentPlayer === 'white' ? 'black' : 'white';
self.turnIndicator.setText(self.currentPlayer.charAt(0).toUpperCase() + self.currentPlayer.slice(1) + "'s Turn");
};
self.resetGame = function () {
// Clear the entire board
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
if (self.board[row][col].piece) {
self.board[row][col].setPiece(null);
}
// Clear highlights
self.board[row][col].setHighlight(false);
self.board[row][col].setSelected(false);
self.board[row][col].setLastMove(false);
}
}
// Clear game state
self.selectedSquare = null;
self.possibleMoves = [];
self.currentPlayer = 'white';
self.gameOver = false;
self.moveHistory = [];
self.lastMovedPiece = null;
self.lastMoveFrom = null;
self.lastMoveTo = null;
self.inCheck = {
white: false,
black: false
};
// Reset UI
self.turnIndicator.setText("White's Turn");
self.checkIndicator.setText("");
self.undoButton.setEnabled(false);
// Re-populate pieces
self.setupPieces();
// Play move sound
LK.getSound('movePiece').play();
};
self.makeAIMove = function () {
// Simple AI - find all possible moves and choose a random one
// For a smarter AI, you'd implement minimax with alpha-beta pruning
var allMoves = [];
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var square = self.board[row][col];
if (square.piece && square.piece.color === 'black') {
var moves = self.calculatePossibleMoves(square);
for (var i = 0; i < moves.length; i++) {
allMoves.push({
from: square,
to: self.board[moves[i].row][moves[i].col]
});
}
}
}
}
if (allMoves.length > 0) {
// Prioritize captures and checks
var goodMoves = allMoves.filter(function (move) {
// Is this a capture?
if (move.to.piece) return true;
// Would this move put the opponent in check?
// Simulate the move
var fromPiece = move.from.piece;
var toPiece = move.to.piece;
move.from.piece = null;
move.to.piece = fromPiece;
var wouldCauseCheck = self.isPlayerInCheck('white');
// Undo the simulation
move.from.piece = fromPiece;
move.to.piece = toPiece;
return wouldCauseCheck;
});
// If we have any "good" moves, pick from those
var finalMoves = goodMoves.length > 0 ? goodMoves : allMoves;
// Choose a random move
var randomIndex = Math.floor(Math.random() * finalMoves.length);
var aiMove = finalMoves[randomIndex];
// Make the move
self.movePiece(aiMove.from, aiMove.to);
}
};
self.calculatePossibleMoves = function (square) {
var piece = square.piece;
if (!piece) return [];
var rawMoves = self.getRawPieceMoves(square);
var legalMoves = [];
// Filter out moves that would put or leave the king in check
for (var i = 0; i < rawMoves.length; i++) {
var move = rawMoves[i];
var targetSquare = self.board[move.row][move.col];
// Simulate the move
var capturedPiece = targetSquare.piece;
square.piece = null;
targetSquare.piece = piece;
// Check if the move leaves the king in check
var inCheck = self.isPlayerInCheck(piece.color);
// Undo the simulation
square.piece = piece;
targetSquare.piece = capturedPiece;
if (!inCheck) {
legalMoves.push(move);
}
}
return legalMoves;
};
self.getRawPieceMoves = function (square) {
var piece = square.piece;
if (!piece) return [];
var moves = [];
var row = square.row;
var col = square.col;
switch (piece.type) {
case 'pawn':
self.getPawnMoves(piece, row, col, moves);
break;
case 'rook':
self.getRookMoves(piece, row, col, moves);
break;
case 'knight':
self.getKnightMoves(piece, row, col, moves);
break;
case 'bishop':
self.getBishopMoves(piece, row, col, moves);
break;
case 'queen':
self.getQueenMoves(piece, row, col, moves);
break;
case 'king':
self.getKingMoves(piece, row, col, moves);
break;
}
return moves;
};
self.getPawnMoves = function (piece, row, col, moves) {
var direction = piece.color === 'white' ? -1 : 1;
var startRow = piece.color === 'white' ? 6 : 1;
// Forward move
if (self.isInBounds(row + direction, col) && !self.board[row + direction][col].piece) {
moves.push({
row: row + direction,
col: col
});
// Double move from starting position
if (row === startRow && !self.board[row + 2 * direction][col].piece) {
moves.push({
row: row + 2 * direction,
col: col
});
}
}
// Captures
for (var dcol = -1; dcol <= 1; dcol += 2) {
if (self.isInBounds(row + direction, col + dcol)) {
var targetSquare = self.board[row + direction][col + dcol];
if (targetSquare.piece && targetSquare.piece.color !== piece.color) {
moves.push({
row: row + direction,
col: col + dcol
});
}
}
}
};
self.getRookMoves = function (piece, row, col, moves) {
// Horizontal and vertical moves
var directions = [{
dr: 0,
dc: 1
},
// right
{
dr: 0,
dc: -1
},
// left
{
dr: 1,
dc: 0
},
// down
{
dr: -1,
dc: 0
} // up
];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
for (var dist = 1; dist < 8; dist++) {
var newRow = row + dir.dr * dist;
var newCol = col + dir.dc * dist;
if (!self.isInBounds(newRow, newCol)) break;
var targetSquare = self.board[newRow][newCol];
if (!targetSquare.piece) {
moves.push({
row: newRow,
col: newCol
});
} else {
if (targetSquare.piece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
}
}
};
self.getKnightMoves = function (piece, row, col, moves) {
var knightMoves = [{
dr: -2,
dc: -1
}, {
dr: -2,
dc: 1
}, {
dr: -1,
dc: -2
}, {
dr: -1,
dc: 2
}, {
dr: 1,
dc: -2
}, {
dr: 1,
dc: 2
}, {
dr: 2,
dc: -1
}, {
dr: 2,
dc: 1
}];
for (var i = 0; i < knightMoves.length; i++) {
var move = knightMoves[i];
var newRow = row + move.dr;
var newCol = col + move.dc;
if (self.isInBounds(newRow, newCol)) {
var targetSquare = self.board[newRow][newCol];
if (!targetSquare.piece || targetSquare.piece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
};
self.getBishopMoves = function (piece, row, col, moves) {
// Diagonal moves
var directions = [{
dr: 1,
dc: 1
},
// down-right
{
dr: 1,
dc: -1
},
// down-left
{
dr: -1,
dc: 1
},
// up-right
{
dr: -1,
dc: -1
} // up-left
];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
for (var dist = 1; dist < 8; dist++) {
var newRow = row + dir.dr * dist;
var newCol = col + dir.dc * dist;
if (!self.isInBounds(newRow, newCol)) break;
var targetSquare = self.board[newRow][newCol];
if (!targetSquare.piece) {
moves.push({
row: newRow,
col: newCol
});
} else {
if (targetSquare.piece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
}
}
};
self.getQueenMoves = function (piece, row, col, moves) {
// Queen = Rook + Bishop
self.getRookMoves(piece, row, col, moves);
self.getBishopMoves(piece, row, col, moves);
};
self.getKingMoves = function (piece, row, col, moves) {
// All 8 directions
for (var dr = -1; dr <= 1; dr++) {
for (var dc = -1; dc <= 1; dc++) {
if (dr === 0 && dc === 0) continue;
var newRow = row + dr;
var newCol = col + dc;
if (self.isInBounds(newRow, newCol)) {
var targetSquare = self.board[newRow][newCol];
if (!targetSquare.piece || targetSquare.piece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
}
// Castling
if (!piece.hasMoved && !self.inCheck[piece.color]) {
// Kingside castling
if (self.canCastle(row, col, 0, 3)) {
moves.push({
row: row,
col: col + 2
});
}
// Queenside castling
if (self.canCastle(row, col, 0, -4)) {
moves.push({
row: row,
col: col - 2
});
}
}
};
self.canCastle = function (row, col, rowOffset, colOffset) {
var direction = colOffset > 0 ? 1 : -1;
var distance = Math.abs(colOffset);
// Check if the rook is there and hasn't moved
var rookCol = direction > 0 ? 7 : 0;
var rookSquare = self.board[row][rookCol];
if (!rookSquare.piece || rookSquare.piece.type !== 'rook' || rookSquare.piece.color !== self.currentPlayer || rookSquare.piece.hasMoved) {
return false;
}
// Check if the squares between king and rook are empty
for (var i = 1; i < distance; i++) {
var checkCol = col + i * direction;
if (self.board[row][checkCol].piece) {
return false;
}
}
// Check if the king passes through or ends up in check
for (var i = 0; i <= 2; i++) {
var checkCol = col + i * direction;
// Simulate the king at this position
var originalSquare = self.board[row][col];
var checkSquare = self.board[row][checkCol];
var kingPiece = originalSquare.piece;
var tempPiece = checkSquare.piece;
originalSquare.piece = null;
checkSquare.piece = kingPiece;
var inCheck = self.isPlayerInCheck(self.currentPlayer);
// Restore board
originalSquare.piece = kingPiece;
checkSquare.piece = tempPiece;
if (inCheck) {
return false;
}
}
return true;
};
self.isInBounds = function (row, col) {
return row >= 0 && row < 8 && col >= 0 && col < 8;
};
return self;
});
var ChessPiece = Container.expand(function () {
var self = Container.call(this);
self.init = function (type, color) {
self.type = type;
self.color = color;
self.hasMoved = false;
var assetId = color + type.charAt(0).toUpperCase() + type.slice(1);
var pieceAsset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// No letters on pieces
return self;
};
return self;
});
var ChessSquare = Container.expand(function () {
var self = Container.call(this);
self.init = function (row, col, color) {
self.row = row;
self.col = col;
self.color = color;
self.piece = null;
var squareAsset = self.attachAsset(color === 'white' ? 'whiteSquare' : 'blackSquare', {
anchorX: 0,
anchorY: 0,
width: SQUARE_SIZE,
height: SQUARE_SIZE
});
self.highlight = self.attachAsset('highlight', {
anchorX: 0,
anchorY: 0,
width: SQUARE_SIZE,
height: SQUARE_SIZE,
alpha: 0
});
self.selected = self.attachAsset('selected', {
anchorX: 0,
anchorY: 0,
width: SQUARE_SIZE,
height: SQUARE_SIZE,
alpha: 0
});
self.lastMove = self.attachAsset('lastMove', {
anchorX: 0,
anchorY: 0,
width: SQUARE_SIZE,
height: SQUARE_SIZE,
alpha: 0
});
return self;
};
self.setHighlight = function (value) {
self.highlight.alpha = value ? 0.5 : 0;
};
self.setSelected = function (value) {
self.selected.alpha = value ? 0.5 : 0;
};
self.setLastMove = function (value) {
self.lastMove.alpha = value ? 0.3 : 0;
};
self.setPiece = function (piece) {
if (self.piece) {
self.removeChild(self.piece);
}
self.piece = piece;
if (piece) {
self.addChild(piece);
piece.x = SQUARE_SIZE / 2;
piece.y = SQUARE_SIZE / 2;
}
};
self.down = function (x, y, obj) {
chessGame.squareClicked(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x333333
});
/****
* Game Code
****/
// Constants
var SQUARE_SIZE = 200; // Increased square size
var BOARD_SIZE = SQUARE_SIZE * 8;
var AI_ENABLED = true;
// Center the board horizontally and vertically
var boardOffsetX = (2048 - BOARD_SIZE) / 2;
var boardOffsetY = (2732 - BOARD_SIZE) / 2 - 100; // Center vertically with offset for title
// Create chess game
var chessGame = new ChessGame().init();
chessGame.x = boardOffsetX;
chessGame.y = boardOffsetY;
game.addChild(chessGame);
// Add title
var title = new Text2("Play against MissPiece", {
size: 120,
// Increased text size
fill: 0xFFFFFF
});
title.anchor.set(0.5, 0);
title.x = 2048 / 2;
title.y = 50; // Adjusted position
game.addChild(title);
// No instructions text needed
// Play background music
LK.playMusic('bgMusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});