/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ChessPiece = Container.expand(function (type, color, row, col) { var self = Container.call(this); self.pieceType = type; self.pieceColor = color; self.boardRow = row; self.boardCol = col; self.hasMoved = false; var assetName = color === 'black' ? 'black' + type.charAt(0).toUpperCase() + type.slice(1) : type; var pieceGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { if (self.pieceColor === 'white' && currentTurn === 'white') { selectPiece(self); } }; self.moveTo = function (newRow, newCol) { self.boardRow = newRow; self.boardCol = newCol; self.hasMoved = true; var newX = boardStartX + newCol * squareSize + squareSize / 2; var newY = boardStartY + newRow * squareSize + squareSize / 2; tween(self, { x: newX, y: newY }, { duration: 300 }); }; 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; var squareGraphics = self.attachAsset(self.isLight ? 'lightSquare' : 'darkSquare', { anchorX: 0, anchorY: 0 }); self.highlight = null; self.piece = null; self.down = function (x, y, obj) { handleSquareClick(self.row, self.col); }; self.showHighlight = function (type) { if (self.highlight) { self.removeChild(self.highlight); } var color = type === 'selected' ? 'selectedSquare' : 'highlightSquare'; self.highlight = self.addChild(LK.getAsset(color, { anchorX: 0, anchorY: 0, alpha: 0.7 })); }; self.hideHighlight = function () { if (self.highlight) { self.removeChild(self.highlight); self.highlight = null; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F4F2F }); /**** * Game Code ****/ var boardSize = 8; var squareSize = 225; var boardStartX = (2048 - boardSize * squareSize) / 2; var boardStartY = (2732 - boardSize * squareSize) / 2; var board = []; var pieces = []; var selectedPiece = null; var currentTurn = 'white'; var gameState = 'playing'; // Initialize board squares for (var row = 0; row < boardSize; row++) { board[row] = []; for (var col = 0; col < boardSize; col++) { var square = new ChessSquare(row, col); square.x = boardStartX + col * squareSize; square.y = boardStartY + row * squareSize; board[row][col] = square; game.addChild(square); } } // Initial piece setup var initialSetup = [['rook', 'knight', 'bishop', 'queen', 'king', 'bishop', 'knight', 'rook'], ['pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn'], [null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null], ['pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn'], ['rook', 'knight', 'bishop', 'queen', 'king', 'bishop', 'knight', 'rook']]; // Create pieces for (var row = 0; row < boardSize; row++) { for (var col = 0; col < boardSize; col++) { if (initialSetup[row][col]) { var color = row < 2 ? 'black' : 'white'; var piece = new ChessPiece(initialSetup[row][col], color, row, col); piece.x = boardStartX + col * squareSize + squareSize / 2; piece.y = boardStartY + row * squareSize + squareSize / 2; pieces.push(piece); board[row][col].piece = piece; game.addChild(piece); } } } // Turn indicator var turnText = new Text2('White to move', { size: 80, fill: 0xFFFFFF }); turnText.anchor.set(0.5, 0); turnText.x = 2048 / 2; turnText.y = 100; game.addChild(turnText); function selectPiece(piece) { clearHighlights(); if (selectedPiece === piece) { selectedPiece = null; return; } selectedPiece = piece; board[piece.boardRow][piece.boardCol].showHighlight('selected'); var legalMoves = getLegalMoves(piece); for (var i = 0; i < legalMoves.length; i++) { var move = legalMoves[i]; board[move.row][move.col].showHighlight('legal'); } } function handleSquareClick(row, col) { if (currentTurn !== 'white' || gameState !== 'playing') { return; } if (selectedPiece) { var legalMoves = getLegalMoves(selectedPiece); var isLegalMove = false; for (var i = 0; i < legalMoves.length; i++) { if (legalMoves[i].row === row && legalMoves[i].col === col) { isLegalMove = true; break; } } if (isLegalMove) { makeMove(selectedPiece, row, col); } else { clearHighlights(); selectedPiece = null; } } } function makeMove(piece, toRow, toCol) { var capturedPiece = board[toRow][toCol].piece; // Remove piece from old position board[piece.boardRow][piece.boardCol].piece = null; // Capture enemy piece if present if (capturedPiece) { game.removeChild(capturedPiece); for (var i = pieces.length - 1; i >= 0; i--) { if (pieces[i] === capturedPiece) { pieces.splice(i, 1); break; } } LK.getSound('capture').play(); } else { LK.getSound('move').play(); } // Move piece to new position board[toRow][toCol].piece = piece; piece.moveTo(toRow, toCol); clearHighlights(); selectedPiece = null; // Switch turns currentTurn = currentTurn === 'white' ? 'black' : 'white'; turnText.setText(currentTurn === 'white' ? 'White to move' : 'Black to move'); // Check for game end conditions if (isCheckmate(currentTurn)) { gameState = 'ended'; if (currentTurn === 'white') { LK.showGameOver(); } else { LK.showYouWin(); } } } function clearHighlights() { for (var row = 0; row < boardSize; row++) { for (var col = 0; col < boardSize; col++) { board[row][col].hideHighlight(); } } } function getLegalMoves(piece) { var moves = []; var row = piece.boardRow; var col = piece.boardCol; switch (piece.pieceType) { case 'pawn': var direction = piece.pieceColor === 'white' ? -1 : 1; var startRow = piece.pieceColor === 'white' ? 6 : 1; // Forward move if (isValidSquare(row + direction, col) && !board[row + direction][col].piece) { moves.push({ row: row + direction, col: col }); // Double move from starting position if (row === startRow && !board[row + 2 * direction][col].piece) { moves.push({ row: row + 2 * direction, col: col }); } } // Captures if (isValidSquare(row + direction, col - 1) && board[row + direction][col - 1].piece && board[row + direction][col - 1].piece.pieceColor !== piece.pieceColor) { moves.push({ row: row + direction, col: col - 1 }); } if (isValidSquare(row + direction, col + 1) && board[row + direction][col + 1].piece && board[row + direction][col + 1].piece.pieceColor !== piece.pieceColor) { moves.push({ row: row + direction, col: col + 1 }); } break; case 'rook': addLinearMoves(moves, piece, [[0, 1], [0, -1], [1, 0], [-1, 0]]); break; case 'bishop': addLinearMoves(moves, piece, [[1, 1], [1, -1], [-1, 1], [-1, -1]]); break; case 'queen': addLinearMoves(moves, piece, [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]]); break; case 'king': var kingMoves = [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]]; for (var i = 0; i < kingMoves.length; i++) { var newRow = row + kingMoves[i][0]; var newCol = col + kingMoves[i][1]; if (isValidSquare(newRow, newCol) && (!board[newRow][newCol].piece || board[newRow][newCol].piece.pieceColor !== piece.pieceColor)) { moves.push({ row: newRow, col: newCol }); } } break; case 'knight': 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 newRow = row + knightMoves[i][0]; var newCol = col + knightMoves[i][1]; if (isValidSquare(newRow, newCol) && (!board[newRow][newCol].piece || board[newRow][newCol].piece.pieceColor !== piece.pieceColor)) { moves.push({ row: newRow, col: newCol }); } } break; } return moves; } function addLinearMoves(moves, piece, directions) { for (var d = 0; d < directions.length; d++) { var dir = directions[d]; for (var i = 1; i < 8; i++) { var newRow = piece.boardRow + dir[0] * i; var newCol = piece.boardCol + dir[1] * i; if (!isValidSquare(newRow, newCol)) { break; } var targetSquare = board[newRow][newCol]; if (targetSquare.piece) { if (targetSquare.piece.pieceColor !== piece.pieceColor) { moves.push({ row: newRow, col: newCol }); } break; } else { moves.push({ row: newRow, col: newCol }); } } } } function isValidSquare(row, col) { return row >= 0 && row < boardSize && col >= 0 && col < boardSize; } function findKing(color) { for (var i = 0; i < pieces.length; i++) { if (pieces[i].pieceType === 'king' && pieces[i].pieceColor === color) { return pieces[i]; } } return null; } function isInCheck(color) { var king = findKing(color); if (!king) return false; for (var i = 0; i < pieces.length; i++) { var piece = pieces[i]; if (piece.pieceColor !== color) { var moves = getLegalMoves(piece); for (var j = 0; j < moves.length; j++) { if (moves[j].row === king.boardRow && moves[j].col === king.boardCol) { 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.pieceColor === color) { var moves = getLegalMoves(piece); if (moves.length > 0) { return false; } } } return true; } // Simple AI that makes random moves function makeAIMove() { if (currentTurn !== 'black' || gameState !== 'playing') { return; } var blackPieces = []; for (var i = 0; i < pieces.length; i++) { if (pieces[i].pieceColor === 'black') { blackPieces.push(pieces[i]); } } var allMoves = []; for (var i = 0; i < blackPieces.length; i++) { var piece = blackPieces[i]; var moves = getLegalMoves(piece); for (var j = 0; j < moves.length; j++) { allMoves.push({ piece: piece, move: moves[j] }); } } if (allMoves.length > 0) { var randomIndex = Math.floor(Math.random() * allMoves.length); var selectedMove = allMoves[randomIndex]; LK.setTimeout(function () { makeMove(selectedMove.piece, selectedMove.move.row, selectedMove.move.col); }, 1000); } } var aiMoveTimer = 0; game.update = function () { if (currentTurn === 'black' && gameState === 'playing') { aiMoveTimer++; if (aiMoveTimer >= 120) { // 2 seconds at 60fps makeAIMove(); aiMoveTimer = 0; } } else { aiMoveTimer = 0; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var ChessPiece = Container.expand(function (type, color, row, col) {
var self = Container.call(this);
self.pieceType = type;
self.pieceColor = color;
self.boardRow = row;
self.boardCol = col;
self.hasMoved = false;
var assetName = color === 'black' ? 'black' + type.charAt(0).toUpperCase() + type.slice(1) : type;
var pieceGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
if (self.pieceColor === 'white' && currentTurn === 'white') {
selectPiece(self);
}
};
self.moveTo = function (newRow, newCol) {
self.boardRow = newRow;
self.boardCol = newCol;
self.hasMoved = true;
var newX = boardStartX + newCol * squareSize + squareSize / 2;
var newY = boardStartY + newRow * squareSize + squareSize / 2;
tween(self, {
x: newX,
y: newY
}, {
duration: 300
});
};
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;
var squareGraphics = self.attachAsset(self.isLight ? 'lightSquare' : 'darkSquare', {
anchorX: 0,
anchorY: 0
});
self.highlight = null;
self.piece = null;
self.down = function (x, y, obj) {
handleSquareClick(self.row, self.col);
};
self.showHighlight = function (type) {
if (self.highlight) {
self.removeChild(self.highlight);
}
var color = type === 'selected' ? 'selectedSquare' : 'highlightSquare';
self.highlight = self.addChild(LK.getAsset(color, {
anchorX: 0,
anchorY: 0,
alpha: 0.7
}));
};
self.hideHighlight = function () {
if (self.highlight) {
self.removeChild(self.highlight);
self.highlight = null;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F2F
});
/****
* Game Code
****/
var boardSize = 8;
var squareSize = 225;
var boardStartX = (2048 - boardSize * squareSize) / 2;
var boardStartY = (2732 - boardSize * squareSize) / 2;
var board = [];
var pieces = [];
var selectedPiece = null;
var currentTurn = 'white';
var gameState = 'playing';
// Initialize board squares
for (var row = 0; row < boardSize; row++) {
board[row] = [];
for (var col = 0; col < boardSize; col++) {
var square = new ChessSquare(row, col);
square.x = boardStartX + col * squareSize;
square.y = boardStartY + row * squareSize;
board[row][col] = square;
game.addChild(square);
}
}
// Initial piece setup
var initialSetup = [['rook', 'knight', 'bishop', 'queen', 'king', 'bishop', 'knight', 'rook'], ['pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn'], [null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null], [null, null, null, null, null, null, null, null], ['pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn'], ['rook', 'knight', 'bishop', 'queen', 'king', 'bishop', 'knight', 'rook']];
// Create pieces
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
if (initialSetup[row][col]) {
var color = row < 2 ? 'black' : 'white';
var piece = new ChessPiece(initialSetup[row][col], color, row, col);
piece.x = boardStartX + col * squareSize + squareSize / 2;
piece.y = boardStartY + row * squareSize + squareSize / 2;
pieces.push(piece);
board[row][col].piece = piece;
game.addChild(piece);
}
}
}
// Turn indicator
var turnText = new Text2('White to move', {
size: 80,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
turnText.x = 2048 / 2;
turnText.y = 100;
game.addChild(turnText);
function selectPiece(piece) {
clearHighlights();
if (selectedPiece === piece) {
selectedPiece = null;
return;
}
selectedPiece = piece;
board[piece.boardRow][piece.boardCol].showHighlight('selected');
var legalMoves = getLegalMoves(piece);
for (var i = 0; i < legalMoves.length; i++) {
var move = legalMoves[i];
board[move.row][move.col].showHighlight('legal');
}
}
function handleSquareClick(row, col) {
if (currentTurn !== 'white' || gameState !== 'playing') {
return;
}
if (selectedPiece) {
var legalMoves = getLegalMoves(selectedPiece);
var isLegalMove = false;
for (var i = 0; i < legalMoves.length; i++) {
if (legalMoves[i].row === row && legalMoves[i].col === col) {
isLegalMove = true;
break;
}
}
if (isLegalMove) {
makeMove(selectedPiece, row, col);
} else {
clearHighlights();
selectedPiece = null;
}
}
}
function makeMove(piece, toRow, toCol) {
var capturedPiece = board[toRow][toCol].piece;
// Remove piece from old position
board[piece.boardRow][piece.boardCol].piece = null;
// Capture enemy piece if present
if (capturedPiece) {
game.removeChild(capturedPiece);
for (var i = pieces.length - 1; i >= 0; i--) {
if (pieces[i] === capturedPiece) {
pieces.splice(i, 1);
break;
}
}
LK.getSound('capture').play();
} else {
LK.getSound('move').play();
}
// Move piece to new position
board[toRow][toCol].piece = piece;
piece.moveTo(toRow, toCol);
clearHighlights();
selectedPiece = null;
// Switch turns
currentTurn = currentTurn === 'white' ? 'black' : 'white';
turnText.setText(currentTurn === 'white' ? 'White to move' : 'Black to move');
// Check for game end conditions
if (isCheckmate(currentTurn)) {
gameState = 'ended';
if (currentTurn === 'white') {
LK.showGameOver();
} else {
LK.showYouWin();
}
}
}
function clearHighlights() {
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
board[row][col].hideHighlight();
}
}
}
function getLegalMoves(piece) {
var moves = [];
var row = piece.boardRow;
var col = piece.boardCol;
switch (piece.pieceType) {
case 'pawn':
var direction = piece.pieceColor === 'white' ? -1 : 1;
var startRow = piece.pieceColor === 'white' ? 6 : 1;
// Forward move
if (isValidSquare(row + direction, col) && !board[row + direction][col].piece) {
moves.push({
row: row + direction,
col: col
});
// Double move from starting position
if (row === startRow && !board[row + 2 * direction][col].piece) {
moves.push({
row: row + 2 * direction,
col: col
});
}
}
// Captures
if (isValidSquare(row + direction, col - 1) && board[row + direction][col - 1].piece && board[row + direction][col - 1].piece.pieceColor !== piece.pieceColor) {
moves.push({
row: row + direction,
col: col - 1
});
}
if (isValidSquare(row + direction, col + 1) && board[row + direction][col + 1].piece && board[row + direction][col + 1].piece.pieceColor !== piece.pieceColor) {
moves.push({
row: row + direction,
col: col + 1
});
}
break;
case 'rook':
addLinearMoves(moves, piece, [[0, 1], [0, -1], [1, 0], [-1, 0]]);
break;
case 'bishop':
addLinearMoves(moves, piece, [[1, 1], [1, -1], [-1, 1], [-1, -1]]);
break;
case 'queen':
addLinearMoves(moves, piece, [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]]);
break;
case 'king':
var kingMoves = [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]];
for (var i = 0; i < kingMoves.length; i++) {
var newRow = row + kingMoves[i][0];
var newCol = col + kingMoves[i][1];
if (isValidSquare(newRow, newCol) && (!board[newRow][newCol].piece || board[newRow][newCol].piece.pieceColor !== piece.pieceColor)) {
moves.push({
row: newRow,
col: newCol
});
}
}
break;
case 'knight':
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 newRow = row + knightMoves[i][0];
var newCol = col + knightMoves[i][1];
if (isValidSquare(newRow, newCol) && (!board[newRow][newCol].piece || board[newRow][newCol].piece.pieceColor !== piece.pieceColor)) {
moves.push({
row: newRow,
col: newCol
});
}
}
break;
}
return moves;
}
function addLinearMoves(moves, piece, directions) {
for (var d = 0; d < directions.length; d++) {
var dir = directions[d];
for (var i = 1; i < 8; i++) {
var newRow = piece.boardRow + dir[0] * i;
var newCol = piece.boardCol + dir[1] * i;
if (!isValidSquare(newRow, newCol)) {
break;
}
var targetSquare = board[newRow][newCol];
if (targetSquare.piece) {
if (targetSquare.piece.pieceColor !== piece.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
break;
} else {
moves.push({
row: newRow,
col: newCol
});
}
}
}
}
function isValidSquare(row, col) {
return row >= 0 && row < boardSize && col >= 0 && col < boardSize;
}
function findKing(color) {
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].pieceType === 'king' && pieces[i].pieceColor === color) {
return pieces[i];
}
}
return null;
}
function isInCheck(color) {
var king = findKing(color);
if (!king) return false;
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.pieceColor !== color) {
var moves = getLegalMoves(piece);
for (var j = 0; j < moves.length; j++) {
if (moves[j].row === king.boardRow && moves[j].col === king.boardCol) {
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.pieceColor === color) {
var moves = getLegalMoves(piece);
if (moves.length > 0) {
return false;
}
}
}
return true;
}
// Simple AI that makes random moves
function makeAIMove() {
if (currentTurn !== 'black' || gameState !== 'playing') {
return;
}
var blackPieces = [];
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].pieceColor === 'black') {
blackPieces.push(pieces[i]);
}
}
var allMoves = [];
for (var i = 0; i < blackPieces.length; i++) {
var piece = blackPieces[i];
var moves = getLegalMoves(piece);
for (var j = 0; j < moves.length; j++) {
allMoves.push({
piece: piece,
move: moves[j]
});
}
}
if (allMoves.length > 0) {
var randomIndex = Math.floor(Math.random() * allMoves.length);
var selectedMove = allMoves[randomIndex];
LK.setTimeout(function () {
makeMove(selectedMove.piece, selectedMove.move.row, selectedMove.move.col);
}, 1000);
}
}
var aiMoveTimer = 0;
game.update = function () {
if (currentTurn === 'black' && gameState === 'playing') {
aiMoveTimer++;
if (aiMoveTimer >= 120) {
// 2 seconds at 60fps
makeAIMove();
aiMoveTimer = 0;
}
} else {
aiMoveTimer = 0;
}
};
top view of yellow cat wearing crown. In-Game asset. 2d. High contrast. No shadows
top view of purple cat wearing crown
purple panda top view. In-Game asset. 2d. High contrast. No shadows
yellow panda top view. In-Game asset. 2d. High contrast. No shadows
yellow capybara top view. In-Game asset. 2d. High contrast. No shadows
purple capybara top view. In-Game asset. 2d. High contrast. No shadows
purple monkey top view. In-Game asset. 2d. High contrast. No shadows
yellow monkey top view. In-Game asset. 2d. High contrast. No shadows
yellow giraffe top view. In-Game asset. 2d. High contrast. No shadows
purple giraffe top view. In-Game asset. 2d. High contrast. No shadows
purple dog top view. In-Game asset. 2d. High contrast. No shadows
yellow dog top view. In-Game asset. 2d. High contrast. No shadows