/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ChessPiece = Container.expand(function (type, color, row, col) { var self = Container.call(this); self.type = type; self.color = color; self.row = row; self.col = col; self.hasMoved = false; self.hasBeenConverted = false; var assetName = color + type.charAt(0).toUpperCase() + type.slice(1); self.pieceGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.updatePosition = function () { self.x = 124 + self.col * 240; self.y = 366 + self.row * 240; }; self.updatePosition(); self.isValidMove = function (toRow, toCol) { var deltaRow = toRow - self.row; var deltaCol = toCol - self.col; var absDeltaRow = Math.abs(deltaRow); var absDeltaCol = Math.abs(deltaCol); switch (self.type) { case 'pawn': var direction = self.color === 'white' ? -1 : 1; var startRow = self.color === 'white' ? 6 : 1; if (deltaCol === 0) { if (deltaRow === direction && !board[toRow][toCol].piece) { return true; } if (self.row === startRow && deltaRow === 2 * direction && !board[toRow][toCol].piece) { return true; } } else if (absDeltaCol === 1 && deltaRow === direction) { if (board[toRow][toCol].piece && board[toRow][toCol].piece.color !== self.color) { return true; } } break; case 'rook': if (deltaRow === 0 || deltaCol === 0) { return isPathClear(self.row, self.col, toRow, toCol); } break; case 'knight': if (absDeltaRow === 2 && absDeltaCol === 1 || absDeltaRow === 1 && absDeltaCol === 2) { return true; } break; case 'bishop': if (absDeltaRow === absDeltaCol) { return isPathClear(self.row, self.col, toRow, toCol); } break; case 'queen': if (deltaRow === 0 || deltaCol === 0 || absDeltaRow === absDeltaCol) { return isPathClear(self.row, self.col, toRow, toCol); } break; case 'king': if (absDeltaRow <= 1 && absDeltaCol <= 1) { return true; } break; case 'mage': // Mage can move 1 square in any direction when no target if (!board[toRow][toCol].piece) { if (absDeltaRow <= 1 && absDeltaCol <= 1) { return true; } } // Mage can only attack diagonally forward else if (board[toRow][toCol].piece && board[toRow][toCol].piece.color !== self.color) { var direction = self.color === 'white' ? -1 : 1; if (deltaRow === direction && absDeltaCol === 1) { return true; } } break; case 'guard': if (absDeltaRow <= 1 && absDeltaCol <= 1) { return true; } break; case 'dragon': if (absDeltaRow === absDeltaCol && absDeltaRow <= 3) { return isPathClear(self.row, self.col, toRow, toCol); } if (absDeltaRow === 2 && absDeltaCol === 1 || absDeltaRow === 1 && absDeltaCol === 2) { return true; } break; case 'seer': var direction = self.color === 'white' ? -1 : 1; if (deltaCol === 0) { if (deltaRow === direction && !board[toRow][toCol].piece) { return true; } } else if (absDeltaCol === 2 && deltaRow === 2 * direction) { if (board[toRow][toCol].piece && board[toRow][toCol].piece.color !== self.color) { return true; } } break; case 'panther': if (absDeltaRow === 1 && absDeltaCol === 1) { return true; } break; } return false; }; return self; }); var ChessSquare = Container.expand(function (row, col) { var self = Container.call(this); self.row = row; self.col = col; self.isLight = (row + col) % 2 === 0; self.piece = null; self.isSelected = false; self.isValidMove = false; self.squareSize = 240; self.squareGraphics = self.attachAsset(self.isLight ? 'lightSquare' : 'darkSquare', { anchorX: 0.5, anchorY: 0.5 }); self.selectedGraphics = null; self.validMoveGraphics = null; self.x = 124 + col * self.squareSize; self.y = 366 + row * self.squareSize; self.setSelected = function (selected) { self.isSelected = selected; if (selected) { if (!self.selectedGraphics) { self.selectedGraphics = self.attachAsset('selectedSquare', { anchorX: 0.5, anchorY: 0.5 }); } self.selectedGraphics.alpha = 0.5; } else { if (self.selectedGraphics) { self.selectedGraphics.alpha = 0; } } }; self.setValidMove = function (valid) { self.isValidMove = valid; if (valid) { if (!self.validMoveGraphics) { self.validMoveGraphics = self.attachAsset('validMoveSquare', { anchorX: 0.5, anchorY: 0.5 }); } self.validMoveGraphics.alpha = 0.3; } else { if (self.validMoveGraphics) { self.validMoveGraphics.alpha = 0; } } }; self.down = function (x, y, obj) { handleSquareClick(self.row, self.col); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x4A4A4A }); /**** * Game Code ****/ // Chess game state var board = []; var pieces = []; var currentPlayer = 'white'; var selectedSquare = null; var gameOver = false; var whiteKing = null; var blackKing = null; var convertedPieces = []; var isComputerPlayer = false; var computerColor = 'black'; var computerThinking = false; // Initialize the chess board for (var row = 0; row < 8; row++) { board[row] = []; for (var col = 0; col < 8; col++) { var square = new ChessSquare(row, col); board[row][col] = square; game.addChild(square); } } // Initial piece setup with fantasy pieces var initialSetup = [['rook', 'knight', 'bishop', 'queen', 'king', 'bishop', 'knight', 'rook'], ['pawn', 'dragon', 'pawn', 'guard', 'mage', 'pawn', 'dragon', 'pawn']]; var fantasySetup = [['dragon', 'seer', 'panther', '', '', 'panther', 'seer', 'dragon'], ['', '', '', '', '', '', '', '']]; // Place black pieces for (var row = 0; row < 2; row++) { for (var col = 0; col < 8; col++) { var piece = new ChessPiece(initialSetup[row][col], 'black', row, col); pieces.push(piece); board[row][col].piece = piece; game.addChild(piece); if (piece.type === 'king') { blackKing = piece; } } } // Place white pieces for (var row = 0; row < 2; row++) { for (var col = 0; col < 8; col++) { var piece = new ChessPiece(initialSetup[row][col], 'white', 7 - row, col); pieces.push(piece); board[7 - row][col].piece = piece; game.addChild(piece); if (piece.type === 'king') { whiteKing = piece; } } } // Place fantasy pieces for black (rows 2-3) for (var row = 0; row < 2; row++) { for (var col = 0; col < 8; col++) { if (fantasySetup[row][col] !== '') { var piece = new ChessPiece(fantasySetup[row][col], 'black', row + 2, col); pieces.push(piece); board[row + 2][col].piece = piece; game.addChild(piece); } } } // Place fantasy pieces for white (rows 4-5) for (var row = 0; row < 2; row++) { for (var col = 0; col < 8; col++) { if (fantasySetup[row][col] !== '') { var piece = new ChessPiece(fantasySetup[row][col], 'white', 5 - row, col); pieces.push(piece); board[5 - row][col].piece = piece; game.addChild(piece); } } } // Add protective pawns on row 3 for black (in front of Guard and Mage) var blackGuardPawn = new ChessPiece('pawn', 'black', 2, 3); pieces.push(blackGuardPawn); board[2][3].piece = blackGuardPawn; game.addChild(blackGuardPawn); var blackMagePawn = new ChessPiece('pawn', 'black', 2, 4); pieces.push(blackMagePawn); board[2][4].piece = blackMagePawn; game.addChild(blackMagePawn); // Add protective pawns on row 5 for white (in front of Guard and Mage) var whiteGuardPawn = new ChessPiece('pawn', 'white', 5, 3); pieces.push(whiteGuardPawn); board[5][3].piece = whiteGuardPawn; game.addChild(whiteGuardPawn); var whiteMagePawn = new ChessPiece('pawn', 'white', 5, 4); pieces.push(whiteMagePawn); board[5][4].piece = whiteMagePawn; game.addChild(whiteMagePawn); // UI Elements var turnDisplay = new Text2('White to move', { size: 60, fill: '#FFFFFF' }); turnDisplay.anchor.set(0.5, 0); LK.gui.top.addChild(turnDisplay); turnDisplay.y = 20; var statusDisplay = new Text2('Select a piece to move', { size: 40, fill: '#FFFFFF' }); statusDisplay.anchor.set(0.5, 1); LK.gui.bottom.addChild(statusDisplay); statusDisplay.y = -20; function isPathClear(fromRow, fromCol, toRow, toCol) { var deltaRow = toRow - fromRow; var deltaCol = toCol - fromCol; var stepRow = deltaRow === 0 ? 0 : deltaRow > 0 ? 1 : -1; var stepCol = deltaCol === 0 ? 0 : deltaCol > 0 ? 1 : -1; var currentRow = fromRow + stepRow; var currentCol = fromCol + stepCol; while (currentRow !== toRow || currentCol !== toCol) { if (board[currentRow][currentCol].piece) { return false; } currentRow += stepRow; currentCol += stepCol; } return true; } function isInCheck(color) { var king = color === 'white' ? whiteKing : blackKing; if (!king) return false; for (var i = 0; i < pieces.length; i++) { var piece = pieces[i]; if (piece.color !== color && piece.isValidMove(king.row, king.col)) { return true; } } return false; } function evaluatePosition() { var pieceValues = { 'pawn': 1, 'knight': 3, 'bishop': 3, 'rook': 5, 'queen': 9, 'king': 100, 'mage': 4, 'guard': 2, 'dragon': 6, 'seer': 2, 'panther': 3 }; // Position value tables for pieces var pawnTable = [[0, 0, 0, 0, 0, 0, 0, 0], [5, 5, 5, 5, 5, 5, 5, 5], [1, 1, 2, 3, 3, 2, 1, 1], [0.5, 0.5, 1, 2.5, 2.5, 1, 0.5, 0.5], [0, 0, 0, 2, 2, 0, 0, 0], [0.5, -0.5, -1, 0, 0, -1, -0.5, 0.5], [0.5, 1, 1, -2, -2, 1, 1, 0.5], [0, 0, 0, 0, 0, 0, 0, 0]]; var knightTable = [[-5, -4, -3, -3, -3, -3, -4, -5], [-4, -2, 0, 0, 0, 0, -2, -4], [-3, 0, 1, 1.5, 1.5, 1, 0, -3], [-3, 0.5, 1.5, 2, 2, 1.5, 0.5, -3], [-3, 0, 1.5, 2, 2, 1.5, 0, -3], [-3, 0.5, 1, 1.5, 1.5, 1, 0.5, -3], [-4, -2, 0, 0.5, 0.5, 0, -2, -4], [-5, -4, -3, -3, -3, -3, -4, -5]]; var bishopTable = [[-2, -1, -1, -1, -1, -1, -1, -2], [-1, 0, 0, 0, 0, 0, 0, -1], [-1, 0, 0.5, 1, 1, 0.5, 0, -1], [-1, 0.5, 0.5, 1, 1, 0.5, 0.5, -1], [-1, 0, 1, 1, 1, 1, 0, -1], [-1, 1, 1, 1, 1, 1, 1, -1], [-1, 0.5, 0, 0, 0, 0, 0.5, -1], [-2, -1, -1, -1, -1, -1, -1, -2]]; var rookTable = [[0, 0, 0, 0, 0, 0, 0, 0], [0.5, 1, 1, 1, 1, 1, 1, 0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [0, 0, 0, 0.5, 0.5, 0, 0, 0]]; var queenTable = [[-2, -1, -1, -0.5, -0.5, -1, -1, -2], [-1, 0, 0, 0, 0, 0, 0, -1], [-1, 0, 0.5, 0.5, 0.5, 0.5, 0, -1], [-0.5, 0, 0.5, 0.5, 0.5, 0.5, 0, -0.5], [0, 0, 0.5, 0.5, 0.5, 0.5, 0, -0.5], [-1, 0.5, 0.5, 0.5, 0.5, 0.5, 0, -1], [-1, 0, 0.5, 0, 0, 0, 0, -1], [-2, -1, -1, -0.5, -0.5, -1, -1, -2]]; var kingTable = [[-3, -4, -4, -5, -5, -4, -4, -3], [-3, -4, -4, -5, -5, -4, -4, -3], [-3, -4, -4, -5, -5, -4, -4, -3], [-3, -4, -4, -5, -5, -4, -4, -3], [-2, -3, -3, -4, -4, -3, -3, -2], [-1, -2, -2, -2, -2, -2, -2, -1], [2, 2, 0, 0, 0, 0, 2, 2], [2, 3, 1, 0, 0, 1, 3, 2]]; var score = 0; for (var i = 0; i < pieces.length; i++) { var piece = pieces[i]; var value = pieceValues[piece.type] || 1; var positionValue = 0; // Add positional values var row = piece.row; var col = piece.col; if (piece.color === 'black') { row = 7 - row; // Flip for black pieces } switch (piece.type) { case 'pawn': positionValue = pawnTable[row][col]; break; case 'knight': positionValue = knightTable[row][col]; break; case 'bishop': positionValue = bishopTable[row][col]; break; case 'rook': positionValue = rookTable[row][col]; break; case 'queen': positionValue = queenTable[row][col]; break; case 'king': positionValue = kingTable[row][col]; break; } if (piece.color === computerColor) { score += value + positionValue; } else { score -= value + positionValue; } } // Add strategic bonuses var mobilityBonus = 0; var computerMoves = getAllValidMoves(computerColor); var opponentMoves = getAllValidMoves(computerColor === 'white' ? 'black' : 'white'); mobilityBonus = (computerMoves.length - opponentMoves.length) * 0.1; score += mobilityBonus; // King safety evaluation var computerKing = computerColor === 'white' ? whiteKing : blackKing; var opponentKing = computerColor === 'white' ? blackKing : whiteKing; if (computerKing && opponentKing) { // Penalize exposed king var kingThreats = 0; for (var i = 0; i < pieces.length; i++) { if (pieces[i].color !== computerColor && pieces[i].isValidMove(computerKing.row, computerKing.col)) { kingThreats++; } } score -= kingThreats * 2; } return score; } function getAllValidMoves(color) { var moves = []; for (var i = 0; i < pieces.length; i++) { var piece = pieces[i]; if (piece.color === color) { for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { if (piece.isValidMove(row, col)) { var targetPiece = board[row][col].piece; if (!targetPiece || targetPiece.color !== piece.color) { moves.push({ piece: piece, fromRow: piece.row, fromCol: piece.col, toRow: row, toCol: col, targetPiece: targetPiece }); } } } } } } return moves; } function minimax(depth, isMaximizing, alpha, beta) { if (depth === 0 || gameOver) { return evaluatePosition(); } var moves = getAllValidMoves(isMaximizing ? computerColor : computerColor === 'white' ? 'black' : 'white'); if (moves.length === 0) { return isMaximizing ? -Infinity : Infinity; } var bestScore = isMaximizing ? -Infinity : Infinity; for (var i = 0; i < moves.length; i++) { var move = moves[i]; // Make move var originalPiece = board[move.toRow][move.toCol].piece; board[move.piece.row][move.piece.col].piece = null; board[move.toRow][move.toCol].piece = move.piece; var oldRow = move.piece.row; var oldCol = move.piece.col; move.piece.row = move.toRow; move.piece.col = move.toCol; // Remove captured piece from pieces array temporarily var capturedIndex = -1; if (originalPiece) { for (var j = 0; j < pieces.length; j++) { if (pieces[j] === originalPiece) { capturedIndex = j; pieces.splice(j, 1); break; } } } var score = minimax(depth - 1, !isMaximizing, alpha, beta); // Unmake move move.piece.row = oldRow; move.piece.col = oldCol; board[oldRow][oldCol].piece = move.piece; board[move.toRow][move.toCol].piece = originalPiece; if (originalPiece && capturedIndex !== -1) { pieces.splice(capturedIndex, 0, originalPiece); } if (isMaximizing) { bestScore = Math.max(bestScore, score); alpha = Math.max(alpha, score); } else { bestScore = Math.min(bestScore, score); beta = Math.min(beta, score); } if (beta <= alpha) { break; // Alpha-beta pruning } } return bestScore; } function makeComputerMove() { if (computerThinking || gameOver) return; computerThinking = true; statusDisplay.setText('Computer thinking...'); LK.setTimeout(function () { var moves = getAllValidMoves(computerColor); if (moves.length === 0) { computerThinking = false; return; } var bestMove = null; var bestScore = -Infinity; var searchDepth = 2; // Fast expert level depth // Define piece values for move sorting var pieceValues = { 'pawn': 1, 'knight': 3, 'bishop': 3, 'rook': 5, 'queen': 9, 'king': 100, 'mage': 4, 'guard': 2, 'dragon': 6, 'seer': 2, 'panther': 3 }; // Order moves for better pruning moves.sort(function (a, b) { var scoreA = 0; var scoreB = 0; // Prioritize captures if (a.targetPiece) { scoreA += (pieceValues[a.targetPiece.type] || 1) * 10; } if (b.targetPiece) { scoreB += (pieceValues[b.targetPiece.type] || 1) * 10; } // Prioritize center control var centerDistanceA = Math.abs(a.toRow - 3.5) + Math.abs(a.toCol - 3.5); var centerDistanceB = Math.abs(b.toRow - 3.5) + Math.abs(b.toCol - 3.5); scoreA += 7 - centerDistanceA; scoreB += 7 - centerDistanceB; return scoreB - scoreA; }); // Use minimax with alpha-beta pruning - limit to top moves for speed var movesToEvaluate = Math.min(moves.length, 15); for (var i = 0; i < movesToEvaluate; i++) { var move = moves[i]; // Make move var originalPiece = board[move.toRow][move.toCol].piece; board[move.piece.row][move.piece.col].piece = null; board[move.toRow][move.toCol].piece = move.piece; var oldRow = move.piece.row; var oldCol = move.piece.col; move.piece.row = move.toRow; move.piece.col = move.toCol; // Remove captured piece from pieces array temporarily var capturedIndex = -1; if (originalPiece) { for (var j = 0; j < pieces.length; j++) { if (pieces[j] === originalPiece) { capturedIndex = j; pieces.splice(j, 1); break; } } } var score = minimax(searchDepth - 1, false, -Infinity, Infinity); // Unmake move move.piece.row = oldRow; move.piece.col = oldCol; board[oldRow][oldCol].piece = move.piece; board[move.toRow][move.toCol].piece = originalPiece; if (originalPiece && capturedIndex !== -1) { pieces.splice(capturedIndex, 0, originalPiece); } if (score > bestScore) { bestScore = score; bestMove = move; } } if (bestMove) { movePiece(bestMove.piece, bestMove.toRow, bestMove.toCol); } computerThinking = false; }, 50); // Ultra fast thinking time for immediate response } function clearHighlights() { for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { board[row][col].setSelected(false); board[row][col].setValidMove(false); } } } function highlightValidMoves(piece) { for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { if (piece.isValidMove(row, col)) { var targetPiece = board[row][col].piece; if (!targetPiece || targetPiece.color !== piece.color) { board[row][col].setValidMove(true); } } } } } function handleSquareClick(row, col) { if (gameOver || computerThinking) return; if (isComputerPlayer && currentPlayer === computerColor) return; var clickedSquare = board[row][col]; var clickedPiece = clickedSquare.piece; if (selectedSquare) { if (selectedSquare.row === row && selectedSquare.col === col) { clearHighlights(); selectedSquare = null; statusDisplay.setText('Select a piece to move'); } else if (clickedPiece && clickedPiece.color === currentPlayer) { clearHighlights(); selectedSquare = clickedSquare; selectedSquare.setSelected(true); highlightValidMoves(clickedPiece); statusDisplay.setText('Select where to move ' + clickedPiece.type); } else { var selectedPiece = selectedSquare.piece; if (selectedPiece && selectedPiece.isValidMove(row, col)) { var targetPiece = clickedSquare.piece; if (!targetPiece || targetPiece.color !== selectedPiece.color) { movePiece(selectedPiece, row, col); } } else { statusDisplay.setText('Invalid move!'); } } } else { if (clickedPiece && clickedPiece.color === currentPlayer) { selectedSquare = clickedSquare; selectedSquare.setSelected(true); highlightValidMoves(clickedPiece); statusDisplay.setText('Select where to move ' + clickedPiece.type); } else { statusDisplay.setText('Select a ' + currentPlayer + ' piece to move'); } } } function movePiece(piece, toRow, toCol) { var targetPiece = board[toRow][toCol].piece; if (targetPiece) { // Mage special ability: convert captured piece if (piece.type === 'mage') { // Check if piece has already been converted if (targetPiece.hasBeenConverted) { statusDisplay.setText('This piece has already been converted!'); return; } // Convert the target piece to the Mage's side targetPiece.color = piece.color; targetPiece.hasBeenConverted = true; targetPiece.pieceGraphics.destroy(); var newAssetName = targetPiece.color + targetPiece.type.charAt(0).toUpperCase() + targetPiece.type.slice(1); targetPiece.pieceGraphics = targetPiece.attachAsset(newAssetName, { anchorX: 0.5, anchorY: 0.5 }); targetPiece.updatePosition(); statusDisplay.setText('Mage converted ' + targetPiece.type + '!'); LK.getSound('capture').play(); // Move the mage to the target square board[piece.row][piece.col].piece = null; board[toRow][toCol].piece = piece; piece.row = toRow; piece.col = toCol; piece.hasMoved = true; piece.updatePosition(); // Move the converted piece to the mage's original position var originalRow = piece.row; var originalCol = piece.col; board[originalRow][originalCol].piece = targetPiece; targetPiece.row = originalRow; targetPiece.col = originalCol; targetPiece.updatePosition(); clearHighlights(); selectedSquare = null; currentPlayer = currentPlayer === 'white' ? 'black' : 'white'; turnDisplay.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' to move'); statusDisplay.setText('Select a piece to move'); return; } else { LK.getSound('capture').play(); targetPiece.destroy(); for (var i = pieces.length - 1; i >= 0; i--) { if (pieces[i] === targetPiece) { pieces.splice(i, 1); break; } } } if (targetPiece && targetPiece.type === 'king') { gameOver = true; statusDisplay.setText(currentPlayer + ' wins!'); if (currentPlayer === 'white') { LK.showYouWin(); } else { LK.showGameOver(); } return; } } else { LK.getSound('move').play(); } board[piece.row][piece.col].piece = null; board[toRow][toCol].piece = piece; piece.row = toRow; piece.col = toCol; piece.hasMoved = true; piece.updatePosition(); // Check for pawn promotion if (piece.type === 'pawn') { var promotionRow = piece.color === 'white' ? 0 : 7; if (piece.row === promotionRow) { // For demo purposes, auto-promote to queen // In full implementation, show promotion dialog piece.type = 'queen'; piece.pieceGraphics.destroy(); var newAssetName = piece.color + 'Queen'; piece.pieceGraphics = piece.attachAsset(newAssetName, { anchorX: 0.5, anchorY: 0.5 }); piece.updatePosition(); statusDisplay.setText('Pawn promoted to Queen!'); } } clearHighlights(); selectedSquare = null; currentPlayer = currentPlayer === 'white' ? 'black' : 'white'; turnDisplay.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' to move'); statusDisplay.setText('Select a piece to move'); if (isInCheck(currentPlayer)) { statusDisplay.setText(currentPlayer + ' is in check!'); LK.effects.flashScreen(0xFF0000, 500); } var capturedPieces = 0; for (var i = 0; i < pieces.length; i++) { if (pieces[i].color !== currentPlayer) { capturedPieces++; } } LK.setScore(16 - capturedPieces); // Trigger computer move if it's computer's turn if (isComputerPlayer && currentPlayer === computerColor) { makeComputerMove(); } } LK.playMusic('chessMusic'); // Enable computer player isComputerPlayer = true; computerColor = 'black'; game.update = function () { // Chess doesn't need continuous updates like RTS games // All game logic is handled by user interactions };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var ChessPiece = Container.expand(function (type, color, row, col) {
var self = Container.call(this);
self.type = type;
self.color = color;
self.row = row;
self.col = col;
self.hasMoved = false;
self.hasBeenConverted = false;
var assetName = color + type.charAt(0).toUpperCase() + type.slice(1);
self.pieceGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.updatePosition = function () {
self.x = 124 + self.col * 240;
self.y = 366 + self.row * 240;
};
self.updatePosition();
self.isValidMove = function (toRow, toCol) {
var deltaRow = toRow - self.row;
var deltaCol = toCol - self.col;
var absDeltaRow = Math.abs(deltaRow);
var absDeltaCol = Math.abs(deltaCol);
switch (self.type) {
case 'pawn':
var direction = self.color === 'white' ? -1 : 1;
var startRow = self.color === 'white' ? 6 : 1;
if (deltaCol === 0) {
if (deltaRow === direction && !board[toRow][toCol].piece) {
return true;
}
if (self.row === startRow && deltaRow === 2 * direction && !board[toRow][toCol].piece) {
return true;
}
} else if (absDeltaCol === 1 && deltaRow === direction) {
if (board[toRow][toCol].piece && board[toRow][toCol].piece.color !== self.color) {
return true;
}
}
break;
case 'rook':
if (deltaRow === 0 || deltaCol === 0) {
return isPathClear(self.row, self.col, toRow, toCol);
}
break;
case 'knight':
if (absDeltaRow === 2 && absDeltaCol === 1 || absDeltaRow === 1 && absDeltaCol === 2) {
return true;
}
break;
case 'bishop':
if (absDeltaRow === absDeltaCol) {
return isPathClear(self.row, self.col, toRow, toCol);
}
break;
case 'queen':
if (deltaRow === 0 || deltaCol === 0 || absDeltaRow === absDeltaCol) {
return isPathClear(self.row, self.col, toRow, toCol);
}
break;
case 'king':
if (absDeltaRow <= 1 && absDeltaCol <= 1) {
return true;
}
break;
case 'mage':
// Mage can move 1 square in any direction when no target
if (!board[toRow][toCol].piece) {
if (absDeltaRow <= 1 && absDeltaCol <= 1) {
return true;
}
}
// Mage can only attack diagonally forward
else if (board[toRow][toCol].piece && board[toRow][toCol].piece.color !== self.color) {
var direction = self.color === 'white' ? -1 : 1;
if (deltaRow === direction && absDeltaCol === 1) {
return true;
}
}
break;
case 'guard':
if (absDeltaRow <= 1 && absDeltaCol <= 1) {
return true;
}
break;
case 'dragon':
if (absDeltaRow === absDeltaCol && absDeltaRow <= 3) {
return isPathClear(self.row, self.col, toRow, toCol);
}
if (absDeltaRow === 2 && absDeltaCol === 1 || absDeltaRow === 1 && absDeltaCol === 2) {
return true;
}
break;
case 'seer':
var direction = self.color === 'white' ? -1 : 1;
if (deltaCol === 0) {
if (deltaRow === direction && !board[toRow][toCol].piece) {
return true;
}
} else if (absDeltaCol === 2 && deltaRow === 2 * direction) {
if (board[toRow][toCol].piece && board[toRow][toCol].piece.color !== self.color) {
return true;
}
}
break;
case 'panther':
if (absDeltaRow === 1 && absDeltaCol === 1) {
return true;
}
break;
}
return false;
};
return self;
});
var ChessSquare = Container.expand(function (row, col) {
var self = Container.call(this);
self.row = row;
self.col = col;
self.isLight = (row + col) % 2 === 0;
self.piece = null;
self.isSelected = false;
self.isValidMove = false;
self.squareSize = 240;
self.squareGraphics = self.attachAsset(self.isLight ? 'lightSquare' : 'darkSquare', {
anchorX: 0.5,
anchorY: 0.5
});
self.selectedGraphics = null;
self.validMoveGraphics = null;
self.x = 124 + col * self.squareSize;
self.y = 366 + row * self.squareSize;
self.setSelected = function (selected) {
self.isSelected = selected;
if (selected) {
if (!self.selectedGraphics) {
self.selectedGraphics = self.attachAsset('selectedSquare', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.selectedGraphics.alpha = 0.5;
} else {
if (self.selectedGraphics) {
self.selectedGraphics.alpha = 0;
}
}
};
self.setValidMove = function (valid) {
self.isValidMove = valid;
if (valid) {
if (!self.validMoveGraphics) {
self.validMoveGraphics = self.attachAsset('validMoveSquare', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.validMoveGraphics.alpha = 0.3;
} else {
if (self.validMoveGraphics) {
self.validMoveGraphics.alpha = 0;
}
}
};
self.down = function (x, y, obj) {
handleSquareClick(self.row, self.col);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4A4A4A
});
/****
* Game Code
****/
// Chess game state
var board = [];
var pieces = [];
var currentPlayer = 'white';
var selectedSquare = null;
var gameOver = false;
var whiteKing = null;
var blackKing = null;
var convertedPieces = [];
var isComputerPlayer = false;
var computerColor = 'black';
var computerThinking = false;
// Initialize the chess board
for (var row = 0; row < 8; row++) {
board[row] = [];
for (var col = 0; col < 8; col++) {
var square = new ChessSquare(row, col);
board[row][col] = square;
game.addChild(square);
}
}
// Initial piece setup with fantasy pieces
var initialSetup = [['rook', 'knight', 'bishop', 'queen', 'king', 'bishop', 'knight', 'rook'], ['pawn', 'dragon', 'pawn', 'guard', 'mage', 'pawn', 'dragon', 'pawn']];
var fantasySetup = [['dragon', 'seer', 'panther', '', '', 'panther', 'seer', 'dragon'], ['', '', '', '', '', '', '', '']];
// Place black pieces
for (var row = 0; row < 2; row++) {
for (var col = 0; col < 8; col++) {
var piece = new ChessPiece(initialSetup[row][col], 'black', row, col);
pieces.push(piece);
board[row][col].piece = piece;
game.addChild(piece);
if (piece.type === 'king') {
blackKing = piece;
}
}
}
// Place white pieces
for (var row = 0; row < 2; row++) {
for (var col = 0; col < 8; col++) {
var piece = new ChessPiece(initialSetup[row][col], 'white', 7 - row, col);
pieces.push(piece);
board[7 - row][col].piece = piece;
game.addChild(piece);
if (piece.type === 'king') {
whiteKing = piece;
}
}
}
// Place fantasy pieces for black (rows 2-3)
for (var row = 0; row < 2; row++) {
for (var col = 0; col < 8; col++) {
if (fantasySetup[row][col] !== '') {
var piece = new ChessPiece(fantasySetup[row][col], 'black', row + 2, col);
pieces.push(piece);
board[row + 2][col].piece = piece;
game.addChild(piece);
}
}
}
// Place fantasy pieces for white (rows 4-5)
for (var row = 0; row < 2; row++) {
for (var col = 0; col < 8; col++) {
if (fantasySetup[row][col] !== '') {
var piece = new ChessPiece(fantasySetup[row][col], 'white', 5 - row, col);
pieces.push(piece);
board[5 - row][col].piece = piece;
game.addChild(piece);
}
}
}
// Add protective pawns on row 3 for black (in front of Guard and Mage)
var blackGuardPawn = new ChessPiece('pawn', 'black', 2, 3);
pieces.push(blackGuardPawn);
board[2][3].piece = blackGuardPawn;
game.addChild(blackGuardPawn);
var blackMagePawn = new ChessPiece('pawn', 'black', 2, 4);
pieces.push(blackMagePawn);
board[2][4].piece = blackMagePawn;
game.addChild(blackMagePawn);
// Add protective pawns on row 5 for white (in front of Guard and Mage)
var whiteGuardPawn = new ChessPiece('pawn', 'white', 5, 3);
pieces.push(whiteGuardPawn);
board[5][3].piece = whiteGuardPawn;
game.addChild(whiteGuardPawn);
var whiteMagePawn = new ChessPiece('pawn', 'white', 5, 4);
pieces.push(whiteMagePawn);
board[5][4].piece = whiteMagePawn;
game.addChild(whiteMagePawn);
// UI Elements
var turnDisplay = new Text2('White to move', {
size: 60,
fill: '#FFFFFF'
});
turnDisplay.anchor.set(0.5, 0);
LK.gui.top.addChild(turnDisplay);
turnDisplay.y = 20;
var statusDisplay = new Text2('Select a piece to move', {
size: 40,
fill: '#FFFFFF'
});
statusDisplay.anchor.set(0.5, 1);
LK.gui.bottom.addChild(statusDisplay);
statusDisplay.y = -20;
function isPathClear(fromRow, fromCol, toRow, toCol) {
var deltaRow = toRow - fromRow;
var deltaCol = toCol - fromCol;
var stepRow = deltaRow === 0 ? 0 : deltaRow > 0 ? 1 : -1;
var stepCol = deltaCol === 0 ? 0 : deltaCol > 0 ? 1 : -1;
var currentRow = fromRow + stepRow;
var currentCol = fromCol + stepCol;
while (currentRow !== toRow || currentCol !== toCol) {
if (board[currentRow][currentCol].piece) {
return false;
}
currentRow += stepRow;
currentCol += stepCol;
}
return true;
}
function isInCheck(color) {
var king = color === 'white' ? whiteKing : blackKing;
if (!king) return false;
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.color !== color && piece.isValidMove(king.row, king.col)) {
return true;
}
}
return false;
}
function evaluatePosition() {
var pieceValues = {
'pawn': 1,
'knight': 3,
'bishop': 3,
'rook': 5,
'queen': 9,
'king': 100,
'mage': 4,
'guard': 2,
'dragon': 6,
'seer': 2,
'panther': 3
};
// Position value tables for pieces
var pawnTable = [[0, 0, 0, 0, 0, 0, 0, 0], [5, 5, 5, 5, 5, 5, 5, 5], [1, 1, 2, 3, 3, 2, 1, 1], [0.5, 0.5, 1, 2.5, 2.5, 1, 0.5, 0.5], [0, 0, 0, 2, 2, 0, 0, 0], [0.5, -0.5, -1, 0, 0, -1, -0.5, 0.5], [0.5, 1, 1, -2, -2, 1, 1, 0.5], [0, 0, 0, 0, 0, 0, 0, 0]];
var knightTable = [[-5, -4, -3, -3, -3, -3, -4, -5], [-4, -2, 0, 0, 0, 0, -2, -4], [-3, 0, 1, 1.5, 1.5, 1, 0, -3], [-3, 0.5, 1.5, 2, 2, 1.5, 0.5, -3], [-3, 0, 1.5, 2, 2, 1.5, 0, -3], [-3, 0.5, 1, 1.5, 1.5, 1, 0.5, -3], [-4, -2, 0, 0.5, 0.5, 0, -2, -4], [-5, -4, -3, -3, -3, -3, -4, -5]];
var bishopTable = [[-2, -1, -1, -1, -1, -1, -1, -2], [-1, 0, 0, 0, 0, 0, 0, -1], [-1, 0, 0.5, 1, 1, 0.5, 0, -1], [-1, 0.5, 0.5, 1, 1, 0.5, 0.5, -1], [-1, 0, 1, 1, 1, 1, 0, -1], [-1, 1, 1, 1, 1, 1, 1, -1], [-1, 0.5, 0, 0, 0, 0, 0.5, -1], [-2, -1, -1, -1, -1, -1, -1, -2]];
var rookTable = [[0, 0, 0, 0, 0, 0, 0, 0], [0.5, 1, 1, 1, 1, 1, 1, 0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [-0.5, 0, 0, 0, 0, 0, 0, -0.5], [0, 0, 0, 0.5, 0.5, 0, 0, 0]];
var queenTable = [[-2, -1, -1, -0.5, -0.5, -1, -1, -2], [-1, 0, 0, 0, 0, 0, 0, -1], [-1, 0, 0.5, 0.5, 0.5, 0.5, 0, -1], [-0.5, 0, 0.5, 0.5, 0.5, 0.5, 0, -0.5], [0, 0, 0.5, 0.5, 0.5, 0.5, 0, -0.5], [-1, 0.5, 0.5, 0.5, 0.5, 0.5, 0, -1], [-1, 0, 0.5, 0, 0, 0, 0, -1], [-2, -1, -1, -0.5, -0.5, -1, -1, -2]];
var kingTable = [[-3, -4, -4, -5, -5, -4, -4, -3], [-3, -4, -4, -5, -5, -4, -4, -3], [-3, -4, -4, -5, -5, -4, -4, -3], [-3, -4, -4, -5, -5, -4, -4, -3], [-2, -3, -3, -4, -4, -3, -3, -2], [-1, -2, -2, -2, -2, -2, -2, -1], [2, 2, 0, 0, 0, 0, 2, 2], [2, 3, 1, 0, 0, 1, 3, 2]];
var score = 0;
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
var value = pieceValues[piece.type] || 1;
var positionValue = 0;
// Add positional values
var row = piece.row;
var col = piece.col;
if (piece.color === 'black') {
row = 7 - row; // Flip for black pieces
}
switch (piece.type) {
case 'pawn':
positionValue = pawnTable[row][col];
break;
case 'knight':
positionValue = knightTable[row][col];
break;
case 'bishop':
positionValue = bishopTable[row][col];
break;
case 'rook':
positionValue = rookTable[row][col];
break;
case 'queen':
positionValue = queenTable[row][col];
break;
case 'king':
positionValue = kingTable[row][col];
break;
}
if (piece.color === computerColor) {
score += value + positionValue;
} else {
score -= value + positionValue;
}
}
// Add strategic bonuses
var mobilityBonus = 0;
var computerMoves = getAllValidMoves(computerColor);
var opponentMoves = getAllValidMoves(computerColor === 'white' ? 'black' : 'white');
mobilityBonus = (computerMoves.length - opponentMoves.length) * 0.1;
score += mobilityBonus;
// King safety evaluation
var computerKing = computerColor === 'white' ? whiteKing : blackKing;
var opponentKing = computerColor === 'white' ? blackKing : whiteKing;
if (computerKing && opponentKing) {
// Penalize exposed king
var kingThreats = 0;
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].color !== computerColor && pieces[i].isValidMove(computerKing.row, computerKing.col)) {
kingThreats++;
}
}
score -= kingThreats * 2;
}
return score;
}
function getAllValidMoves(color) {
var moves = [];
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.color === color) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
if (piece.isValidMove(row, col)) {
var targetPiece = board[row][col].piece;
if (!targetPiece || targetPiece.color !== piece.color) {
moves.push({
piece: piece,
fromRow: piece.row,
fromCol: piece.col,
toRow: row,
toCol: col,
targetPiece: targetPiece
});
}
}
}
}
}
}
return moves;
}
function minimax(depth, isMaximizing, alpha, beta) {
if (depth === 0 || gameOver) {
return evaluatePosition();
}
var moves = getAllValidMoves(isMaximizing ? computerColor : computerColor === 'white' ? 'black' : 'white');
if (moves.length === 0) {
return isMaximizing ? -Infinity : Infinity;
}
var bestScore = isMaximizing ? -Infinity : Infinity;
for (var i = 0; i < moves.length; i++) {
var move = moves[i];
// Make move
var originalPiece = board[move.toRow][move.toCol].piece;
board[move.piece.row][move.piece.col].piece = null;
board[move.toRow][move.toCol].piece = move.piece;
var oldRow = move.piece.row;
var oldCol = move.piece.col;
move.piece.row = move.toRow;
move.piece.col = move.toCol;
// Remove captured piece from pieces array temporarily
var capturedIndex = -1;
if (originalPiece) {
for (var j = 0; j < pieces.length; j++) {
if (pieces[j] === originalPiece) {
capturedIndex = j;
pieces.splice(j, 1);
break;
}
}
}
var score = minimax(depth - 1, !isMaximizing, alpha, beta);
// Unmake move
move.piece.row = oldRow;
move.piece.col = oldCol;
board[oldRow][oldCol].piece = move.piece;
board[move.toRow][move.toCol].piece = originalPiece;
if (originalPiece && capturedIndex !== -1) {
pieces.splice(capturedIndex, 0, originalPiece);
}
if (isMaximizing) {
bestScore = Math.max(bestScore, score);
alpha = Math.max(alpha, score);
} else {
bestScore = Math.min(bestScore, score);
beta = Math.min(beta, score);
}
if (beta <= alpha) {
break; // Alpha-beta pruning
}
}
return bestScore;
}
function makeComputerMove() {
if (computerThinking || gameOver) return;
computerThinking = true;
statusDisplay.setText('Computer thinking...');
LK.setTimeout(function () {
var moves = getAllValidMoves(computerColor);
if (moves.length === 0) {
computerThinking = false;
return;
}
var bestMove = null;
var bestScore = -Infinity;
var searchDepth = 2; // Fast expert level depth
// Define piece values for move sorting
var pieceValues = {
'pawn': 1,
'knight': 3,
'bishop': 3,
'rook': 5,
'queen': 9,
'king': 100,
'mage': 4,
'guard': 2,
'dragon': 6,
'seer': 2,
'panther': 3
};
// Order moves for better pruning
moves.sort(function (a, b) {
var scoreA = 0;
var scoreB = 0;
// Prioritize captures
if (a.targetPiece) {
scoreA += (pieceValues[a.targetPiece.type] || 1) * 10;
}
if (b.targetPiece) {
scoreB += (pieceValues[b.targetPiece.type] || 1) * 10;
}
// Prioritize center control
var centerDistanceA = Math.abs(a.toRow - 3.5) + Math.abs(a.toCol - 3.5);
var centerDistanceB = Math.abs(b.toRow - 3.5) + Math.abs(b.toCol - 3.5);
scoreA += 7 - centerDistanceA;
scoreB += 7 - centerDistanceB;
return scoreB - scoreA;
});
// Use minimax with alpha-beta pruning - limit to top moves for speed
var movesToEvaluate = Math.min(moves.length, 15);
for (var i = 0; i < movesToEvaluate; i++) {
var move = moves[i];
// Make move
var originalPiece = board[move.toRow][move.toCol].piece;
board[move.piece.row][move.piece.col].piece = null;
board[move.toRow][move.toCol].piece = move.piece;
var oldRow = move.piece.row;
var oldCol = move.piece.col;
move.piece.row = move.toRow;
move.piece.col = move.toCol;
// Remove captured piece from pieces array temporarily
var capturedIndex = -1;
if (originalPiece) {
for (var j = 0; j < pieces.length; j++) {
if (pieces[j] === originalPiece) {
capturedIndex = j;
pieces.splice(j, 1);
break;
}
}
}
var score = minimax(searchDepth - 1, false, -Infinity, Infinity);
// Unmake move
move.piece.row = oldRow;
move.piece.col = oldCol;
board[oldRow][oldCol].piece = move.piece;
board[move.toRow][move.toCol].piece = originalPiece;
if (originalPiece && capturedIndex !== -1) {
pieces.splice(capturedIndex, 0, originalPiece);
}
if (score > bestScore) {
bestScore = score;
bestMove = move;
}
}
if (bestMove) {
movePiece(bestMove.piece, bestMove.toRow, bestMove.toCol);
}
computerThinking = false;
}, 50); // Ultra fast thinking time for immediate response
}
function clearHighlights() {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
board[row][col].setSelected(false);
board[row][col].setValidMove(false);
}
}
}
function highlightValidMoves(piece) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
if (piece.isValidMove(row, col)) {
var targetPiece = board[row][col].piece;
if (!targetPiece || targetPiece.color !== piece.color) {
board[row][col].setValidMove(true);
}
}
}
}
}
function handleSquareClick(row, col) {
if (gameOver || computerThinking) return;
if (isComputerPlayer && currentPlayer === computerColor) return;
var clickedSquare = board[row][col];
var clickedPiece = clickedSquare.piece;
if (selectedSquare) {
if (selectedSquare.row === row && selectedSquare.col === col) {
clearHighlights();
selectedSquare = null;
statusDisplay.setText('Select a piece to move');
} else if (clickedPiece && clickedPiece.color === currentPlayer) {
clearHighlights();
selectedSquare = clickedSquare;
selectedSquare.setSelected(true);
highlightValidMoves(clickedPiece);
statusDisplay.setText('Select where to move ' + clickedPiece.type);
} else {
var selectedPiece = selectedSquare.piece;
if (selectedPiece && selectedPiece.isValidMove(row, col)) {
var targetPiece = clickedSquare.piece;
if (!targetPiece || targetPiece.color !== selectedPiece.color) {
movePiece(selectedPiece, row, col);
}
} else {
statusDisplay.setText('Invalid move!');
}
}
} else {
if (clickedPiece && clickedPiece.color === currentPlayer) {
selectedSquare = clickedSquare;
selectedSquare.setSelected(true);
highlightValidMoves(clickedPiece);
statusDisplay.setText('Select where to move ' + clickedPiece.type);
} else {
statusDisplay.setText('Select a ' + currentPlayer + ' piece to move');
}
}
}
function movePiece(piece, toRow, toCol) {
var targetPiece = board[toRow][toCol].piece;
if (targetPiece) {
// Mage special ability: convert captured piece
if (piece.type === 'mage') {
// Check if piece has already been converted
if (targetPiece.hasBeenConverted) {
statusDisplay.setText('This piece has already been converted!');
return;
}
// Convert the target piece to the Mage's side
targetPiece.color = piece.color;
targetPiece.hasBeenConverted = true;
targetPiece.pieceGraphics.destroy();
var newAssetName = targetPiece.color + targetPiece.type.charAt(0).toUpperCase() + targetPiece.type.slice(1);
targetPiece.pieceGraphics = targetPiece.attachAsset(newAssetName, {
anchorX: 0.5,
anchorY: 0.5
});
targetPiece.updatePosition();
statusDisplay.setText('Mage converted ' + targetPiece.type + '!');
LK.getSound('capture').play();
// Move the mage to the target square
board[piece.row][piece.col].piece = null;
board[toRow][toCol].piece = piece;
piece.row = toRow;
piece.col = toCol;
piece.hasMoved = true;
piece.updatePosition();
// Move the converted piece to the mage's original position
var originalRow = piece.row;
var originalCol = piece.col;
board[originalRow][originalCol].piece = targetPiece;
targetPiece.row = originalRow;
targetPiece.col = originalCol;
targetPiece.updatePosition();
clearHighlights();
selectedSquare = null;
currentPlayer = currentPlayer === 'white' ? 'black' : 'white';
turnDisplay.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' to move');
statusDisplay.setText('Select a piece to move');
return;
} else {
LK.getSound('capture').play();
targetPiece.destroy();
for (var i = pieces.length - 1; i >= 0; i--) {
if (pieces[i] === targetPiece) {
pieces.splice(i, 1);
break;
}
}
}
if (targetPiece && targetPiece.type === 'king') {
gameOver = true;
statusDisplay.setText(currentPlayer + ' wins!');
if (currentPlayer === 'white') {
LK.showYouWin();
} else {
LK.showGameOver();
}
return;
}
} else {
LK.getSound('move').play();
}
board[piece.row][piece.col].piece = null;
board[toRow][toCol].piece = piece;
piece.row = toRow;
piece.col = toCol;
piece.hasMoved = true;
piece.updatePosition();
// Check for pawn promotion
if (piece.type === 'pawn') {
var promotionRow = piece.color === 'white' ? 0 : 7;
if (piece.row === promotionRow) {
// For demo purposes, auto-promote to queen
// In full implementation, show promotion dialog
piece.type = 'queen';
piece.pieceGraphics.destroy();
var newAssetName = piece.color + 'Queen';
piece.pieceGraphics = piece.attachAsset(newAssetName, {
anchorX: 0.5,
anchorY: 0.5
});
piece.updatePosition();
statusDisplay.setText('Pawn promoted to Queen!');
}
}
clearHighlights();
selectedSquare = null;
currentPlayer = currentPlayer === 'white' ? 'black' : 'white';
turnDisplay.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' to move');
statusDisplay.setText('Select a piece to move');
if (isInCheck(currentPlayer)) {
statusDisplay.setText(currentPlayer + ' is in check!');
LK.effects.flashScreen(0xFF0000, 500);
}
var capturedPieces = 0;
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].color !== currentPlayer) {
capturedPieces++;
}
}
LK.setScore(16 - capturedPieces);
// Trigger computer move if it's computer's turn
if (isComputerPlayer && currentPlayer === computerColor) {
makeComputerMove();
}
}
LK.playMusic('chessMusic');
// Enable computer player
isComputerPlayer = true;
computerColor = 'black';
game.update = function () {
// Chess doesn't need continuous updates like RTS games
// All game logic is handled by user interactions
};