/**** * Classes ****/ var ChessPiece = Container.expand(function (type, color) { var self = Container.call(this); self.type = type; self.color = color; self.hasMoved = false; var assetName = color + type.charAt(0).toUpperCase() + type.slice(1); var pieceGraphic = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.getValidMoves = function (board, fromRow, fromCol) { var moves = []; switch (self.type) { case 'pawn': moves = getPawnMoves(board, fromRow, fromCol, self.color); break; case 'rook': moves = getRookMoves(board, fromRow, fromCol, self.color); break; case 'knight': moves = getKnightMoves(board, fromRow, fromCol, self.color); break; case 'bishop': moves = getBishopMoves(board, fromRow, fromCol, self.color); break; case 'queen': moves = getQueenMoves(board, fromRow, fromCol, self.color); break; case 'king': moves = getKingMoves(board, fromRow, fromCol, self.color); break; } return moves; }; return self; }); var ChessSquare = Container.expand(function (row, col) { var self = Container.call(this); self.row = row; self.col = col; self.piece = null; self.isLight = (row + col) % 2 === 0; self.isHighlighted = false; self.isSelected = false; var squareGraphic = self.attachAsset(self.isLight ? 'lightSquare' : 'darkSquare', { anchorX: 0.5, anchorY: 0.5 }); var highlightGraphic = self.attachAsset('highlightSquare', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); var selectedGraphic = self.attachAsset('selectedSquare', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.setHighlight = function (highlight) { self.isHighlighted = highlight; highlightGraphic.alpha = highlight ? 0.5 : 0; }; self.setSelected = function (selected) { self.isSelected = selected; selectedGraphic.alpha = selected ? 0.5 : 0; }; self.setPiece = function (piece) { if (self.piece) { self.removeChild(self.piece); } self.piece = piece; if (piece) { self.addChild(piece); } }; self.down = function (x, y, obj) { handleSquareClick(self); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x8B4513 }); /**** * Game Code ****/ var boardSize = 1800; var squareSize = 225; var boardStartX = (2048 - boardSize) / 2; var boardStartY = (2732 - boardSize) / 2; var board = []; var selectedSquare = null; var currentPlayer = 'white'; var gameOver = false; var turnText = new Text2('White to move', { size: 80, fill: 0xFFFFFF }); turnText.anchor.set(0.5, 0); LK.gui.top.addChild(turnText); function initializeBoard() { for (var row = 0; row < 8; row++) { board[row] = []; for (var col = 0; col < 8; col++) { var square = new ChessSquare(row, col); square.x = boardStartX + col * squareSize + squareSize / 2; square.y = boardStartY + row * squareSize + squareSize / 2; board[row][col] = square; game.addChild(square); } } } function setupPieces() { var pieceOrder = ['rook', 'knight', 'bishop', 'queen', 'king', 'bishop', 'knight', 'rook']; for (var col = 0; col < 8; col++) { board[0][col].setPiece(new ChessPiece(pieceOrder[col], 'black')); board[1][col].setPiece(new ChessPiece('pawn', 'black')); board[6][col].setPiece(new ChessPiece('pawn', 'white')); board[7][col].setPiece(new ChessPiece(pieceOrder[col], 'white')); } } function handleSquareClick(square) { if (gameOver) return; // Only allow player to control white pieces if (currentPlayer === 'black') return; if (selectedSquare) { if (selectedSquare === square) { clearSelection(); } else if (square.isHighlighted) { movePiece(selectedSquare, square); clearSelection(); switchPlayer(); // Trigger AI move after player move if (currentPlayer === 'black' && !gameOver) { LK.setTimeout(function () { makeAIMove(); }, 500); } } else { clearSelection(); if (square.piece && square.piece.color === 'white') { selectSquare(square); } } } else { if (square.piece && square.piece.color === 'white') { selectSquare(square); } } } function selectSquare(square) { selectedSquare = square; square.setSelected(true); var validMoves = square.piece.getValidMoves(board, square.row, square.col); for (var i = 0; i < validMoves.length; i++) { var move = validMoves[i]; board[move.row][move.col].setHighlight(true); } } function clearSelection() { if (selectedSquare) { selectedSquare.setSelected(false); selectedSquare = null; } for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { board[row][col].setHighlight(false); } } } function movePiece(fromSquare, toSquare) { var piece = fromSquare.piece; if (toSquare.piece) { LK.setScore(LK.getScore() + getPieceValue(toSquare.piece.type)); } toSquare.setPiece(piece); fromSquare.setPiece(null); piece.hasMoved = true; if (isCheckmate(currentPlayer === 'white' ? 'black' : 'white')) { gameOver = true; turnText.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' wins!'); LK.showYouWin(); } } function switchPlayer() { currentPlayer = currentPlayer === 'white' ? 'black' : 'white'; turnText.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' to move'); } function getPieceValue(type) { switch (type) { case 'pawn': return 1; case 'knight': return 3; case 'bishop': return 3; case 'rook': return 5; case 'queen': return 9; case 'king': return 0; default: return 0; } } function isValidSquare(row, col) { return row >= 0 && row < 8 && col >= 0 && col < 8; } function getPawnMoves(board, row, col, color) { var moves = []; var direction = color === 'white' ? -1 : 1; var startRow = color === 'white' ? 6 : 1; var newRow = row + direction; if (isValidSquare(newRow, col) && !board[newRow][col].piece) { moves.push({ row: newRow, col: col }); if (row === startRow) { newRow = row + 2 * direction; if (isValidSquare(newRow, col) && !board[newRow][col].piece) { moves.push({ row: newRow, col: col }); } } } for (var i = -1; i <= 1; i += 2) { var newCol = col + i; newRow = row + direction; if (isValidSquare(newRow, newCol) && board[newRow][newCol].piece && board[newRow][newCol].piece.color !== color) { moves.push({ row: newRow, col: newCol }); } } return moves; } function getRookMoves(board, row, col, color) { var moves = []; var directions = [[0, 1], [0, -1], [1, 0], [-1, 0]]; for (var d = 0; d < directions.length; d++) { var dir = directions[d]; for (var i = 1; i < 8; i++) { var newRow = row + dir[0] * i; var newCol = col + dir[1] * i; if (!isValidSquare(newRow, newCol)) break; if (board[newRow][newCol].piece) { if (board[newRow][newCol].piece.color !== color) { moves.push({ row: newRow, col: newCol }); } break; } moves.push({ row: newRow, col: newCol }); } } return moves; } function getKnightMoves(board, row, col, color) { var moves = []; var knightMoves = [[2, 1], [2, -1], [-2, 1], [-2, -1], [1, 2], [1, -2], [-1, 2], [-1, -2]]; for (var i = 0; i < knightMoves.length; i++) { var move = knightMoves[i]; var newRow = row + move[0]; var newCol = col + move[1]; if (isValidSquare(newRow, newCol)) { if (!board[newRow][newCol].piece || board[newRow][newCol].piece.color !== color) { moves.push({ row: newRow, col: newCol }); } } } return moves; } function getBishopMoves(board, row, col, color) { 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 = row + dir[0] * i; var newCol = col + dir[1] * i; if (!isValidSquare(newRow, newCol)) break; if (board[newRow][newCol].piece) { if (board[newRow][newCol].piece.color !== color) { moves.push({ row: newRow, col: newCol }); } break; } moves.push({ row: newRow, col: newCol }); } } return moves; } function getQueenMoves(board, row, col, color) { var rookMoves = getRookMoves(board, row, col, color); var bishopMoves = getBishopMoves(board, row, col, color); return rookMoves.concat(bishopMoves); } function getKingMoves(board, row, col, color) { var moves = []; var directions = [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]]; for (var i = 0; i < directions.length; i++) { var dir = directions[i]; var newRow = row + dir[0]; var newCol = col + dir[1]; if (isValidSquare(newRow, newCol)) { if (!board[newRow][newCol].piece || board[newRow][newCol].piece.color !== color) { moves.push({ row: newRow, col: newCol }); } } } return moves; } function findKing(color) { for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var piece = board[row][col].piece; if (piece && piece.type === 'king' && piece.color === color) { return { row: row, col: col }; } } } return null; } function isInCheck(color) { var king = findKing(color); if (!king) return false; var enemyColor = color === 'white' ? 'black' : 'white'; for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var piece = board[row][col].piece; if (piece && piece.color === enemyColor) { var moves = piece.getValidMoves(board, row, col); for (var i = 0; i < moves.length; i++) { if (moves[i].row === king.row && moves[i].col === king.col) { return true; } } } } } return false; } function isCheckmate(color) { if (!isInCheck(color)) return false; for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var piece = board[row][col].piece; if (piece && piece.color === color) { var moves = piece.getValidMoves(board, row, col); if (moves.length > 0) { return false; } } } } return true; } function getAllValidMoves(color) { var allMoves = []; for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { var piece = board[row][col].piece; if (piece && piece.color === color) { var moves = piece.getValidMoves(board, row, col); for (var i = 0; i < moves.length; i++) { allMoves.push({ fromRow: row, fromCol: col, toRow: moves[i].row, toCol: moves[i].col, piece: piece }); } } } } return allMoves; } function evaluateMove(move) { var score = 0; var targetSquare = board[move.toRow][move.toCol]; // Capture bonus if (targetSquare.piece) { score += getPieceValue(targetSquare.piece.type) * 10; } // Center control bonus var centerDistance = Math.abs(move.toRow - 3.5) + Math.abs(move.toCol - 3.5); score += (7 - centerDistance) * 2; // Random factor to add variety score += Math.random() * 5; return score; } function makeAIMove() { if (gameOver || currentPlayer !== 'black') return; var possibleMoves = getAllValidMoves('black'); if (possibleMoves.length === 0) return; // Find best move var bestMove = possibleMoves[0]; var bestScore = evaluateMove(bestMove); for (var i = 1; i < possibleMoves.length; i++) { var score = evaluateMove(possibleMoves[i]); if (score > bestScore) { bestScore = score; bestMove = possibleMoves[i]; } } // Execute the move var fromSquare = board[bestMove.fromRow][bestMove.fromCol]; var toSquare = board[bestMove.toRow][bestMove.toCol]; movePiece(fromSquare, toSquare); switchPlayer(); } initializeBoard(); setupPieces();
/****
* Classes
****/
var ChessPiece = Container.expand(function (type, color) {
var self = Container.call(this);
self.type = type;
self.color = color;
self.hasMoved = false;
var assetName = color + type.charAt(0).toUpperCase() + type.slice(1);
var pieceGraphic = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.getValidMoves = function (board, fromRow, fromCol) {
var moves = [];
switch (self.type) {
case 'pawn':
moves = getPawnMoves(board, fromRow, fromCol, self.color);
break;
case 'rook':
moves = getRookMoves(board, fromRow, fromCol, self.color);
break;
case 'knight':
moves = getKnightMoves(board, fromRow, fromCol, self.color);
break;
case 'bishop':
moves = getBishopMoves(board, fromRow, fromCol, self.color);
break;
case 'queen':
moves = getQueenMoves(board, fromRow, fromCol, self.color);
break;
case 'king':
moves = getKingMoves(board, fromRow, fromCol, self.color);
break;
}
return moves;
};
return self;
});
var ChessSquare = Container.expand(function (row, col) {
var self = Container.call(this);
self.row = row;
self.col = col;
self.piece = null;
self.isLight = (row + col) % 2 === 0;
self.isHighlighted = false;
self.isSelected = false;
var squareGraphic = self.attachAsset(self.isLight ? 'lightSquare' : 'darkSquare', {
anchorX: 0.5,
anchorY: 0.5
});
var highlightGraphic = self.attachAsset('highlightSquare', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
var selectedGraphic = self.attachAsset('selectedSquare', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.setHighlight = function (highlight) {
self.isHighlighted = highlight;
highlightGraphic.alpha = highlight ? 0.5 : 0;
};
self.setSelected = function (selected) {
self.isSelected = selected;
selectedGraphic.alpha = selected ? 0.5 : 0;
};
self.setPiece = function (piece) {
if (self.piece) {
self.removeChild(self.piece);
}
self.piece = piece;
if (piece) {
self.addChild(piece);
}
};
self.down = function (x, y, obj) {
handleSquareClick(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8B4513
});
/****
* Game Code
****/
var boardSize = 1800;
var squareSize = 225;
var boardStartX = (2048 - boardSize) / 2;
var boardStartY = (2732 - boardSize) / 2;
var board = [];
var selectedSquare = null;
var currentPlayer = 'white';
var gameOver = false;
var turnText = new Text2('White to move', {
size: 80,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
LK.gui.top.addChild(turnText);
function initializeBoard() {
for (var row = 0; row < 8; row++) {
board[row] = [];
for (var col = 0; col < 8; col++) {
var square = new ChessSquare(row, col);
square.x = boardStartX + col * squareSize + squareSize / 2;
square.y = boardStartY + row * squareSize + squareSize / 2;
board[row][col] = square;
game.addChild(square);
}
}
}
function setupPieces() {
var pieceOrder = ['rook', 'knight', 'bishop', 'queen', 'king', 'bishop', 'knight', 'rook'];
for (var col = 0; col < 8; col++) {
board[0][col].setPiece(new ChessPiece(pieceOrder[col], 'black'));
board[1][col].setPiece(new ChessPiece('pawn', 'black'));
board[6][col].setPiece(new ChessPiece('pawn', 'white'));
board[7][col].setPiece(new ChessPiece(pieceOrder[col], 'white'));
}
}
function handleSquareClick(square) {
if (gameOver) return;
// Only allow player to control white pieces
if (currentPlayer === 'black') return;
if (selectedSquare) {
if (selectedSquare === square) {
clearSelection();
} else if (square.isHighlighted) {
movePiece(selectedSquare, square);
clearSelection();
switchPlayer();
// Trigger AI move after player move
if (currentPlayer === 'black' && !gameOver) {
LK.setTimeout(function () {
makeAIMove();
}, 500);
}
} else {
clearSelection();
if (square.piece && square.piece.color === 'white') {
selectSquare(square);
}
}
} else {
if (square.piece && square.piece.color === 'white') {
selectSquare(square);
}
}
}
function selectSquare(square) {
selectedSquare = square;
square.setSelected(true);
var validMoves = square.piece.getValidMoves(board, square.row, square.col);
for (var i = 0; i < validMoves.length; i++) {
var move = validMoves[i];
board[move.row][move.col].setHighlight(true);
}
}
function clearSelection() {
if (selectedSquare) {
selectedSquare.setSelected(false);
selectedSquare = null;
}
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
board[row][col].setHighlight(false);
}
}
}
function movePiece(fromSquare, toSquare) {
var piece = fromSquare.piece;
if (toSquare.piece) {
LK.setScore(LK.getScore() + getPieceValue(toSquare.piece.type));
}
toSquare.setPiece(piece);
fromSquare.setPiece(null);
piece.hasMoved = true;
if (isCheckmate(currentPlayer === 'white' ? 'black' : 'white')) {
gameOver = true;
turnText.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' wins!');
LK.showYouWin();
}
}
function switchPlayer() {
currentPlayer = currentPlayer === 'white' ? 'black' : 'white';
turnText.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' to move');
}
function getPieceValue(type) {
switch (type) {
case 'pawn':
return 1;
case 'knight':
return 3;
case 'bishop':
return 3;
case 'rook':
return 5;
case 'queen':
return 9;
case 'king':
return 0;
default:
return 0;
}
}
function isValidSquare(row, col) {
return row >= 0 && row < 8 && col >= 0 && col < 8;
}
function getPawnMoves(board, row, col, color) {
var moves = [];
var direction = color === 'white' ? -1 : 1;
var startRow = color === 'white' ? 6 : 1;
var newRow = row + direction;
if (isValidSquare(newRow, col) && !board[newRow][col].piece) {
moves.push({
row: newRow,
col: col
});
if (row === startRow) {
newRow = row + 2 * direction;
if (isValidSquare(newRow, col) && !board[newRow][col].piece) {
moves.push({
row: newRow,
col: col
});
}
}
}
for (var i = -1; i <= 1; i += 2) {
var newCol = col + i;
newRow = row + direction;
if (isValidSquare(newRow, newCol) && board[newRow][newCol].piece && board[newRow][newCol].piece.color !== color) {
moves.push({
row: newRow,
col: newCol
});
}
}
return moves;
}
function getRookMoves(board, row, col, color) {
var moves = [];
var directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];
for (var d = 0; d < directions.length; d++) {
var dir = directions[d];
for (var i = 1; i < 8; i++) {
var newRow = row + dir[0] * i;
var newCol = col + dir[1] * i;
if (!isValidSquare(newRow, newCol)) break;
if (board[newRow][newCol].piece) {
if (board[newRow][newCol].piece.color !== color) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
moves.push({
row: newRow,
col: newCol
});
}
}
return moves;
}
function getKnightMoves(board, row, col, color) {
var moves = [];
var knightMoves = [[2, 1], [2, -1], [-2, 1], [-2, -1], [1, 2], [1, -2], [-1, 2], [-1, -2]];
for (var i = 0; i < knightMoves.length; i++) {
var move = knightMoves[i];
var newRow = row + move[0];
var newCol = col + move[1];
if (isValidSquare(newRow, newCol)) {
if (!board[newRow][newCol].piece || board[newRow][newCol].piece.color !== color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
return moves;
}
function getBishopMoves(board, row, col, color) {
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 = row + dir[0] * i;
var newCol = col + dir[1] * i;
if (!isValidSquare(newRow, newCol)) break;
if (board[newRow][newCol].piece) {
if (board[newRow][newCol].piece.color !== color) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
moves.push({
row: newRow,
col: newCol
});
}
}
return moves;
}
function getQueenMoves(board, row, col, color) {
var rookMoves = getRookMoves(board, row, col, color);
var bishopMoves = getBishopMoves(board, row, col, color);
return rookMoves.concat(bishopMoves);
}
function getKingMoves(board, row, col, color) {
var moves = [];
var directions = [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
var newRow = row + dir[0];
var newCol = col + dir[1];
if (isValidSquare(newRow, newCol)) {
if (!board[newRow][newCol].piece || board[newRow][newCol].piece.color !== color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
return moves;
}
function findKing(color) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = board[row][col].piece;
if (piece && piece.type === 'king' && piece.color === color) {
return {
row: row,
col: col
};
}
}
}
return null;
}
function isInCheck(color) {
var king = findKing(color);
if (!king) return false;
var enemyColor = color === 'white' ? 'black' : 'white';
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = board[row][col].piece;
if (piece && piece.color === enemyColor) {
var moves = piece.getValidMoves(board, row, col);
for (var i = 0; i < moves.length; i++) {
if (moves[i].row === king.row && moves[i].col === king.col) {
return true;
}
}
}
}
}
return false;
}
function isCheckmate(color) {
if (!isInCheck(color)) return false;
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = board[row][col].piece;
if (piece && piece.color === color) {
var moves = piece.getValidMoves(board, row, col);
if (moves.length > 0) {
return false;
}
}
}
}
return true;
}
function getAllValidMoves(color) {
var allMoves = [];
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = board[row][col].piece;
if (piece && piece.color === color) {
var moves = piece.getValidMoves(board, row, col);
for (var i = 0; i < moves.length; i++) {
allMoves.push({
fromRow: row,
fromCol: col,
toRow: moves[i].row,
toCol: moves[i].col,
piece: piece
});
}
}
}
}
return allMoves;
}
function evaluateMove(move) {
var score = 0;
var targetSquare = board[move.toRow][move.toCol];
// Capture bonus
if (targetSquare.piece) {
score += getPieceValue(targetSquare.piece.type) * 10;
}
// Center control bonus
var centerDistance = Math.abs(move.toRow - 3.5) + Math.abs(move.toCol - 3.5);
score += (7 - centerDistance) * 2;
// Random factor to add variety
score += Math.random() * 5;
return score;
}
function makeAIMove() {
if (gameOver || currentPlayer !== 'black') return;
var possibleMoves = getAllValidMoves('black');
if (possibleMoves.length === 0) return;
// Find best move
var bestMove = possibleMoves[0];
var bestScore = evaluateMove(bestMove);
for (var i = 1; i < possibleMoves.length; i++) {
var score = evaluateMove(possibleMoves[i]);
if (score > bestScore) {
bestScore = score;
bestMove = possibleMoves[i];
}
}
// Execute the move
var fromSquare = board[bestMove.fromRow][bestMove.fromCol];
var toSquare = board[bestMove.toRow][bestMove.toCol];
movePiece(fromSquare, toSquare);
switchPlayer();
}
initializeBoard();
setupPieces();