User prompt
Bring back the knight and rooks, there will be only 2 snakes and they will replace the rook and knight that will not come back. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Now, instead of a rook and a knight, let's add a new piece called a snake. This piece makes two moves per turn and moves in a Z-shape. (It moves in a 3x3 grid in a Z-shape.) During these three moves, it eats one piece for each point it stops. It also inflicts poison on the pieces behind it. (The poison effect is a new effect, which turns the piece red and makes it unplayable for three turns. The duration of this poison is written on the piece.) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Now, instead of a rook and a knight, let's add a new piece called a snake. This piece makes two moves per turn and moves in a Z-shape. (It moves in a 3x3 grid in a Z-shape.) During these three moves, it eats one piece for each point it stops. It also inflicts poison on the pieces behind it. (The poison effect is a new effect, which turns the piece red and makes it unplayable for three turns. The duration of this poison is written on the piece.) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Now, let's add a new piece called the snake, replacing the rook and knight. This piece makes two moves per turn and moves in a Z-shape. (It moves in a 3x3 grid in a Z-shape.) During these three moves, it eats one piece for each point it stops. It also inflicts poison on the pieces behind it. (The poison effect is a new effect, which turns the piece red and makes it unplayable for three turns. The duration of this poison is written on the piece.) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Now, let's add a new piece called the snake, replacing the rook and knight. This piece makes two moves per turn and moves in a Z-shape. (It moves in a 3x3 grid in a Z-shape.) During these three moves, it eats one piece for each point it stops. It also inflicts poison on the pieces behind it. (The poison effect is a new effect, which turns the piece red and makes it unplayable for three turns. The duration of this poison is written on the piece.) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
In must escape situations, first of all, it must be checked whether the king and other pieces can capture the king piece, then the game must start from the beginning.
User prompt
Re-arrange the pieces according to your normal chessboard layout. Pieces of the same type are divided into two groups and placed side by side and take their classic places, but the pieces of the same type are placed side by side and around the king, similar to the original chess layout, but the normal extra pieces will be placed side by side and divided on two sides (example: if there are 5 rooks, a1 rook, a2 rook, a3 knight, a3 knight... and a14 rook, a15 rook, etc. synchronization and division by 2. If one side is odd, give 1 extra to a random side).
User prompt
Add assets to the squares showing my remaining lives and add assets to the squares showing the enemy's lives. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Do not add a new 4 life bar, delete the new life bar. The old life bar is 8 (add assets for the first 4 rightful life bars) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add assets to the 4 live life bars, separate life bars for AI and player ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
delete health bar
User prompt
Add player and AI health bars as assets ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
However, if the player cannot escape and can capture a piece that would checkmate them, the game automatically performs the action of capturing that piece instead of the player or AI. The game does not end, and 4 lives are not lost in this situation. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
However, if the player is unable to escape and can capture a piece that would checkmate them, the game automatically performs the capture action on behalf of the player or AI
User prompt
If a side is checkmated (pinned) and there's no escape, the player loses all lives and the game restarts. However, if the king can capture the captured piece, the game automatically captures that piece and the game continues. Remove the scoreboard and prevent your king from being placed on squares where it cannot be protected or can be checkmated.
User prompt
Similarly, when the king is taken, the opponent AI can make yellow moves to escape the king instead of thinking the game is over. However, when one of the two sides runs out of lives, the game starts from the beginning instead of stopping. In other words, if any side runs out of 4 lives, regardless of whether it is black or white, the game starts from the beginning. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the opponent's king's health drops to 1, they attempt to force their king to escape or capture the king by placing a piece between themselves and the king in check. These are also examples of yellow-squared moves. However, the game continues until the player or king has 4 lives; in other words, the opponent wins if they check four times. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
One life has been lost, but no squares have been taken. Once the king is formed, the yellow squares are taken, and the game continues. The yellow square rule ensures that the game continues when the king is captured. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the opponent checks and our health decreases by 1, the game continues, but we only make moves that protect or escape the king. The squares where these moves are made and the squares containing the pieces will be colored yellow. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The game does not end when one side checks. When the other side checks, the player's health decreases by 1. The opponent can only make moves to escape or protect their king. This applies to both sides.
User prompt
Let's put our four rights regarding our right to health behind chess pieces so that everyone can see their own life in front of them and everyone's life is behind their own chess pieces.
User prompt
Add lives to each side, representing the health of that side. You have 4 lives, and each health bar has a unique ability.
User prompt
The square below your opponent's king is also purple. Your opponent primarily plays to capture your chess pieces and attempts to capture your king (while playing aggressively and protecting their king). The king has 4 lives, and each capture reduces by 1. If either side loses, the game starts over from the beginning. Similarly, if either side checkmates, the game starts over from the beginning. When the match ends, it starts over from the beginning. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The square where the king is located is purple, and no matter where the king moves, the purple square will be the square below it. There is only one purple square, and it is always below the king.
User prompt
I straightened the squares in the first row. They look like rectangles, so make them squares too.
/****
* 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.row = row;
self.col = col;
self.hasMoved = false;
var assetName = color + type.charAt(0).toUpperCase() + type.slice(1);
var pieceGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.updatePosition = function (animate) {
var targetX = boardStartX + self.col * squareSize + squareSize / 2;
var targetY = boardStartY + self.row * squareSize + squareSize / 2;
if (animate && (self.x !== targetX || self.y !== targetY)) {
tween(self, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut
});
} else {
self.x = targetX;
self.y = targetY;
}
};
self.canMoveTo = function (targetRow, targetCol) {
if (targetRow < 0 || targetRow > 7 || targetCol < 0 || targetCol > 15) {
return false;
}
var targetPiece = getPieceAt(targetRow, targetCol);
if (targetPiece && targetPiece.pieceColor === self.pieceColor) {
return false;
}
switch (self.pieceType) {
case 'pawn':
return self.canPawnMove(targetRow, targetCol);
case 'rook':
return self.canRookMove(targetRow, targetCol);
case 'knight':
return self.canKnightMove(targetRow, targetCol);
case 'bishop':
return self.canBishopMove(targetRow, targetCol);
case 'queen':
return self.canQueenMove(targetRow, targetCol);
case 'king':
return self.canKingMove(targetRow, targetCol);
}
return false;
};
self.canPawnMove = function (targetRow, targetCol) {
var direction = self.pieceColor === 'white' ? -1 : 1;
var startRow = self.pieceColor === 'white' ? 6 : 1;
if (targetCol === self.col) {
if (targetRow === self.row + direction && !getPieceAt(targetRow, targetCol)) {
return true;
}
if (self.row === startRow && targetRow === self.row + 2 * direction && !getPieceAt(targetRow, targetCol)) {
return true;
}
} else if (Math.abs(targetCol - self.col) === 1 && targetRow === self.row + direction) {
var targetPiece = getPieceAt(targetRow, targetCol);
if (targetPiece && targetPiece.pieceColor !== self.pieceColor) {
return true;
}
}
return false;
};
self.canRookMove = function (targetRow, targetCol) {
if (self.row !== targetRow && self.col !== targetCol) {
return false;
}
return isPathClear(self.row, self.col, targetRow, targetCol);
};
self.canKnightMove = function (targetRow, targetCol) {
var rowDiff = Math.abs(targetRow - self.row);
var colDiff = Math.abs(targetCol - self.col);
return rowDiff === 2 && colDiff === 1 || rowDiff === 1 && colDiff === 2;
};
self.canBishopMove = function (targetRow, targetCol) {
if (Math.abs(targetRow - self.row) !== Math.abs(targetCol - self.col)) {
return false;
}
return isPathClear(self.row, self.col, targetRow, targetCol);
};
self.canQueenMove = function (targetRow, targetCol) {
return self.canRookMove(targetRow, targetCol) || self.canBishopMove(targetRow, targetCol);
};
self.canKingMove = function (targetRow, targetCol) {
var rowDiff = Math.abs(targetRow - self.row);
var colDiff = Math.abs(targetCol - self.col);
return rowDiff <= 1 && colDiff <= 1;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2D1810
});
/****
* Game Code
****/
// Game dimensions and board setup
// Chess board squares
// White pieces
// Black pieces
// Sound effects
var squareSize = 128;
var boardStartX = (2048 - squareSize * 16) / 2;
var boardStartY = (2732 - squareSize * 8) / 2 + 100;
// Game state
var currentPlayer = 'white';
var selectedPiece = null;
var validMoves = [];
var pieces = [];
var gameBoard = [];
var highlightSquares = [];
var validMoveSquares = [];
var dragNode = null;
var gameState = 'playing'; // playing, check, checkmate, stalemate
// Initialize empty board
for (var row = 0; row < 8; row++) {
gameBoard[row] = [];
for (var col = 0; col < 16; col++) {
gameBoard[row][col] = null;
}
}
// Create visual board
var boardContainer = game.addChild(new Container());
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
var isLight = (row + col) % 2 === 0;
var square = LK.getAsset(isLight ? 'lightSquare' : 'darkSquare', {
anchorX: 0,
anchorY: 0
});
square.x = boardStartX + col * squareSize;
square.y = boardStartY + row * squareSize;
boardContainer.addChild(square);
}
}
// Initialize pieces
var pieceSetup = [['rook', 'knight', 'bishop', 'rook', 'queen', 'king', 'queen', 'rook', 'bishop', 'knight', 'rook', 'bishop', 'knight', 'rook', 'knight', 'bishop'], ['pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn']];
// Create black pieces
for (var row = 0; row < 2; row++) {
for (var col = 0; col < 16; col++) {
var piece = new ChessPiece(pieceSetup[row][col], 'black', row, col);
pieces.push(piece);
gameBoard[row][col] = piece;
game.addChild(piece);
piece.updatePosition();
}
}
// Create white pieces
for (var row = 6; row < 8; row++) {
for (var col = 0; col < 16; col++) {
var pieceType = row === 6 ? 'pawn' : pieceSetup[7 - row][col];
var piece = new ChessPiece(pieceType, 'white', row, col);
pieces.push(piece);
gameBoard[row][col] = piece;
game.addChild(piece);
piece.updatePosition();
}
}
// UI Elements
var turnText = new Text2('Your Turn', {
size: 80,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
LK.gui.top.addChild(turnText);
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = 100;
LK.gui.top.addChild(scoreText);
function getPieceAt(row, col) {
if (row < 0 || row > 7 || col < 0 || col > 15) {
return null;
}
return gameBoard[row][col];
}
function isPathClear(fromRow, fromCol, toRow, toCol) {
var rowStep = toRow > fromRow ? 1 : toRow < fromRow ? -1 : 0;
var colStep = toCol > fromCol ? 1 : toCol < fromCol ? -1 : 0;
var currentRow = fromRow + rowStep;
var currentCol = fromCol + colStep;
while (currentRow !== toRow || currentCol !== toCol) {
if (getPieceAt(currentRow, currentCol)) {
return false;
}
currentRow += rowStep;
currentCol += colStep;
}
return true;
}
function getSquareFromPosition(x, y) {
var col = Math.floor((x - boardStartX) / squareSize);
var row = Math.floor((y - boardStartY) / squareSize);
if (row >= 0 && row < 8 && col >= 0 && col < 16) {
return {
row: row,
col: col
};
}
return null;
}
function clearHighlights() {
for (var i = 0; i < highlightSquares.length; i++) {
highlightSquares[i].destroy();
}
highlightSquares = [];
for (var i = 0; i < validMoveSquares.length; i++) {
validMoveSquares[i].destroy();
}
validMoveSquares = [];
}
function highlightSquare(row, col, color) {
var highlight = LK.getAsset(color === 'blue' ? 'highlightSquare' : 'validMoveSquare', {
anchorX: 0,
anchorY: 0,
alpha: 0.7
});
highlight.x = boardStartX + col * squareSize;
highlight.y = boardStartY + row * squareSize;
game.addChild(highlight);
if (color === 'blue') {
highlightSquares.push(highlight);
} else {
validMoveSquares.push(highlight);
}
}
function showValidMoves(piece) {
validMoves = [];
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
if (piece.canMoveTo(row, col)) {
validMoves.push({
row: row,
col: col
});
highlightSquare(row, col, 'green');
}
}
}
}
function movePiece(piece, newRow, newCol) {
var capturedPiece = getPieceAt(newRow, newCol);
var isCapture = capturedPiece !== null;
// Remove piece from old position
gameBoard[piece.row][piece.col] = null;
// Remove captured piece
if (capturedPiece) {
for (var i = 0; i < pieces.length; i++) {
if (pieces[i] === capturedPiece) {
pieces[i].destroy();
pieces.splice(i, 1);
break;
}
}
LK.setScore(LK.getScore() + getPieceValue(capturedPiece.pieceType));
scoreText.setText('Score: ' + LK.getScore());
}
// Move piece to new position
piece.row = newRow;
piece.col = newCol;
piece.hasMoved = true;
gameBoard[newRow][newCol] = piece;
piece.updatePosition(true);
// Play sound
if (isCapture) {
LK.getSound('capture').play();
} else {
LK.getSound('move').play();
}
// Check for pawn promotion
if (piece.pieceType === 'pawn' && (newRow === 0 || newRow === 7)) {
promotePawn(piece);
}
// Switch turns
currentPlayer = currentPlayer === 'white' ? 'black' : 'white';
turnText.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + '\'s Turn');
// Check for check/checkmate
if (isInCheck(currentPlayer)) {
if (isCheckmate(currentPlayer)) {
gameState = 'checkmate';
var winner = currentPlayer === 'white' ? 'Black' : 'White';
turnText.setText(winner + ' Wins!');
LK.setTimeout(function () {
restartGame();
}, 2000);
} else {
gameState = 'check';
LK.getSound('check').play();
turnText.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' in Check!');
}
} else if (isStalemate(currentPlayer)) {
gameState = 'stalemate';
turnText.setText('Stalemate!');
LK.setTimeout(function () {
restartGame();
}, 2000);
} else {
gameState = 'playing';
}
// Trigger AI move if it's black's turn
if (currentPlayer === 'black' && gameState === 'playing') {
makeAIMove();
}
}
function getPieceValue(pieceType) {
switch (pieceType) {
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 promotePawn(pawn) {
// Simple promotion to queen for now
pawn.pieceType = 'queen';
pawn.destroy();
var newQueen = new ChessPiece('queen', pawn.pieceColor, pawn.row, pawn.col);
for (var i = 0; i < pieces.length; i++) {
if (pieces[i] === pawn) {
pieces[i] = newQueen;
break;
}
}
gameBoard[pawn.row][pawn.col] = newQueen;
game.addChild(newQueen);
newQueen.updatePosition();
}
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 && piece.canMoveTo(king.row, 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.pieceColor === color) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
if (piece.canMoveTo(row, col)) {
// Simulate move
var originalRow = piece.row;
var originalCol = piece.col;
var capturedPiece = getPieceAt(row, col);
gameBoard[originalRow][originalCol] = null;
gameBoard[row][col] = piece;
piece.row = row;
piece.col = col;
var stillInCheck = isInCheck(color);
// Restore position
piece.row = originalRow;
piece.col = originalCol;
gameBoard[originalRow][originalCol] = piece;
gameBoard[row][col] = capturedPiece;
if (!stillInCheck) {
return false;
}
}
}
}
}
}
return true;
}
function isStalemate(color) {
if (isInCheck(color)) return false;
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.pieceColor === color) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
if (piece.canMoveTo(row, col)) {
return false;
}
}
}
}
}
return true;
}
function getAllValidMoves(color) {
var allMoves = [];
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.pieceColor === color) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
if (piece.canMoveTo(row, col)) {
allMoves.push({
piece: piece,
toRow: row,
toCol: col
});
}
}
}
}
}
return allMoves;
}
function makeAIMove() {
if (currentPlayer !== 'black' || gameState !== 'playing') return;
var validAIMoves = getAllValidMoves('black');
if (validAIMoves.length === 0) return;
// Select random move
var randomIndex = Math.floor(Math.random() * validAIMoves.length);
var chosenMove = validAIMoves[randomIndex];
// Execute the move after a short delay to make it feel more natural
LK.setTimeout(function () {
movePiece(chosenMove.piece, chosenMove.toRow, chosenMove.toCol);
}, 800);
}
function restartGame() {
// Clear all pieces
for (var i = 0; i < pieces.length; i++) {
pieces[i].destroy();
}
pieces = [];
// Clear highlights
clearHighlights();
// Reset game state
currentPlayer = 'white';
selectedPiece = null;
validMoves = [];
dragNode = null;
gameState = 'playing';
LK.setScore(0);
scoreText.setText('Score: 0');
turnText.setText('Your Turn');
// Clear board
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
gameBoard[row][col] = null;
}
}
// Recreate pieces
var pieceSetup = [['rook', 'knight', 'bishop', 'rook', 'queen', 'king', 'queen', 'rook', 'bishop', 'knight', 'rook', 'bishop', 'knight', 'rook', 'knight', 'bishop'], ['pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn']];
// Create black pieces
for (var row = 0; row < 2; row++) {
for (var col = 0; col < 16; col++) {
var piece = new ChessPiece(pieceSetup[row][col], 'black', row, col);
pieces.push(piece);
gameBoard[row][col] = piece;
game.addChild(piece);
piece.updatePosition();
}
}
// Create white pieces
for (var row = 6; row < 8; row++) {
for (var col = 0; col < 16; col++) {
var pieceType = row === 6 ? 'pawn' : pieceSetup[7 - row][col];
var piece = new ChessPiece(pieceType, 'white', row, col);
pieces.push(piece);
gameBoard[row][col] = piece;
game.addChild(piece);
piece.updatePosition();
}
}
}
game.down = function (x, y, obj) {
if (gameState !== 'playing') return;
var square = getSquareFromPosition(x, y);
if (!square) return;
var clickedPiece = getPieceAt(square.row, square.col);
if (selectedPiece) {
// Check if clicked on valid move
var isValidMove = false;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].row === square.row && validMoves[i].col === square.col) {
isValidMove = true;
break;
}
}
if (isValidMove) {
movePiece(selectedPiece, square.row, square.col);
}
clearHighlights();
selectedPiece = null;
}
if (clickedPiece && clickedPiece.pieceColor === currentPlayer && currentPlayer === 'white') {
selectedPiece = clickedPiece;
dragNode = clickedPiece;
highlightSquare(clickedPiece.row, clickedPiece.col, 'blue');
showValidMoves(clickedPiece);
}
};
game.move = function (x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
}
};
game.up = function (x, y, obj) {
if (dragNode && selectedPiece) {
var square = getSquareFromPosition(x, y);
if (square) {
var isValidMove = false;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].row === square.row && validMoves[i].col === square.col) {
isValidMove = true;
break;
}
}
if (isValidMove) {
movePiece(selectedPiece, square.row, square.col);
clearHighlights();
selectedPiece = null;
} else {
selectedPiece.updatePosition(true);
}
} else {
selectedPiece.updatePosition(true);
}
}
dragNode = null;
};
game.update = function () {
// Game logic runs automatically through event handlers
}; /****
* 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.row = row;
self.col = col;
self.hasMoved = false;
var assetName = color + type.charAt(0).toUpperCase() + type.slice(1);
var pieceGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.updatePosition = function (animate) {
var targetX = boardStartX + self.col * squareSize + squareSize / 2;
var targetY = boardStartY + self.row * squareSize + squareSize / 2;
if (animate && (self.x !== targetX || self.y !== targetY)) {
tween(self, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut
});
} else {
self.x = targetX;
self.y = targetY;
}
};
self.canMoveTo = function (targetRow, targetCol) {
if (targetRow < 0 || targetRow > 7 || targetCol < 0 || targetCol > 15) {
return false;
}
var targetPiece = getPieceAt(targetRow, targetCol);
if (targetPiece && targetPiece.pieceColor === self.pieceColor) {
return false;
}
switch (self.pieceType) {
case 'pawn':
return self.canPawnMove(targetRow, targetCol);
case 'rook':
return self.canRookMove(targetRow, targetCol);
case 'knight':
return self.canKnightMove(targetRow, targetCol);
case 'bishop':
return self.canBishopMove(targetRow, targetCol);
case 'queen':
return self.canQueenMove(targetRow, targetCol);
case 'king':
return self.canKingMove(targetRow, targetCol);
}
return false;
};
self.canPawnMove = function (targetRow, targetCol) {
var direction = self.pieceColor === 'white' ? -1 : 1;
var startRow = self.pieceColor === 'white' ? 6 : 1;
if (targetCol === self.col) {
if (targetRow === self.row + direction && !getPieceAt(targetRow, targetCol)) {
return true;
}
if (self.row === startRow && targetRow === self.row + 2 * direction && !getPieceAt(targetRow, targetCol)) {
return true;
}
} else if (Math.abs(targetCol - self.col) === 1 && targetRow === self.row + direction) {
var targetPiece = getPieceAt(targetRow, targetCol);
if (targetPiece && targetPiece.pieceColor !== self.pieceColor) {
return true;
}
}
return false;
};
self.canRookMove = function (targetRow, targetCol) {
if (self.row !== targetRow && self.col !== targetCol) {
return false;
}
return isPathClear(self.row, self.col, targetRow, targetCol);
};
self.canKnightMove = function (targetRow, targetCol) {
var rowDiff = Math.abs(targetRow - self.row);
var colDiff = Math.abs(targetCol - self.col);
return rowDiff === 2 && colDiff === 1 || rowDiff === 1 && colDiff === 2;
};
self.canBishopMove = function (targetRow, targetCol) {
if (Math.abs(targetRow - self.row) !== Math.abs(targetCol - self.col)) {
return false;
}
return isPathClear(self.row, self.col, targetRow, targetCol);
};
self.canQueenMove = function (targetRow, targetCol) {
return self.canRookMove(targetRow, targetCol) || self.canBishopMove(targetRow, targetCol);
};
self.canKingMove = function (targetRow, targetCol) {
var rowDiff = Math.abs(targetRow - self.row);
var colDiff = Math.abs(targetCol - self.col);
return rowDiff <= 1 && colDiff <= 1;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2D1810
});
/****
* Game Code
****/
// Game dimensions and board setup
// Chess board squares
// White pieces
// Black pieces
// Sound effects
var squareSize = 128;
var boardStartX = (2048 - squareSize * 16) / 2;
var boardStartY = (2732 - squareSize * 8) / 2 + 100;
// Game state
var currentPlayer = 'white';
var selectedPiece = null;
var validMoves = [];
var pieces = [];
var gameBoard = [];
var highlightSquares = [];
var validMoveSquares = [];
var dragNode = null;
var gameState = 'playing'; // playing, check, checkmate, stalemate
// Initialize empty board
for (var row = 0; row < 8; row++) {
gameBoard[row] = [];
for (var col = 0; col < 16; col++) {
gameBoard[row][col] = null;
}
}
// Create visual board
var boardContainer = game.addChild(new Container());
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
var isLight = (row + col) % 2 === 0;
var square = LK.getAsset(isLight ? 'lightSquare' : 'darkSquare', {
anchorX: 0,
anchorY: 0
});
square.x = boardStartX + col * squareSize;
square.y = boardStartY + row * squareSize;
boardContainer.addChild(square);
}
}
// Initialize pieces
var pieceSetup = [['rook', 'knight', 'bishop', 'rook', 'queen', 'king', 'queen', 'rook', 'bishop', 'knight', 'rook', 'bishop', 'knight', 'rook', 'knight', 'bishop'], ['pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn']];
// Create black pieces
for (var row = 0; row < 2; row++) {
for (var col = 0; col < 16; col++) {
var piece = new ChessPiece(pieceSetup[row][col], 'black', row, col);
pieces.push(piece);
gameBoard[row][col] = piece;
game.addChild(piece);
piece.updatePosition();
}
}
// Create white pieces
for (var row = 6; row < 8; row++) {
for (var col = 0; col < 16; col++) {
var pieceType = row === 6 ? 'pawn' : pieceSetup[7 - row][col];
var piece = new ChessPiece(pieceType, 'white', row, col);
pieces.push(piece);
gameBoard[row][col] = piece;
game.addChild(piece);
piece.updatePosition();
}
}
// UI Elements
var turnText = new Text2('Your Turn', {
size: 80,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
LK.gui.top.addChild(turnText);
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = 100;
LK.gui.top.addChild(scoreText);
function getPieceAt(row, col) {
if (row < 0 || row > 7 || col < 0 || col > 15) {
return null;
}
return gameBoard[row][col];
}
function isPathClear(fromRow, fromCol, toRow, toCol) {
var rowStep = toRow > fromRow ? 1 : toRow < fromRow ? -1 : 0;
var colStep = toCol > fromCol ? 1 : toCol < fromCol ? -1 : 0;
var currentRow = fromRow + rowStep;
var currentCol = fromCol + colStep;
while (currentRow !== toRow || currentCol !== toCol) {
if (getPieceAt(currentRow, currentCol)) {
return false;
}
currentRow += rowStep;
currentCol += colStep;
}
return true;
}
function getSquareFromPosition(x, y) {
var col = Math.floor((x - boardStartX) / squareSize);
var row = Math.floor((y - boardStartY) / squareSize);
if (row >= 0 && row < 8 && col >= 0 && col < 16) {
return {
row: row,
col: col
};
}
return null;
}
function clearHighlights() {
for (var i = 0; i < highlightSquares.length; i++) {
highlightSquares[i].destroy();
}
highlightSquares = [];
for (var i = 0; i < validMoveSquares.length; i++) {
validMoveSquares[i].destroy();
}
validMoveSquares = [];
}
function highlightSquare(row, col, color) {
var highlight = LK.getAsset(color === 'blue' ? 'highlightSquare' : 'validMoveSquare', {
anchorX: 0,
anchorY: 0,
alpha: 0.7
});
highlight.x = boardStartX + col * squareSize;
highlight.y = boardStartY + row * squareSize;
game.addChild(highlight);
if (color === 'blue') {
highlightSquares.push(highlight);
} else {
validMoveSquares.push(highlight);
}
}
function showValidMoves(piece) {
validMoves = [];
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
if (piece.canMoveTo(row, col)) {
validMoves.push({
row: row,
col: col
});
highlightSquare(row, col, 'green');
}
}
}
}
function movePiece(piece, newRow, newCol) {
var capturedPiece = getPieceAt(newRow, newCol);
var isCapture = capturedPiece !== null;
// Remove piece from old position
gameBoard[piece.row][piece.col] = null;
// Remove captured piece
if (capturedPiece) {
for (var i = 0; i < pieces.length; i++) {
if (pieces[i] === capturedPiece) {
pieces[i].destroy();
pieces.splice(i, 1);
break;
}
}
LK.setScore(LK.getScore() + getPieceValue(capturedPiece.pieceType));
scoreText.setText('Score: ' + LK.getScore());
}
// Move piece to new position
piece.row = newRow;
piece.col = newCol;
piece.hasMoved = true;
gameBoard[newRow][newCol] = piece;
piece.updatePosition(true);
// Play sound
if (isCapture) {
LK.getSound('capture').play();
} else {
LK.getSound('move').play();
}
// Check for pawn promotion
if (piece.pieceType === 'pawn' && (newRow === 0 || newRow === 7)) {
promotePawn(piece);
}
// Switch turns
currentPlayer = currentPlayer === 'white' ? 'black' : 'white';
turnText.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + '\'s Turn');
// Check for check/checkmate
if (isInCheck(currentPlayer)) {
if (isCheckmate(currentPlayer)) {
gameState = 'checkmate';
var winner = currentPlayer === 'white' ? 'Black' : 'White';
turnText.setText(winner + ' Wins!');
LK.setTimeout(function () {
restartGame();
}, 2000);
} else {
gameState = 'check';
LK.getSound('check').play();
turnText.setText(currentPlayer.charAt(0).toUpperCase() + currentPlayer.slice(1) + ' in Check!');
}
} else if (isStalemate(currentPlayer)) {
gameState = 'stalemate';
turnText.setText('Stalemate!');
LK.setTimeout(function () {
restartGame();
}, 2000);
} else {
gameState = 'playing';
}
// Trigger AI move if it's black's turn
if (currentPlayer === 'black' && gameState === 'playing') {
makeAIMove();
}
}
function getPieceValue(pieceType) {
switch (pieceType) {
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 promotePawn(pawn) {
// Simple promotion to queen for now
pawn.pieceType = 'queen';
pawn.destroy();
var newQueen = new ChessPiece('queen', pawn.pieceColor, pawn.row, pawn.col);
for (var i = 0; i < pieces.length; i++) {
if (pieces[i] === pawn) {
pieces[i] = newQueen;
break;
}
}
gameBoard[pawn.row][pawn.col] = newQueen;
game.addChild(newQueen);
newQueen.updatePosition();
}
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 && piece.canMoveTo(king.row, 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.pieceColor === color) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
if (piece.canMoveTo(row, col)) {
// Simulate move
var originalRow = piece.row;
var originalCol = piece.col;
var capturedPiece = getPieceAt(row, col);
gameBoard[originalRow][originalCol] = null;
gameBoard[row][col] = piece;
piece.row = row;
piece.col = col;
var stillInCheck = isInCheck(color);
// Restore position
piece.row = originalRow;
piece.col = originalCol;
gameBoard[originalRow][originalCol] = piece;
gameBoard[row][col] = capturedPiece;
if (!stillInCheck) {
return false;
}
}
}
}
}
}
return true;
}
function isStalemate(color) {
if (isInCheck(color)) return false;
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.pieceColor === color) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
if (piece.canMoveTo(row, col)) {
return false;
}
}
}
}
}
return true;
}
function getAllValidMoves(color) {
var allMoves = [];
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.pieceColor === color) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
if (piece.canMoveTo(row, col)) {
allMoves.push({
piece: piece,
toRow: row,
toCol: col
});
}
}
}
}
}
return allMoves;
}
function makeAIMove() {
if (currentPlayer !== 'black' || gameState !== 'playing') return;
var validAIMoves = getAllValidMoves('black');
if (validAIMoves.length === 0) return;
// Select random move
var randomIndex = Math.floor(Math.random() * validAIMoves.length);
var chosenMove = validAIMoves[randomIndex];
// Execute the move after a short delay to make it feel more natural
LK.setTimeout(function () {
movePiece(chosenMove.piece, chosenMove.toRow, chosenMove.toCol);
}, 800);
}
function restartGame() {
// Clear all pieces
for (var i = 0; i < pieces.length; i++) {
pieces[i].destroy();
}
pieces = [];
// Clear highlights
clearHighlights();
// Reset game state
currentPlayer = 'white';
selectedPiece = null;
validMoves = [];
dragNode = null;
gameState = 'playing';
LK.setScore(0);
scoreText.setText('Score: 0');
turnText.setText('Your Turn');
// Clear board
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 16; col++) {
gameBoard[row][col] = null;
}
}
// Recreate pieces
var pieceSetup = [['rook', 'knight', 'bishop', 'rook', 'queen', 'king', 'queen', 'rook', 'bishop', 'knight', 'rook', 'bishop', 'knight', 'rook', 'knight', 'bishop'], ['pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn']];
// Create black pieces
for (var row = 0; row < 2; row++) {
for (var col = 0; col < 16; col++) {
var piece = new ChessPiece(pieceSetup[row][col], 'black', row, col);
pieces.push(piece);
gameBoard[row][col] = piece;
game.addChild(piece);
piece.updatePosition();
}
}
// Create white pieces
for (var row = 6; row < 8; row++) {
for (var col = 0; col < 16; col++) {
var pieceType = row === 6 ? 'pawn' : pieceSetup[7 - row][col];
var piece = new ChessPiece(pieceType, 'white', row, col);
pieces.push(piece);
gameBoard[row][col] = piece;
game.addChild(piece);
piece.updatePosition();
}
}
}
game.down = function (x, y, obj) {
if (gameState !== 'playing') return;
var square = getSquareFromPosition(x, y);
if (!square) return;
var clickedPiece = getPieceAt(square.row, square.col);
if (selectedPiece) {
// Check if clicked on valid move
var isValidMove = false;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].row === square.row && validMoves[i].col === square.col) {
isValidMove = true;
break;
}
}
if (isValidMove) {
movePiece(selectedPiece, square.row, square.col);
}
clearHighlights();
selectedPiece = null;
}
if (clickedPiece && clickedPiece.pieceColor === currentPlayer && currentPlayer === 'white') {
selectedPiece = clickedPiece;
dragNode = clickedPiece;
highlightSquare(clickedPiece.row, clickedPiece.col, 'blue');
showValidMoves(clickedPiece);
}
};
game.move = function (x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
}
};
game.up = function (x, y, obj) {
if (dragNode && selectedPiece) {
var square = getSquareFromPosition(x, y);
if (square) {
var isValidMove = false;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].row === square.row && validMoves[i].col === square.col) {
isValidMove = true;
break;
}
}
if (isValidMove) {
movePiece(selectedPiece, square.row, square.col);
clearHighlights();
selectedPiece = null;
} else {
selectedPiece.updatePosition(true);
}
} else {
selectedPiece.updatePosition(true);
}
}
dragNode = null;
};
game.update = function () {
// Game logic runs automatically through event handlers
};
a black chess piece that resembles a chess pawn but is dressed like a jester. In-Game asset. 2d. High contrast. No shadows
Draw a black pawn dressed in a priest's robe and holding two crosses in the air in a divine manner. In-Game asset. 2d. High contrast. No shadows
Draw a white pawn dressed in a priest's robe and holding two crosses in the air in a divine manner. In-Game asset. 2d. High contrast. No shadows