/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ChessBoard = Container.expand(function () { var self = Container.call(this); self.squares = []; self.highlightSquares = []; // Create board squares for (var row = 0; row < 8; row++) { self.squares[row] = []; for (var col = 0; col < 8; col++) { var isLight = (row + col) % 2 === 1; var square = self.attachAsset(isLight ? 'lightSquare' : 'darkSquare', { x: col * squareSize, y: row * squareSize }); self.squares[row][col] = square; } } self.clearHighlights = function () { for (var i = 0; i < self.highlightSquares.length; i++) { self.highlightSquares[i].destroy(); } self.highlightSquares = []; }; self.highlightSquare = function (row, col, type) { var assetType = type || 'selectedSquare'; var highlight = self.attachAsset(assetType, { x: col * squareSize, y: row * squareSize, alpha: 0.7 }); self.highlightSquares.push(highlight); }; return self; }); var ChessPiece = Container.expand(function (pieceType, color, row, col) { var self = Container.call(this); self.pieceType = pieceType; self.color = color; self.row = row; self.col = col; self.hasMoved = false; var assetId = color + pieceType; var pieceGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.moveTo = function (newRow, newCol) { self.row = newRow; self.col = newCol; self.hasMoved = true; self.x = boardOffsetX + newCol * squareSize + squareSize / 2; self.y = boardOffsetY + newRow * squareSize + squareSize / 2; }; self.getValidMoves = function () { var moves = []; switch (self.pieceType) { case 'Pawn': moves = getPawnMoves(self); break; case 'Rook': moves = getRookMoves(self); break; case 'Knight': moves = getKnightMoves(self); break; case 'Bishop': moves = getBishopMoves(self); break; case 'Queen': moves = getQueenMoves(self); break; case 'King': moves = getKingMoves(self); break; } return moves; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x8B7355 }); /**** * Game Code ****/ // White pieces // Black pieces var squareSize = 128; var boardSize = squareSize * 8; var boardOffsetX = (2048 - boardSize) / 2; var boardOffsetY = (2732 - boardSize) / 2 - 200; var board = game.addChild(new ChessBoard()); board.x = boardOffsetX; board.y = boardOffsetY; var pieces = []; var gameBoard = []; var currentTurn = 'white'; var selectedPiece = null; var whiteKing = null; var blackKing = null; var gameOver = false; var aiEnabled = true; var aiDifficulty = 'medium'; // easy, medium, hard var aiThinking = false; var gameStarted = false; var showingSelection = true; // Initialize game board array for (var row = 0; row < 8; row++) { gameBoard[row] = []; for (var col = 0; col < 8; col++) { gameBoard[row][col] = null; } } // Create coordinate labels var coordinateLabels = []; // Create column labels (A-H) var columnLabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; for (var i = 0; i < 8; i++) { var colLabel = new Text2(columnLabels[i], { size: 40, fill: 0xFFFFFF }); colLabel.anchor.set(0.5, 0.5); colLabel.x = boardOffsetX + i * squareSize + squareSize / 2; colLabel.y = boardOffsetY - 30; game.addChild(colLabel); coordinateLabels.push(colLabel); } // Create row labels (1-8) var rowLabels = ['1', '2', '3', '4', '5', '6', '7', '8']; for (var i = 0; i < 8; i++) { var rowLabel = new Text2(rowLabels[i], { size: 40, fill: 0xFFFFFF }); rowLabel.anchor.set(0.5, 0.5); rowLabel.x = boardOffsetX - 30; rowLabel.y = boardOffsetY + i * squareSize + squareSize / 2; game.addChild(rowLabel); coordinateLabels.push(rowLabel); } // Create turn indicator var turnText = new Text2('Select Difficulty to Start', { size: 80, fill: 0xFFFFFF }); turnText.anchor.set(0.5, 0); LK.gui.top.addChild(turnText); turnText.y = 150; // Create difficulty buttons var difficultyButtons = []; var difficultyLabels = ['Easy', 'Medium', 'Hard', 'Impossible']; var difficultyValues = ['easy', 'medium', 'hard', 'impossible']; var buttonWidth = 180; var buttonHeight = 80; var buttonSpacing = 200; var startX = (2048 - (difficultyLabels.length * buttonSpacing - (buttonSpacing - buttonWidth))) / 2; for (var i = 0; i < difficultyLabels.length; i++) { var button = new Container(); var buttonBg = button.attachAsset('lightSquare', { width: buttonWidth, height: buttonHeight, anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2(difficultyLabels[i], { size: 40, fill: 0x000000 }); buttonText.anchor.set(0.5, 0.5); button.addChild(buttonText); button.x = startX + i * buttonSpacing; button.y = 2732 - 150; button.difficultyValue = difficultyValues[i]; button.buttonBg = buttonBg; button.isSelected = difficultyValues[i] === aiDifficulty; // Highlight selected difficulty (but don't mark as selected initially) if (button.isSelected && gameStarted) { buttonBg.tint = 0x90ee90; } difficultyButtons.push(button); game.addChild(button); } // Reset game function function resetGame() { // Clear all pieces for (var i = pieces.length - 1; i >= 0; i--) { pieces[i].destroy(); } pieces = []; // Clear coordinate labels for (var i = coordinateLabels.length - 1; i >= 0; i--) { coordinateLabels[i].destroy(); } coordinateLabels = []; // Clear game board for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { gameBoard[row][col] = null; } } // Clear highlights board.clearHighlights(); // Reset game state currentTurn = 'white'; selectedPiece = null; whiteKing = null; blackKing = null; gameOver = false; aiThinking = false; gameStarted = false; showingSelection = true; // Reset all difficulty button selection states for (var i = 0; i < difficultyButtons.length; i++) { var button = difficultyButtons[i]; button.buttonBg.tint = 0xffffff; button.isSelected = false; } // Update turn text turnText.setText('Select Difficulty to Start'); // Recreate coordinate labels var columnLabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; for (var i = 0; i < 8; i++) { var colLabel = new Text2(columnLabels[i], { size: 40, fill: 0xFFFFFF }); colLabel.anchor.set(0.5, 0.5); colLabel.x = boardOffsetX + i * squareSize + squareSize / 2; colLabel.y = boardOffsetY - 30; game.addChild(colLabel); coordinateLabels.push(colLabel); } var rowLabels = ['1', '2', '3', '4', '5', '6', '7', '8']; for (var i = 0; i < 8; i++) { var rowLabel = new Text2(rowLabels[i], { size: 40, fill: 0xFFFFFF }); rowLabel.anchor.set(0.5, 0.5); rowLabel.x = boardOffsetX - 30; rowLabel.y = boardOffsetY + i * squareSize + squareSize / 2; game.addChild(rowLabel); coordinateLabels.push(rowLabel); } // Don't setup pieces immediately on reset // setupPieces(); } // Setup initial piece positions function setupPieces() { var initialSetup = [['Rook', 'Knight', 'Bishop', 'Queen', 'King', 'Bishop', 'Knight', 'Rook'], ['Pawn', 'Pawn', 'Pawn', 'Pawn', 'Pawn', 'Pawn', 'Pawn', 'Pawn']]; // 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); piece.x = boardOffsetX + col * squareSize + squareSize / 2; piece.y = boardOffsetY + row * squareSize + squareSize / 2; game.addChild(piece); pieces.push(piece); gameBoard[row][col] = piece; if (piece.pieceType === 'King') { blackKing = piece; } } } // White pieces for (var row = 6; row < 8; row++) { for (var col = 0; col < 8; col++) { var pieceIndex = row === 6 ? 1 : 0; var piece = new ChessPiece(initialSetup[pieceIndex][col], 'white', row, col); piece.x = boardOffsetX + col * squareSize + squareSize / 2; piece.y = boardOffsetY + row * squareSize + squareSize / 2; game.addChild(piece); pieces.push(piece); gameBoard[row][col] = piece; if (piece.pieceType === 'King') { whiteKing = piece; } } } } function isValidPosition(row, col) { return row >= 0 && row < 8 && col >= 0 && col < 8; } function getPawnMoves(piece) { var moves = []; var direction = piece.color === 'white' ? -1 : 1; var startRow = piece.color === 'white' ? 6 : 1; // Move forward one square var newRow = piece.row + direction; if (isValidPosition(newRow, piece.col) && !gameBoard[newRow][piece.col]) { moves.push({ row: newRow, col: piece.col }); // Move forward two squares from starting position if (piece.row === startRow) { newRow = piece.row + direction * 2; if (isValidPosition(newRow, piece.col) && !gameBoard[newRow][piece.col]) { moves.push({ row: newRow, col: piece.col }); } } } // Capture diagonally for (var colOffset = -1; colOffset <= 1; colOffset += 2) { newRow = piece.row + direction; var newCol = piece.col + colOffset; if (isValidPosition(newRow, newCol)) { var targetPiece = gameBoard[newRow][newCol]; if (targetPiece && targetPiece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } } } return moves; } function getRookMoves(piece) { var moves = []; var directions = [[-1, 0], [1, 0], [0, -1], [0, 1]]; for (var d = 0; d < directions.length; d++) { var dir = directions[d]; for (var i = 1; i < 8; i++) { var newRow = piece.row + dir[0] * i; var newCol = piece.col + dir[1] * i; if (!isValidPosition(newRow, newCol)) break; var targetPiece = gameBoard[newRow][newCol]; if (targetPiece) { if (targetPiece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } break; } else { moves.push({ row: newRow, col: newCol }); } } } return moves; } function getKnightMoves(piece) { var moves = []; var knightMoves = [[-2, -1], [-2, 1], [-1, -2], [-1, 2], [1, -2], [1, 2], [2, -1], [2, 1]]; for (var i = 0; i < knightMoves.length; i++) { var move = knightMoves[i]; var newRow = piece.row + move[0]; var newCol = piece.col + move[1]; if (isValidPosition(newRow, newCol)) { var targetPiece = gameBoard[newRow][newCol]; if (!targetPiece || targetPiece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } } } return moves; } function getBishopMoves(piece) { var moves = []; var directions = [[-1, -1], [-1, 1], [1, -1], [1, 1]]; for (var d = 0; d < directions.length; d++) { var dir = directions[d]; for (var i = 1; i < 8; i++) { var newRow = piece.row + dir[0] * i; var newCol = piece.col + dir[1] * i; if (!isValidPosition(newRow, newCol)) break; var targetPiece = gameBoard[newRow][newCol]; if (targetPiece) { if (targetPiece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } break; } else { moves.push({ row: newRow, col: newCol }); } } } return moves; } function getQueenMoves(piece) { var moves = getRookMoves(piece); return moves.concat(getBishopMoves(piece)); } function getKingMoves(piece) { var moves = []; var directions = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]]; for (var i = 0; i < directions.length; i++) { var dir = directions[i]; var newRow = piece.row + dir[0]; var newCol = piece.col + dir[1]; if (isValidPosition(newRow, newCol)) { var targetPiece = gameBoard[newRow][newCol]; if (!targetPiece || targetPiece.color !== piece.color) { moves.push({ row: newRow, col: newCol }); } } } return moves; } 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.parent) { var moves = piece.getValidMoves(); for (var j = 0; j < moves.length; j++) { if (moves[j].row === king.row && moves[j].col === king.col) { return true; } } } } return false; } function isCheckmate(color) { if (!isInCheck(color)) return false; for (var i = 0; i < pieces.length; i++) { var piece = pieces[i]; if (piece.color === color && piece.parent) { var moves = piece.getValidMoves(); for (var j = 0; j < moves.length; j++) { if (isValidMove(piece, moves[j].row, moves[j].col)) { return false; } } } } return true; } function isValidMove(piece, targetRow, targetCol) { if (!isValidPosition(targetRow, targetCol)) return false; var targetPiece = gameBoard[targetRow][targetCol]; if (targetPiece && targetPiece.color === piece.color) return false; // Test if move would put own king in check var originalRow = piece.row; var originalCol = piece.col; var capturedPiece = gameBoard[targetRow][targetCol]; // Simulate move gameBoard[originalRow][originalCol] = null; gameBoard[targetRow][targetCol] = piece; piece.row = targetRow; piece.col = targetCol; var inCheck = isInCheck(piece.color); // Restore position gameBoard[originalRow][originalCol] = piece; gameBoard[targetRow][targetCol] = capturedPiece; piece.row = originalRow; piece.col = originalCol; return !inCheck; } function makeMove(piece, targetRow, targetCol) { var capturedPiece = gameBoard[targetRow][targetCol]; // Remove captured piece if (capturedPiece) { capturedPiece.destroy(); for (var i = pieces.length - 1; i >= 0; i--) { if (pieces[i] === capturedPiece) { pieces.splice(i, 1); break; } } LK.getSound('captureSound').play(); } else { LK.getSound('moveSound').play(); } // Update board gameBoard[piece.row][piece.col] = null; gameBoard[targetRow][targetCol] = piece; // Move piece piece.moveTo(targetRow, targetCol); // Switch turns currentTurn = currentTurn === 'white' ? 'black' : 'white'; turnText.setText(currentTurn === 'white' ? 'White\'s Turn' : 'Black\'s Turn'); // Check for checkmate if (isCheckmate(currentTurn)) { var winner = currentTurn === 'white' ? 'Black' : 'White'; turnText.setText(winner + ' Wins!'); gameOver = true; LK.setTimeout(function () { LK.showYouWin(); }, 2000); } else if (isInCheck(currentTurn)) { board.highlightSquare(currentTurn === 'white' ? whiteKing.row : blackKing.row, currentTurn === 'white' ? whiteKing.col : blackKing.col, 'checkSquare'); } // Trigger AI move if it's black's turn if (!gameOver) { LK.setTimeout(function () { makeAIMove(); }, 100); } } function getPieceAt(x, y) { var boardX = x - boardOffsetX; var boardY = y - boardOffsetY; if (boardX < 0 || boardX >= boardSize || boardY < 0 || boardY >= boardSize) { return null; } var col = Math.floor(boardX / squareSize); var row = Math.floor(boardY / squareSize); return gameBoard[row][col]; } function getBoardPosition(x, y) { var boardX = x - boardOffsetX; var boardY = y - boardOffsetY; if (boardX < 0 || boardX >= boardSize || boardY < 0 || boardY >= boardSize) { return null; } var col = Math.floor(boardX / squareSize); var row = Math.floor(boardY / squareSize); return { row: row, col: col }; } function getPieceValue(pieceType) { var values = { 'Pawn': 1, 'Knight': 3, 'Bishop': 3, 'Rook': 5, 'Queen': 9, 'King': 1000 }; return values[pieceType] || 0; } function evaluatePosition(color) { var score = 0; var opponentColor = color === 'white' ? 'black' : 'white'; // Material evaluation for (var i = 0; i < pieces.length; i++) { var piece = pieces[i]; if (!piece.parent) continue; var value = getPieceValue(piece.pieceType); if (piece.color === color) { score += value; } else { score -= value; } } // Position bonuses for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var piece = gameBoard[row][col]; if (!piece) continue; var positionBonus = 0; // Center control bonus var centerDistance = Math.abs(row - 3.5) + Math.abs(col - 3.5); positionBonus += (7 - centerDistance) * 0.1; // Piece-specific bonuses if (piece.pieceType === 'Pawn') { if (piece.color === 'black') { positionBonus += row * 0.2; // Advance bonus for black pawns } else { positionBonus += (7 - row) * 0.2; // Advance bonus for white pawns } } if (piece.color === color) { score += positionBonus; } else { score -= positionBonus; } } } // Check penalty if (isInCheck(color)) { score -= 5; } if (isInCheck(opponentColor)) { score += 5; } return score; } function getAllValidMoves(color) { var allMoves = []; for (var i = 0; i < pieces.length; i++) { var piece = pieces[i]; if (piece.color !== color || !piece.parent) continue; var moves = piece.getValidMoves(); for (var j = 0; j < moves.length; j++) { if (isValidMove(piece, moves[j].row, moves[j].col)) { allMoves.push({ piece: piece, targetRow: moves[j].row, targetCol: moves[j].col, score: 0 }); } } } return allMoves; } function evaluateMove(move) { var piece = move.piece; var targetRow = move.targetRow; var targetCol = move.targetCol; var score = 0; // Simulate the move var originalRow = piece.row; var originalCol = piece.col; var capturedPiece = gameBoard[targetRow][targetCol]; gameBoard[originalRow][originalCol] = null; gameBoard[targetRow][targetCol] = piece; piece.row = targetRow; piece.col = targetCol; // Evaluate position after move score = evaluatePosition('black'); // Capture bonus if (capturedPiece) { score += getPieceValue(capturedPiece.pieceType) * 2; } // Check if move gives check if (isInCheck('white')) { score += 3; } // Restore position gameBoard[originalRow][originalCol] = piece; gameBoard[targetRow][targetCol] = capturedPiece; piece.row = originalRow; piece.col = originalCol; return score; } function getAIMove() { var moves = getAllValidMoves('black'); if (moves.length === 0) return null; // Evaluate all moves for (var i = 0; i < moves.length; i++) { moves[i].score = evaluateMove(moves[i]); } // Sort moves by score (best first) moves.sort(function (a, b) { return b.score - a.score; }); // Add some randomness based on difficulty var selectedMove; if (aiDifficulty === 'easy') { // Choose from bottom 70% of moves randomly (weaker play) var weakMoves = moves.slice(Math.floor(moves.length * 0.3)); selectedMove = weakMoves[Math.floor(Math.random() * weakMoves.length)]; } else if (aiDifficulty === 'medium') { // Choose from top 40% of moves randomly var topMoves = moves.slice(0, Math.max(1, Math.floor(moves.length * 0.4))); selectedMove = topMoves[Math.floor(Math.random() * topMoves.length)]; } else if (aiDifficulty === 'hard') { // Hard: choose from top 20% with slight randomness var topMoves = moves.slice(0, Math.max(1, Math.floor(moves.length * 0.2))); selectedMove = topMoves[Math.floor(Math.random() * topMoves.length)]; } else { // Impossible: always choose the absolute best move selectedMove = moves[0]; } return selectedMove; } function makeAIMove() { if (currentTurn !== 'black' || !aiEnabled || gameOver || aiThinking) return; aiThinking = true; turnText.setText('Black is thinking...'); LK.setTimeout(function () { var aiMove = getAIMove(); if (aiMove && currentTurn === 'black') { makeMove(aiMove.piece, aiMove.targetRow, aiMove.targetCol); } aiThinking = false; }, Math.random() * 1000 + 500); // Random delay between 0.5-1.5 seconds } game.down = function (x, y, obj) { if (gameOver || aiThinking) return; // Check if a difficulty button was clicked for (var i = 0; i < difficultyButtons.length; i++) { var button = difficultyButtons[i]; var buttonBounds = { left: button.x - 90, right: button.x + 90, top: button.y - 40, bottom: button.y + 40 }; if (x >= buttonBounds.left && x <= buttonBounds.right && y >= buttonBounds.top && y <= buttonBounds.bottom) { // Update difficulty aiDifficulty = button.difficultyValue; // Update button visuals for (var j = 0; j < difficultyButtons.length; j++) { difficultyButtons[j].buttonBg.tint = 0xffffff; difficultyButtons[j].isSelected = false; } button.buttonBg.tint = 0x90ee90; button.isSelected = true; // Start the game if not already started if (!gameStarted) { gameStarted = true; showingSelection = false; turnText.setText('White\'s Turn'); // Hide all non-selected difficulty buttons for (var k = 0; k < difficultyButtons.length; k++) { var btn = difficultyButtons[k]; if (!btn.isSelected) { btn.visible = false; } } setupPieces(); } return; } } if (showingSelection) return; // Don't allow interaction during selection if (currentTurn === 'black' && aiEnabled) return; // Don't allow human to move black pieces var clickedPiece = getPieceAt(x, y); var boardPos = getBoardPosition(x, y); if (!boardPos) return; if (selectedPiece) { // Try to move selected piece if (clickedPiece === selectedPiece) { // Deselect piece selectedPiece = null; board.clearHighlights(); } else { // Check if this is a valid move var validMoves = selectedPiece.getValidMoves(); var isValid = false; for (var i = 0; i < validMoves.length; i++) { if (validMoves[i].row === boardPos.row && validMoves[i].col === boardPos.col) { if (isValidMove(selectedPiece, boardPos.row, boardPos.col)) { isValid = true; break; } } } if (isValid) { makeMove(selectedPiece, boardPos.row, boardPos.col); selectedPiece = null; board.clearHighlights(); } else if (clickedPiece && clickedPiece.color === currentTurn) { // Select new piece selectedPiece = clickedPiece; board.clearHighlights(); board.highlightSquare(selectedPiece.row, selectedPiece.col); var moves = selectedPiece.getValidMoves(); for (var j = 0; j < moves.length; j++) { if (isValidMove(selectedPiece, moves[j].row, moves[j].col)) { board.highlightSquare(moves[j].row, moves[j].col, 'validMoveSquare'); } } } else { selectedPiece = null; board.clearHighlights(); } } } else if (clickedPiece && clickedPiece.color === currentTurn) { // Select piece selectedPiece = clickedPiece; board.highlightSquare(selectedPiece.row, selectedPiece.col); var moves = selectedPiece.getValidMoves(); for (var k = 0; k < moves.length; k++) { if (isValidMove(selectedPiece, moves[k].row, moves[k].col)) { board.highlightSquare(moves[k].row, moves[k].col, 'validMoveSquare'); } } } }; // Don't setup pieces immediately - wait for difficulty selection // setupPieces();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var ChessBoard = Container.expand(function () {
var self = Container.call(this);
self.squares = [];
self.highlightSquares = [];
// Create board squares
for (var row = 0; row < 8; row++) {
self.squares[row] = [];
for (var col = 0; col < 8; col++) {
var isLight = (row + col) % 2 === 1;
var square = self.attachAsset(isLight ? 'lightSquare' : 'darkSquare', {
x: col * squareSize,
y: row * squareSize
});
self.squares[row][col] = square;
}
}
self.clearHighlights = function () {
for (var i = 0; i < self.highlightSquares.length; i++) {
self.highlightSquares[i].destroy();
}
self.highlightSquares = [];
};
self.highlightSquare = function (row, col, type) {
var assetType = type || 'selectedSquare';
var highlight = self.attachAsset(assetType, {
x: col * squareSize,
y: row * squareSize,
alpha: 0.7
});
self.highlightSquares.push(highlight);
};
return self;
});
var ChessPiece = Container.expand(function (pieceType, color, row, col) {
var self = Container.call(this);
self.pieceType = pieceType;
self.color = color;
self.row = row;
self.col = col;
self.hasMoved = false;
var assetId = color + pieceType;
var pieceGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.moveTo = function (newRow, newCol) {
self.row = newRow;
self.col = newCol;
self.hasMoved = true;
self.x = boardOffsetX + newCol * squareSize + squareSize / 2;
self.y = boardOffsetY + newRow * squareSize + squareSize / 2;
};
self.getValidMoves = function () {
var moves = [];
switch (self.pieceType) {
case 'Pawn':
moves = getPawnMoves(self);
break;
case 'Rook':
moves = getRookMoves(self);
break;
case 'Knight':
moves = getKnightMoves(self);
break;
case 'Bishop':
moves = getBishopMoves(self);
break;
case 'Queen':
moves = getQueenMoves(self);
break;
case 'King':
moves = getKingMoves(self);
break;
}
return moves;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8B7355
});
/****
* Game Code
****/
// White pieces
// Black pieces
var squareSize = 128;
var boardSize = squareSize * 8;
var boardOffsetX = (2048 - boardSize) / 2;
var boardOffsetY = (2732 - boardSize) / 2 - 200;
var board = game.addChild(new ChessBoard());
board.x = boardOffsetX;
board.y = boardOffsetY;
var pieces = [];
var gameBoard = [];
var currentTurn = 'white';
var selectedPiece = null;
var whiteKing = null;
var blackKing = null;
var gameOver = false;
var aiEnabled = true;
var aiDifficulty = 'medium'; // easy, medium, hard
var aiThinking = false;
var gameStarted = false;
var showingSelection = true;
// Initialize game board array
for (var row = 0; row < 8; row++) {
gameBoard[row] = [];
for (var col = 0; col < 8; col++) {
gameBoard[row][col] = null;
}
}
// Create coordinate labels
var coordinateLabels = [];
// Create column labels (A-H)
var columnLabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
for (var i = 0; i < 8; i++) {
var colLabel = new Text2(columnLabels[i], {
size: 40,
fill: 0xFFFFFF
});
colLabel.anchor.set(0.5, 0.5);
colLabel.x = boardOffsetX + i * squareSize + squareSize / 2;
colLabel.y = boardOffsetY - 30;
game.addChild(colLabel);
coordinateLabels.push(colLabel);
}
// Create row labels (1-8)
var rowLabels = ['1', '2', '3', '4', '5', '6', '7', '8'];
for (var i = 0; i < 8; i++) {
var rowLabel = new Text2(rowLabels[i], {
size: 40,
fill: 0xFFFFFF
});
rowLabel.anchor.set(0.5, 0.5);
rowLabel.x = boardOffsetX - 30;
rowLabel.y = boardOffsetY + i * squareSize + squareSize / 2;
game.addChild(rowLabel);
coordinateLabels.push(rowLabel);
}
// Create turn indicator
var turnText = new Text2('Select Difficulty to Start', {
size: 80,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
LK.gui.top.addChild(turnText);
turnText.y = 150;
// Create difficulty buttons
var difficultyButtons = [];
var difficultyLabels = ['Easy', 'Medium', 'Hard', 'Impossible'];
var difficultyValues = ['easy', 'medium', 'hard', 'impossible'];
var buttonWidth = 180;
var buttonHeight = 80;
var buttonSpacing = 200;
var startX = (2048 - (difficultyLabels.length * buttonSpacing - (buttonSpacing - buttonWidth))) / 2;
for (var i = 0; i < difficultyLabels.length; i++) {
var button = new Container();
var buttonBg = button.attachAsset('lightSquare', {
width: buttonWidth,
height: buttonHeight,
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(difficultyLabels[i], {
size: 40,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
button.x = startX + i * buttonSpacing;
button.y = 2732 - 150;
button.difficultyValue = difficultyValues[i];
button.buttonBg = buttonBg;
button.isSelected = difficultyValues[i] === aiDifficulty;
// Highlight selected difficulty (but don't mark as selected initially)
if (button.isSelected && gameStarted) {
buttonBg.tint = 0x90ee90;
}
difficultyButtons.push(button);
game.addChild(button);
}
// Reset game function
function resetGame() {
// Clear all pieces
for (var i = pieces.length - 1; i >= 0; i--) {
pieces[i].destroy();
}
pieces = [];
// Clear coordinate labels
for (var i = coordinateLabels.length - 1; i >= 0; i--) {
coordinateLabels[i].destroy();
}
coordinateLabels = [];
// Clear game board
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
gameBoard[row][col] = null;
}
}
// Clear highlights
board.clearHighlights();
// Reset game state
currentTurn = 'white';
selectedPiece = null;
whiteKing = null;
blackKing = null;
gameOver = false;
aiThinking = false;
gameStarted = false;
showingSelection = true;
// Reset all difficulty button selection states
for (var i = 0; i < difficultyButtons.length; i++) {
var button = difficultyButtons[i];
button.buttonBg.tint = 0xffffff;
button.isSelected = false;
}
// Update turn text
turnText.setText('Select Difficulty to Start');
// Recreate coordinate labels
var columnLabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
for (var i = 0; i < 8; i++) {
var colLabel = new Text2(columnLabels[i], {
size: 40,
fill: 0xFFFFFF
});
colLabel.anchor.set(0.5, 0.5);
colLabel.x = boardOffsetX + i * squareSize + squareSize / 2;
colLabel.y = boardOffsetY - 30;
game.addChild(colLabel);
coordinateLabels.push(colLabel);
}
var rowLabels = ['1', '2', '3', '4', '5', '6', '7', '8'];
for (var i = 0; i < 8; i++) {
var rowLabel = new Text2(rowLabels[i], {
size: 40,
fill: 0xFFFFFF
});
rowLabel.anchor.set(0.5, 0.5);
rowLabel.x = boardOffsetX - 30;
rowLabel.y = boardOffsetY + i * squareSize + squareSize / 2;
game.addChild(rowLabel);
coordinateLabels.push(rowLabel);
}
// Don't setup pieces immediately on reset
// setupPieces();
}
// Setup initial piece positions
function setupPieces() {
var initialSetup = [['Rook', 'Knight', 'Bishop', 'Queen', 'King', 'Bishop', 'Knight', 'Rook'], ['Pawn', 'Pawn', 'Pawn', 'Pawn', 'Pawn', 'Pawn', 'Pawn', 'Pawn']];
// 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);
piece.x = boardOffsetX + col * squareSize + squareSize / 2;
piece.y = boardOffsetY + row * squareSize + squareSize / 2;
game.addChild(piece);
pieces.push(piece);
gameBoard[row][col] = piece;
if (piece.pieceType === 'King') {
blackKing = piece;
}
}
}
// White pieces
for (var row = 6; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var pieceIndex = row === 6 ? 1 : 0;
var piece = new ChessPiece(initialSetup[pieceIndex][col], 'white', row, col);
piece.x = boardOffsetX + col * squareSize + squareSize / 2;
piece.y = boardOffsetY + row * squareSize + squareSize / 2;
game.addChild(piece);
pieces.push(piece);
gameBoard[row][col] = piece;
if (piece.pieceType === 'King') {
whiteKing = piece;
}
}
}
}
function isValidPosition(row, col) {
return row >= 0 && row < 8 && col >= 0 && col < 8;
}
function getPawnMoves(piece) {
var moves = [];
var direction = piece.color === 'white' ? -1 : 1;
var startRow = piece.color === 'white' ? 6 : 1;
// Move forward one square
var newRow = piece.row + direction;
if (isValidPosition(newRow, piece.col) && !gameBoard[newRow][piece.col]) {
moves.push({
row: newRow,
col: piece.col
});
// Move forward two squares from starting position
if (piece.row === startRow) {
newRow = piece.row + direction * 2;
if (isValidPosition(newRow, piece.col) && !gameBoard[newRow][piece.col]) {
moves.push({
row: newRow,
col: piece.col
});
}
}
}
// Capture diagonally
for (var colOffset = -1; colOffset <= 1; colOffset += 2) {
newRow = piece.row + direction;
var newCol = piece.col + colOffset;
if (isValidPosition(newRow, newCol)) {
var targetPiece = gameBoard[newRow][newCol];
if (targetPiece && targetPiece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
return moves;
}
function getRookMoves(piece) {
var moves = [];
var directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
for (var d = 0; d < directions.length; d++) {
var dir = directions[d];
for (var i = 1; i < 8; i++) {
var newRow = piece.row + dir[0] * i;
var newCol = piece.col + dir[1] * i;
if (!isValidPosition(newRow, newCol)) break;
var targetPiece = gameBoard[newRow][newCol];
if (targetPiece) {
if (targetPiece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
break;
} else {
moves.push({
row: newRow,
col: newCol
});
}
}
}
return moves;
}
function getKnightMoves(piece) {
var moves = [];
var knightMoves = [[-2, -1], [-2, 1], [-1, -2], [-1, 2], [1, -2], [1, 2], [2, -1], [2, 1]];
for (var i = 0; i < knightMoves.length; i++) {
var move = knightMoves[i];
var newRow = piece.row + move[0];
var newCol = piece.col + move[1];
if (isValidPosition(newRow, newCol)) {
var targetPiece = gameBoard[newRow][newCol];
if (!targetPiece || targetPiece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
return moves;
}
function getBishopMoves(piece) {
var moves = [];
var directions = [[-1, -1], [-1, 1], [1, -1], [1, 1]];
for (var d = 0; d < directions.length; d++) {
var dir = directions[d];
for (var i = 1; i < 8; i++) {
var newRow = piece.row + dir[0] * i;
var newCol = piece.col + dir[1] * i;
if (!isValidPosition(newRow, newCol)) break;
var targetPiece = gameBoard[newRow][newCol];
if (targetPiece) {
if (targetPiece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
break;
} else {
moves.push({
row: newRow,
col: newCol
});
}
}
}
return moves;
}
function getQueenMoves(piece) {
var moves = getRookMoves(piece);
return moves.concat(getBishopMoves(piece));
}
function getKingMoves(piece) {
var moves = [];
var directions = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
var newRow = piece.row + dir[0];
var newCol = piece.col + dir[1];
if (isValidPosition(newRow, newCol)) {
var targetPiece = gameBoard[newRow][newCol];
if (!targetPiece || targetPiece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
return moves;
}
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.parent) {
var moves = piece.getValidMoves();
for (var j = 0; j < moves.length; j++) {
if (moves[j].row === king.row && moves[j].col === king.col) {
return true;
}
}
}
}
return false;
}
function isCheckmate(color) {
if (!isInCheck(color)) return false;
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.color === color && piece.parent) {
var moves = piece.getValidMoves();
for (var j = 0; j < moves.length; j++) {
if (isValidMove(piece, moves[j].row, moves[j].col)) {
return false;
}
}
}
}
return true;
}
function isValidMove(piece, targetRow, targetCol) {
if (!isValidPosition(targetRow, targetCol)) return false;
var targetPiece = gameBoard[targetRow][targetCol];
if (targetPiece && targetPiece.color === piece.color) return false;
// Test if move would put own king in check
var originalRow = piece.row;
var originalCol = piece.col;
var capturedPiece = gameBoard[targetRow][targetCol];
// Simulate move
gameBoard[originalRow][originalCol] = null;
gameBoard[targetRow][targetCol] = piece;
piece.row = targetRow;
piece.col = targetCol;
var inCheck = isInCheck(piece.color);
// Restore position
gameBoard[originalRow][originalCol] = piece;
gameBoard[targetRow][targetCol] = capturedPiece;
piece.row = originalRow;
piece.col = originalCol;
return !inCheck;
}
function makeMove(piece, targetRow, targetCol) {
var capturedPiece = gameBoard[targetRow][targetCol];
// Remove captured piece
if (capturedPiece) {
capturedPiece.destroy();
for (var i = pieces.length - 1; i >= 0; i--) {
if (pieces[i] === capturedPiece) {
pieces.splice(i, 1);
break;
}
}
LK.getSound('captureSound').play();
} else {
LK.getSound('moveSound').play();
}
// Update board
gameBoard[piece.row][piece.col] = null;
gameBoard[targetRow][targetCol] = piece;
// Move piece
piece.moveTo(targetRow, targetCol);
// Switch turns
currentTurn = currentTurn === 'white' ? 'black' : 'white';
turnText.setText(currentTurn === 'white' ? 'White\'s Turn' : 'Black\'s Turn');
// Check for checkmate
if (isCheckmate(currentTurn)) {
var winner = currentTurn === 'white' ? 'Black' : 'White';
turnText.setText(winner + ' Wins!');
gameOver = true;
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
} else if (isInCheck(currentTurn)) {
board.highlightSquare(currentTurn === 'white' ? whiteKing.row : blackKing.row, currentTurn === 'white' ? whiteKing.col : blackKing.col, 'checkSquare');
}
// Trigger AI move if it's black's turn
if (!gameOver) {
LK.setTimeout(function () {
makeAIMove();
}, 100);
}
}
function getPieceAt(x, y) {
var boardX = x - boardOffsetX;
var boardY = y - boardOffsetY;
if (boardX < 0 || boardX >= boardSize || boardY < 0 || boardY >= boardSize) {
return null;
}
var col = Math.floor(boardX / squareSize);
var row = Math.floor(boardY / squareSize);
return gameBoard[row][col];
}
function getBoardPosition(x, y) {
var boardX = x - boardOffsetX;
var boardY = y - boardOffsetY;
if (boardX < 0 || boardX >= boardSize || boardY < 0 || boardY >= boardSize) {
return null;
}
var col = Math.floor(boardX / squareSize);
var row = Math.floor(boardY / squareSize);
return {
row: row,
col: col
};
}
function getPieceValue(pieceType) {
var values = {
'Pawn': 1,
'Knight': 3,
'Bishop': 3,
'Rook': 5,
'Queen': 9,
'King': 1000
};
return values[pieceType] || 0;
}
function evaluatePosition(color) {
var score = 0;
var opponentColor = color === 'white' ? 'black' : 'white';
// Material evaluation
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (!piece.parent) continue;
var value = getPieceValue(piece.pieceType);
if (piece.color === color) {
score += value;
} else {
score -= value;
}
}
// Position bonuses
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = gameBoard[row][col];
if (!piece) continue;
var positionBonus = 0;
// Center control bonus
var centerDistance = Math.abs(row - 3.5) + Math.abs(col - 3.5);
positionBonus += (7 - centerDistance) * 0.1;
// Piece-specific bonuses
if (piece.pieceType === 'Pawn') {
if (piece.color === 'black') {
positionBonus += row * 0.2; // Advance bonus for black pawns
} else {
positionBonus += (7 - row) * 0.2; // Advance bonus for white pawns
}
}
if (piece.color === color) {
score += positionBonus;
} else {
score -= positionBonus;
}
}
}
// Check penalty
if (isInCheck(color)) {
score -= 5;
}
if (isInCheck(opponentColor)) {
score += 5;
}
return score;
}
function getAllValidMoves(color) {
var allMoves = [];
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.color !== color || !piece.parent) continue;
var moves = piece.getValidMoves();
for (var j = 0; j < moves.length; j++) {
if (isValidMove(piece, moves[j].row, moves[j].col)) {
allMoves.push({
piece: piece,
targetRow: moves[j].row,
targetCol: moves[j].col,
score: 0
});
}
}
}
return allMoves;
}
function evaluateMove(move) {
var piece = move.piece;
var targetRow = move.targetRow;
var targetCol = move.targetCol;
var score = 0;
// Simulate the move
var originalRow = piece.row;
var originalCol = piece.col;
var capturedPiece = gameBoard[targetRow][targetCol];
gameBoard[originalRow][originalCol] = null;
gameBoard[targetRow][targetCol] = piece;
piece.row = targetRow;
piece.col = targetCol;
// Evaluate position after move
score = evaluatePosition('black');
// Capture bonus
if (capturedPiece) {
score += getPieceValue(capturedPiece.pieceType) * 2;
}
// Check if move gives check
if (isInCheck('white')) {
score += 3;
}
// Restore position
gameBoard[originalRow][originalCol] = piece;
gameBoard[targetRow][targetCol] = capturedPiece;
piece.row = originalRow;
piece.col = originalCol;
return score;
}
function getAIMove() {
var moves = getAllValidMoves('black');
if (moves.length === 0) return null;
// Evaluate all moves
for (var i = 0; i < moves.length; i++) {
moves[i].score = evaluateMove(moves[i]);
}
// Sort moves by score (best first)
moves.sort(function (a, b) {
return b.score - a.score;
});
// Add some randomness based on difficulty
var selectedMove;
if (aiDifficulty === 'easy') {
// Choose from bottom 70% of moves randomly (weaker play)
var weakMoves = moves.slice(Math.floor(moves.length * 0.3));
selectedMove = weakMoves[Math.floor(Math.random() * weakMoves.length)];
} else if (aiDifficulty === 'medium') {
// Choose from top 40% of moves randomly
var topMoves = moves.slice(0, Math.max(1, Math.floor(moves.length * 0.4)));
selectedMove = topMoves[Math.floor(Math.random() * topMoves.length)];
} else if (aiDifficulty === 'hard') {
// Hard: choose from top 20% with slight randomness
var topMoves = moves.slice(0, Math.max(1, Math.floor(moves.length * 0.2)));
selectedMove = topMoves[Math.floor(Math.random() * topMoves.length)];
} else {
// Impossible: always choose the absolute best move
selectedMove = moves[0];
}
return selectedMove;
}
function makeAIMove() {
if (currentTurn !== 'black' || !aiEnabled || gameOver || aiThinking) return;
aiThinking = true;
turnText.setText('Black is thinking...');
LK.setTimeout(function () {
var aiMove = getAIMove();
if (aiMove && currentTurn === 'black') {
makeMove(aiMove.piece, aiMove.targetRow, aiMove.targetCol);
}
aiThinking = false;
}, Math.random() * 1000 + 500); // Random delay between 0.5-1.5 seconds
}
game.down = function (x, y, obj) {
if (gameOver || aiThinking) return;
// Check if a difficulty button was clicked
for (var i = 0; i < difficultyButtons.length; i++) {
var button = difficultyButtons[i];
var buttonBounds = {
left: button.x - 90,
right: button.x + 90,
top: button.y - 40,
bottom: button.y + 40
};
if (x >= buttonBounds.left && x <= buttonBounds.right && y >= buttonBounds.top && y <= buttonBounds.bottom) {
// Update difficulty
aiDifficulty = button.difficultyValue;
// Update button visuals
for (var j = 0; j < difficultyButtons.length; j++) {
difficultyButtons[j].buttonBg.tint = 0xffffff;
difficultyButtons[j].isSelected = false;
}
button.buttonBg.tint = 0x90ee90;
button.isSelected = true;
// Start the game if not already started
if (!gameStarted) {
gameStarted = true;
showingSelection = false;
turnText.setText('White\'s Turn');
// Hide all non-selected difficulty buttons
for (var k = 0; k < difficultyButtons.length; k++) {
var btn = difficultyButtons[k];
if (!btn.isSelected) {
btn.visible = false;
}
}
setupPieces();
}
return;
}
}
if (showingSelection) return; // Don't allow interaction during selection
if (currentTurn === 'black' && aiEnabled) return; // Don't allow human to move black pieces
var clickedPiece = getPieceAt(x, y);
var boardPos = getBoardPosition(x, y);
if (!boardPos) return;
if (selectedPiece) {
// Try to move selected piece
if (clickedPiece === selectedPiece) {
// Deselect piece
selectedPiece = null;
board.clearHighlights();
} else {
// Check if this is a valid move
var validMoves = selectedPiece.getValidMoves();
var isValid = false;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].row === boardPos.row && validMoves[i].col === boardPos.col) {
if (isValidMove(selectedPiece, boardPos.row, boardPos.col)) {
isValid = true;
break;
}
}
}
if (isValid) {
makeMove(selectedPiece, boardPos.row, boardPos.col);
selectedPiece = null;
board.clearHighlights();
} else if (clickedPiece && clickedPiece.color === currentTurn) {
// Select new piece
selectedPiece = clickedPiece;
board.clearHighlights();
board.highlightSquare(selectedPiece.row, selectedPiece.col);
var moves = selectedPiece.getValidMoves();
for (var j = 0; j < moves.length; j++) {
if (isValidMove(selectedPiece, moves[j].row, moves[j].col)) {
board.highlightSquare(moves[j].row, moves[j].col, 'validMoveSquare');
}
}
} else {
selectedPiece = null;
board.clearHighlights();
}
}
} else if (clickedPiece && clickedPiece.color === currentTurn) {
// Select piece
selectedPiece = clickedPiece;
board.highlightSquare(selectedPiece.row, selectedPiece.col);
var moves = selectedPiece.getValidMoves();
for (var k = 0; k < moves.length; k++) {
if (isValidMove(selectedPiece, moves[k].row, moves[k].col)) {
board.highlightSquare(moves[k].row, moves[k].col, 'validMoveSquare');
}
}
}
};
// Don't setup pieces immediately - wait for difficulty selection
// setupPieces();
White Bishop Chess. In-Game asset. 2d. High contrast. No shadows
White Queen Chess. In-Game asset. 2d. High contrast. No shadows
White King Chess. In-Game asset. 2d. High contrast. No shadows
White Knight Chess But let it be white on the inside. In-Game asset. 2d. High contrast. No shadows
White Rook Chess. In-Game asset. 2d. High contrast. No shadows
White Pawn Chess. In-Game asset. 2d. High contrast. No shadows
Black bishop Chess. In-Game asset. 2d. High contrast. No shadows
Black rook chess. In-Game asset. 2d. High contrast. No shadows
Black Pawn Chess. In-Game asset. 2d. High contrast. No shadows
Black king Chess. In-Game asset. 2d. High contrast. No shadows
Black Knight Chess. In-Game asset. 2d. High contrast. No shadows
Black Queen Chess. In-Game asset. 2d. High contrast. No shadows