User prompt
Add to giraffe movement After moving diagonally, you must move at least 3 squares vertically or horizontally.
User prompt
Add to giraffe movement Must move at least 3 squares vertically or horizontally
User prompt
Add to giraffe movement Must move at least 3 squares
User prompt
Add the giraffe's movement: 1. Cannot move to squares 2 and 3
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = 0; i < diagonalDirections.length; i++) {' Line Number: 746
Code edit (1 edits merged)
Please save this source code
User prompt
Change the giraffe's movement: It must always move 1 square diagonally and then at least 3 squares in a column or row. If there are friendly pieces in the squares it is going to move to, it cannot move to those squares or jump over the pieces.
User prompt
Change the giraffe's movement: 1 Square diagonally, then it must move at least 3 squares in a column or row. If there are friendly pieces in the squares it is going to move to, it cannot move to those squares
User prompt
Change the giraffe's movement: 1 It must move diagonally one square and then at least three squares. If there are friendly pieces on the squares it is going to move to, it cannot move to those squares. I want it to move at least three squares. 2 It must never move one square
User prompt
Change the giraffe's movement: 1 It must move diagonally one square and then at least three squares. If there are friendly pieces on the squares it is going to move to, it cannot move to those squares
User prompt
Change the giraffe's movement: 1 It must move diagonally one square and then at least two squares. If there are friendly pieces on the squares it is going to move to, it cannot move to those squares.
User prompt
The giraffe must move at least 3 squares to the right or left, otherwise it cannot move.
User prompt
The giraffe must move at least 3 squares to the right or left, otherwise it cannot move. Do not change the remaining moves.
User prompt
The giraffe must move at least 3 squares, otherwise it cannot move. Do not change the remaining moves.
User prompt
When the giraffe moves left or right, there must be one square diagonally in front of it and two squares in the direction it is moving, and once these squares are empty, it can move as far as it wants in the direction it wants to go, provided that there are at least three squares. Do not change the remaining moves
User prompt
Add bull can move one column forward or backward. Do not change the remaining moves
User prompt
The bull can move one column forward or backward. Do not change the remaining moves
Code edit (2 edits merged)
Please save this source code
User prompt
Add Taurus can advance one column. Do not change the remaining movements
User prompt
Taurus can advance one column do not change the remaining movements
User prompt
Taurus can advance one column do not change the remaining movements
User prompt
Taurus can advance one column and change the rest of its moves
User prompt
The bull must move one square in the direction of the column, then move diagonally from the square it is in to an unlimited number of squares. If it has moved one column forward, it can only move diagonally forward. The same applies to backward movements. Do not change the remaining movements
Code edit (1 edits merged)
Please save this source code
/****
* 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; // 0 = white, 1 = black
self.boardRow = row;
self.boardCol = col;
self.hasMoved = false;
self.isPromoted = false; // Track permanent promotion status for vizier
var pieceGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
if (color === 1) {
pieceGraphics.tint = 0x333333;
}
self.moveTo = function (newRow, newCol) {
self.boardRow = newRow;
self.boardCol = newCol;
self.hasMoved = true;
var boardPos = getBoardPosition(newRow, newCol);
tween(self, {
x: boardPos.x,
y: boardPos.y
}, {
duration: 300
});
};
self.getRawMoves = function () {
var moves = [];
var directions = [];
switch (self.pieceType) {
case 'pawn':
var direction = self.pieceColor === 0 ? -1 : 1;
var startRow = self.pieceColor === 0 ? 7 : 2;
// Forward move
if (isValidSquare(self.boardRow + direction, self.boardCol) && !getPieceAt(self.boardRow + direction, self.boardCol)) {
moves.push({
row: self.boardRow + direction,
col: self.boardCol
});
// Double move from start
if (self.boardRow === startRow && !getPieceAt(self.boardRow + 2 * direction, self.boardCol)) {
moves.push({
row: self.boardRow + 2 * direction,
col: self.boardCol
});
}
}
// Diagonal captures
for (var dc = -1; dc <= 1; dc += 2) {
var newRow = self.boardRow + direction;
var newCol = self.boardCol + dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (piece && piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
// En passant
if (lastMove && lastMove.piece.pieceType === 'pawn' && Math.abs(lastMove.fromRow - lastMove.toRow) === 2) {
if (lastMove.toRow === self.boardRow && Math.abs(lastMove.toCol - self.boardCol) === 1) {
moves.push({
row: self.boardRow + direction,
col: lastMove.toCol,
isEnPassant: true,
captureRow: lastMove.toRow,
captureCol: lastMove.toCol
});
}
}
}
break;
case 'rook':
directions = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
for (var dist = 1; dist < 11; dist++) {
var newRow = self.boardRow + dir.dr * dist;
var newCol = self.boardCol + dir.dc * dist;
if (!isValidSquare(newRow, newCol)) {
break;
}
var piece = getPieceAt(newRow, newCol);
if (piece) {
if (piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
moves.push({
row: newRow,
col: newCol
});
}
}
break;
case 'bishop':
// Bishop can move one square orthogonally (row/column only)
var oneSquareOrthogonalDirections = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
// Add one square moves in orthogonal directions only
for (var i = 0; i < oneSquareOrthogonalDirections.length; i++) {
var dir = oneSquareOrthogonalDirections[i];
var newRow = self.boardRow + dir.dr;
var newCol = self.boardCol + dir.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
// Bishop can also move as many squares as wanted diagonally (minimum 2) without jumping over friendly pieces
var diagonalDirections = [{
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
for (var i = 0; i < diagonalDirections.length; i++) {
var dir = diagonalDirections[i];
for (var dist = 2; dist < 11; dist++) {
var newRow = self.boardRow + dir.dr * dist;
var newCol = self.boardCol + dir.dc * dist;
if (!isValidSquare(newRow, newCol)) {
break;
}
var piece = getPieceAt(newRow, newCol);
if (piece) {
if (piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
// Check if path is blocked by friendly piece
var pathBlocked = false;
for (var checkDist = 1; checkDist < dist; checkDist++) {
var checkRow = self.boardRow + dir.dr * checkDist;
var checkCol = self.boardCol + dir.dc * checkDist;
var pathPiece = getPieceAt(checkRow, checkCol);
if (pathPiece && pathPiece.pieceColor === self.pieceColor) {
pathBlocked = true;
break;
}
}
if (pathBlocked) {
break;
}
moves.push({
row: newRow,
col: newCol
});
}
}
break;
case 'queen':
// Vizier: restricted to one square, enhanced to eight squares when promoted
// Diagonal movement is closed at the beginning (only orthogonal moves allowed)
// When promoted, both orthogonal and diagonal moves are allowed
if (self.isPromoted) {
directions = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}, {
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
} else {
// Only orthogonal moves at the beginning (diagonals closed)
directions = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
}
var maxDistance = self.isPromoted ? 8 : 1;
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
for (var dist = 1; dist <= maxDistance; dist++) {
var newRow = self.boardRow + dir.dr * dist;
var newCol = self.boardCol + dir.dc * dist;
if (!isValidSquare(newRow, newCol)) {
break;
}
var piece = getPieceAt(newRow, newCol);
if (piece) {
if (piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
moves.push({
row: newRow,
col: newCol
});
}
}
break;
case 'king':
directions = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}, {
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
var newRow = self.boardRow + dir.dr;
var newCol = self.boardCol + dir.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
break;
case 'knight':
var knightMoves = [{
dr: 2,
dc: 1
}, {
dr: 2,
dc: -1
}, {
dr: -2,
dc: 1
}, {
dr: -2,
dc: -1
}, {
dr: 1,
dc: 2
}, {
dr: 1,
dc: -2
}, {
dr: -1,
dc: 2
}, {
dr: -1,
dc: -2
}];
for (var i = 0; i < knightMoves.length; i++) {
var move = knightMoves[i];
var newRow = self.boardRow + move.dr;
var newCol = self.boardCol + move.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
break;
case 'warElephant':
// Moves 1 or 2 steps row, column, and diagonal with jumping ability
directions = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}, {
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
for (var dist = 1; dist <= 2; dist++) {
var newRow = self.boardRow + dir.dr * dist;
var newCol = self.boardCol + dir.dc * dist;
if (!isValidSquare(newRow, newCol)) {
break;
}
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
break;
case 'siegeTower':
// Must move 1 square in row/column, then 1 square diagonally
// If friendly piece in path, can move 1 step in row/column
// Captures enemy pieces in its path
var orthogonalDirections = [{
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}, {
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}];
var diagonalDirections = [{
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
// Try L-shaped moves: orthogonal then diagonal
for (var i = 0; i < orthogonalDirections.length; i++) {
var orthDir = orthogonalDirections[i];
var firstRow = self.boardRow + orthDir.dr;
var firstCol = self.boardCol + orthDir.dc;
if (!isValidSquare(firstRow, firstCol)) {
continue;
}
var firstPiece = getPieceAt(firstRow, firstCol);
// If friendly piece blocks first step, can only move orthogonally
if (firstPiece && firstPiece.pieceColor === self.pieceColor) {
// Can't move through friendly piece, skip this direction
continue;
}
// Try diagonal moves from the orthogonal position
for (var j = 0; j < diagonalDirections.length; j++) {
var diagDir = diagonalDirections[j];
var finalRow = firstRow + diagDir.dr;
var finalCol = firstCol + diagDir.dc;
if (!isValidSquare(finalRow, finalCol)) {
continue;
}
var finalPiece = getPieceAt(finalRow, finalCol);
if (!finalPiece || finalPiece.pieceColor !== self.pieceColor) {
var moveData = {
row: finalRow,
col: finalCol,
capturesInPath: []
};
// Add captured pieces in path
if (firstPiece && firstPiece.pieceColor !== self.pieceColor) {
moveData.capturesInPath.push({
row: firstRow,
col: firstCol
});
}
if (finalPiece && finalPiece.pieceColor !== self.pieceColor) {
moveData.capturesInPath.push({
row: finalRow,
col: finalCol
});
}
moves.push(moveData);
}
}
}
// If friendly piece in orthogonal path, allow simple orthogonal move
for (var i = 0; i < orthogonalDirections.length; i++) {
var orthDir = orthogonalDirections[i];
var newRow = self.boardRow + orthDir.dr;
var newCol = self.boardCol + orthDir.dc;
if (!isValidSquare(newRow, newCol)) {
continue;
}
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
break;
case 'minister':
// Minister: 1 square diagonally, when promoted moves like rook and knight with jumping
if (self.isPromoted) {
// Rook-like moves (can jump over pieces when promoted)
var rookDirections = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
for (var i = 0; i < rookDirections.length; i++) {
var dir = rookDirections[i];
for (var dist = 1; dist < 11; dist++) {
var newRow = self.boardRow + dir.dr * dist;
var newCol = self.boardCol + dir.dc * dist;
if (!isValidSquare(newRow, newCol)) {
break;
}
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
// Knight-like moves (can jump over pieces)
var knightMoves = [{
dr: 2,
dc: 1
}, {
dr: 2,
dc: -1
}, {
dr: -2,
dc: 1
}, {
dr: -2,
dc: -1
}, {
dr: 1,
dc: 2
}, {
dr: 1,
dc: -2
}, {
dr: -1,
dc: 2
}, {
dr: -1,
dc: -2
}];
for (var i = 0; i < knightMoves.length; i++) {
var move = knightMoves[i];
var newRow = self.boardRow + move.dr;
var newCol = self.boardCol + move.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
} else {
// Standard minister: 1 square diagonally
directions = [{
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
var newRow = self.boardRow + dir.dr;
var newCol = self.boardCol + dir.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
}
break;
case 'royalGuard':
// Up to 3 squares diagonally with blockage of friendly pieces
var diagonalDirections = [{
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
for (var i = 0; i < diagonalDirections.length; i++) {
var dir = diagonalDirections[i];
for (var dist = 1; dist <= 3; dist++) {
var newRow = self.boardRow + dir.dr * dist;
var newCol = self.boardCol + dir.dc * dist;
if (!isValidSquare(newRow, newCol)) {
break;
}
var piece = getPieceAt(newRow, newCol);
if (piece) {
if (piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
moves.push({
row: newRow,
col: newCol
});
}
}
// Only 2 squares along rows and columns (no 1-step moves)
var orthogonalDirections = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
for (var i = 0; i < orthogonalDirections.length; i++) {
var dir = orthogonalDirections[i];
// Only allow 2-step moves in orthogonal directions
var dist = 2;
var newRow = self.boardRow + dir.dr * dist;
var newCol = self.boardCol + dir.dc * dist;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
// Forward or backward L-shaped moves (no left/right L moves)
var lShapeMoves = [
// Forward L-shapes
{
dr: -2,
dc: 1
}, {
dr: -2,
dc: -1
},
// Backward L-shapes
{
dr: 2,
dc: 1
}, {
dr: 2,
dc: -1
}];
for (var i = 0; i < lShapeMoves.length; i++) {
var move = lShapeMoves[i];
var newRow = self.boardRow + move.dr;
var newCol = self.boardCol + move.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
break;
case 'giraffe':
// Moves diagonally one square and then horizontally or vertically at least three squares (or four if desired)
// All squares in the path must be empty
var diagonalDirections = [{
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
var orthogonalDirections = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
// First move diagonally one square
for (var i = 0; i < diagonalDirections.length; i++) {
var diagDir = diagonalDirections[i];
var diagRow = self.boardRow + diagDir.dr;
var diagCol = self.boardCol + diagDir.dc;
if (!isValidSquare(diagRow, diagCol)) {
continue;
}
var diagPiece = getPieceAt(diagRow, diagCol);
if (diagPiece) {
continue; // Diagonal square must be empty
}
// Then move horizontally or vertically at least 3 squares
for (var j = 0; j < orthogonalDirections.length; j++) {
var orthDir = orthogonalDirections[j];
// Try moves from 3 squares up to the edge of the board
for (var dist = 3; dist < 11; dist++) {
var finalRow = diagRow + orthDir.dr * dist;
var finalCol = diagCol + orthDir.dc * dist;
if (!isValidSquare(finalRow, finalCol)) {
break;
}
// Check if all squares in the orthogonal path are empty
var pathClear = true;
for (var k = 1; k <= dist; k++) {
var checkRow = diagRow + orthDir.dr * k;
var checkCol = diagCol + orthDir.dc * k;
var pathPiece = getPieceAt(checkRow, checkCol);
if (k < dist && pathPiece) {
pathClear = false;
break;
} else if (k === dist && pathPiece && pathPiece.pieceColor === self.pieceColor) {
pathClear = false;
break;
}
}
if (pathClear) {
moves.push({
row: finalRow,
col: finalCol
});
} else {
break; // If path is blocked, stop checking further distances
}
}
}
}
// Special left/right movement: one diagonal square in front + two squares in direction + unlimited movement
var leftRightDirections = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}];
for (var i = 0; i < leftRightDirections.length; i++) {
var moveDir = leftRightDirections[i];
// Determine forward direction based on piece color
var forwardDir = self.pieceColor === 0 ? -1 : 1;
// First check: one diagonal square in front
var diagonalRow = self.boardRow + forwardDir;
var diagonalCol = self.boardCol + moveDir.dc;
if (!isValidSquare(diagonalRow, diagonalCol)) {
continue;
}
var diagonalPiece = getPieceAt(diagonalRow, diagonalCol);
if (diagonalPiece) {
continue; // Diagonal square must be empty
}
// Second check: two squares in the direction
var twoSquareRow = self.boardRow;
var twoSquareCol = self.boardCol + moveDir.dc * 2;
if (!isValidSquare(twoSquareRow, twoSquareCol)) {
continue;
}
var twoSquarePiece = getPieceAt(twoSquareRow, twoSquareCol);
if (twoSquarePiece) {
continue; // Two square position must be empty
}
// If both squares are empty, can move unlimited in that direction (minimum 3 squares)
for (var dist = 3; dist < 11; dist++) {
var finalRow = self.boardRow;
var finalCol = self.boardCol + moveDir.dc * dist;
if (!isValidSquare(finalRow, finalCol)) {
break;
}
// Check if all squares in the path are empty
var pathClear = true;
for (var k = 1; k <= dist; k++) {
var checkRow = self.boardRow;
var checkCol = self.boardCol + moveDir.dc * k;
var pathPiece = getPieceAt(checkRow, checkCol);
if (k < dist && pathPiece) {
pathClear = false;
break;
} else if (k === dist && pathPiece && pathPiece.pieceColor === self.pieceColor) {
pathClear = false;
break;
}
}
if (pathClear) {
moves.push({
row: finalRow,
col: finalCol
});
} else {
break; // If path is blocked, stop checking further distances
}
}
}
break;
case 'bull':
// Bull can move one column forward or backward
var columnDirections = [{
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
for (var i = 0; i < columnDirections.length; i++) {
var colDir = columnDirections[i];
var newRow = self.boardRow + colDir.dr;
var newCol = self.boardCol + colDir.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
// Bull moves one square forward or backward in column, then unlimited diagonal movement in same direction
for (var i = 0; i < columnDirections.length; i++) {
var colDir = columnDirections[i];
var firstRow = self.boardRow + colDir.dr;
var firstCol = self.boardCol + colDir.dc;
if (!isValidSquare(firstRow, firstCol)) {
continue;
}
var firstPiece = getPieceAt(firstRow, firstCol);
if (firstPiece) {
continue; // First square must be empty for bull movement
}
// From the first square, move diagonally unlimited in the forward/backward direction
var diagonalDirections = [{
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
for (var j = 0; j < diagonalDirections.length; j++) {
var diagDir = diagonalDirections[j];
// Only allow diagonal movement in same forward/backward direction as column move
if (colDir.dr > 0 && diagDir.dr <= 0 || colDir.dr < 0 && diagDir.dr >= 0) {
continue; // Skip diagonal directions that don't match column direction
}
// Move unlimited squares diagonally from first position
for (var dist = 1; dist < 11; dist++) {
var finalRow = firstRow + diagDir.dr * dist;
var finalCol = firstCol + diagDir.dc * dist;
if (!isValidSquare(finalRow, finalCol)) {
break;
}
var finalPiece = getPieceAt(finalRow, finalCol);
if (finalPiece) {
if (finalPiece.pieceColor !== self.pieceColor) {
moves.push({
row: finalRow,
col: finalCol
});
}
break;
}
moves.push({
row: finalRow,
col: finalCol
});
}
}
}
// Bull can also jump two squares left and right
var leftRightJumps = [{
dr: 0,
dc: 2
}, {
dr: 0,
dc: -2
}];
for (var i = 0; i < leftRightJumps.length; i++) {
var jump = leftRightJumps[i];
var newRow = self.boardRow + jump.dr;
var newCol = self.boardCol + jump.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
break;
case 'camel':
// 1 square column and row (orthogonal moves)
var orthogonalDirections = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
for (var i = 0; i < orthogonalDirections.length; i++) {
var dir = orthogonalDirections[i];
var newRow = self.boardRow + dir.dr;
var newCol = self.boardCol + dir.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
// 1 square long L (knight-like moves)
var knightMoves = [{
dr: 3,
dc: 1
}, {
dr: 3,
dc: -1
}, {
dr: -3,
dc: 1
}, {
dr: -3,
dc: -1
}, {
dr: 1,
dc: 3
}, {
dr: 1,
dc: -3
}, {
dr: -1,
dc: 3
}, {
dr: -1,
dc: -3
}];
for (var i = 0; i < knightMoves.length; i++) {
var move = knightMoves[i];
var newRow = self.boardRow + move.dr;
var newCol = self.boardCol + move.dc;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
break;
case 'lion':
// Can jump 1, 2, or 3 squares diagonally (maximum 3 squares)
var diagonalDirections = [{
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
for (var i = 0; i < diagonalDirections.length; i++) {
var dir = diagonalDirections[i];
for (var dist = 1; dist <= 3; dist++) {
var newRow = self.boardRow + dir.dr * dist;
var newCol = self.boardCol + dir.dc * dist;
if (isValidSquare(newRow, newCol)) {
var piece = getPieceAt(newRow, newCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
}
// Add ability to jump 1 square after 2 squares diagonally
for (var i = 0; i < diagonalDirections.length; i++) {
var dir = diagonalDirections[i];
// First move 2 squares diagonally
var twoSquareRow = self.boardRow + dir.dr * 2;
var twoSquareCol = self.boardCol + dir.dc * 2;
if (isValidSquare(twoSquareRow, twoSquareCol)) {
// Then move 1 square in any orthogonal direction
var oneSquareMoves = [{
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}, {
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}];
for (var j = 0; j < oneSquareMoves.length; j++) {
var oneSquareMove = oneSquareMoves[j];
var finalRow = twoSquareRow + oneSquareMove.dr;
var finalCol = twoSquareCol + oneSquareMove.dc;
if (isValidSquare(finalRow, finalCol)) {
var piece = getPieceAt(finalRow, finalCol);
if (!piece || piece.pieceColor !== self.pieceColor) {
moves.push({
row: finalRow,
col: finalCol
});
}
}
}
}
}
break;
}
return moves;
};
self.getValidMoves = function () {
var moves = self.getRawMoves();
// Add castling for king after getting raw moves
if (self.pieceType === 'king' && !self.hasMoved && !isInCheck(self.pieceColor)) {
// Kingside castling
var kingsideRook = getPieceAt(self.boardRow, self.boardCol + 3);
if (kingsideRook && kingsideRook.pieceType === 'rook' && !kingsideRook.hasMoved) {
var canCastle = true;
for (var c = self.boardCol + 1; c < self.boardCol + 3; c++) {
if (getPieceAt(self.boardRow, c) || isSquareAttacked(self.boardRow, c, 1 - self.pieceColor)) {
canCastle = false;
break;
}
}
if (canCastle) {
moves.push({
row: self.boardRow,
col: self.boardCol + 2,
isCastling: true,
rookFromCol: self.boardCol + 3,
rookToCol: self.boardCol + 1
});
}
}
// Queenside castling
var queensideRook = getPieceAt(self.boardRow, self.boardCol - 4);
if (queensideRook && queensideRook.pieceType === 'rook' && !queensideRook.hasMoved) {
var canCastle = true;
for (var c = self.boardCol - 1; c > self.boardCol - 4; c--) {
if (getPieceAt(self.boardRow, c) || isSquareAttacked(self.boardRow, c, 1 - self.pieceColor)) {
canCastle = false;
break;
}
}
if (canCastle) {
moves.push({
row: self.boardRow,
col: self.boardCol - 2,
isCastling: true,
rookFromCol: self.boardCol - 4,
rookToCol: self.boardCol - 1
});
}
}
}
// Filter moves that would leave the king in check
var validMoves = [];
for (var i = 0; i < moves.length; i++) {
if (isValidMoveConsideringCheck(self, moves[i].row, moves[i].col)) {
validMoves.push(moves[i]);
}
}
return validMoves;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
var BOARD_WIDTH = 11;
var BOARD_HEIGHT = 10;
var SQUARE_SIZE = 180;
var BOARD_START_X = (2048 - BOARD_WIDTH * SQUARE_SIZE) / 2;
var BOARD_START_Y = (2732 - BOARD_HEIGHT * SQUARE_SIZE) / 2;
var boardSquares = [];
var pieces = [];
var selectedPiece = null;
var highlightedSquares = [];
var currentPlayer = 0; // 0 = white, 1 = black
var gameStarted = false;
var lastMove = null;
function getBoardPosition(row, col) {
return {
x: BOARD_START_X + col * SQUARE_SIZE + SQUARE_SIZE / 2,
y: BOARD_START_Y + row * SQUARE_SIZE + SQUARE_SIZE / 2
};
}
function getBoardCoordinates(x, y) {
var col = Math.floor((x - BOARD_START_X) / SQUARE_SIZE);
var row = Math.floor((y - BOARD_START_Y) / SQUARE_SIZE);
return {
row: row,
col: col
};
}
function isValidSquare(row, col) {
return row >= 0 && row < BOARD_HEIGHT && col >= 0 && col < BOARD_WIDTH;
}
function getPieceAt(row, col) {
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].boardRow === row && pieces[i].boardCol === col) {
return pieces[i];
}
}
return null;
}
function createBoard() {
for (var row = 0; row < BOARD_HEIGHT; row++) {
boardSquares[row] = [];
for (var col = 0; col < BOARD_WIDTH; col++) {
var isLight = (row + col) % 2 === 0;
var square = game.addChild(LK.getAsset(isLight ? 'lightSquare' : 'darkSquare', {
anchorX: 0.5,
anchorY: 0.5
}));
var pos = getBoardPosition(row, col);
square.x = pos.x;
square.y = pos.y;
square.boardRow = row;
square.boardCol = col;
boardSquares[row][col] = square;
}
}
}
function createPieces() {
// Create pieces for both players
var pieceSetup = [
// White pieces (bottom)
{
type: 'rook',
color: 0,
row: 8,
col: 0
}, {
type: 'knight',
color: 0,
row: 8,
col: 1
}, {
type: 'warElephant',
color: 0,
row: 9,
col: 0
}, {
type: 'warElephant',
color: 0,
row: 9,
col: 10
}, {
type: 'bishop',
color: 0,
row: 8,
col: 2
}, {
type: 'queen',
color: 0,
row: 8,
col: 4
}, {
type: 'king',
color: 0,
row: 8,
col: 5
}, {
type: 'bishop',
color: 0,
row: 8,
col: 8
}, {
type: 'siegeTower',
color: 0,
row: 9,
col: 6
}, {
type: 'siegeTower',
color: 0,
row: 9,
col: 4
}, {
type: 'minister',
color: 0,
row: 8,
col: 6
}, {
type: 'giraffe',
color: 0,
row: 8,
col: 3
}, {
type: 'giraffe',
color: 0,
row: 8,
col: 7
}, {
type: 'knight',
color: 0,
row: 8,
col: 9
}, {
type: 'rook',
color: 0,
row: 8,
col: 10
},
// White royal guards
{
type: 'royalGuard',
color: 0,
row: 9,
col: 5
},
// White lions
{
type: 'lion',
color: 0,
row: 9,
col: 1
}, {
type: 'lion',
color: 0,
row: 9,
col: 9
},
// White camels
{
type: 'camel',
color: 0,
row: 9,
col: 2
}, {
type: 'camel',
color: 0,
row: 9,
col: 8
},
// White bulls
{
type: 'bull',
color: 0,
row: 9,
col: 3
}, {
type: 'bull',
color: 0,
row: 9,
col: 7
},
// Black pieces (top)
{
type: 'rook',
color: 1,
row: 1,
col: 0
}, {
type: 'knight',
color: 1,
row: 1,
col: 1
}, {
type: 'warElephant',
color: 1,
row: 0,
col: 0
}, {
type: 'warElephant',
color: 1,
row: 0,
col: 10
}, {
type: 'bishop',
color: 1,
row: 1,
col: 2
}, {
type: 'queen',
color: 1,
row: 1,
col: 6
}, {
type: 'king',
color: 1,
row: 1,
col: 5
}, {
type: 'bishop',
color: 1,
row: 1,
col: 8
}, {
type: 'siegeTower',
color: 1,
row: 0,
col: 6
}, {
type: 'siegeTower',
color: 1,
row: 0,
col: 4
}, {
type: 'minister',
color: 1,
row: 1,
col: 4
}, {
type: 'giraffe',
color: 1,
row: 1,
col: 3
}, {
type: 'giraffe',
color: 1,
row: 1,
col: 7
}, {
type: 'knight',
color: 1,
row: 1,
col: 9
}, {
type: 'rook',
color: 1,
row: 1,
col: 10
},
// Black royal guards
{
type: 'royalGuard',
color: 1,
row: 0,
col: 5
},
// Black lions
{
type: 'lion',
color: 1,
row: 0,
col: 1
}, {
type: 'lion',
color: 1,
row: 0,
col: 9
},
// Black camels
{
type: 'camel',
color: 1,
row: 0,
col: 2
}, {
type: 'camel',
color: 1,
row: 0,
col: 8
},
// Black bulls
{
type: 'bull',
color: 1,
row: 0,
col: 3
}, {
type: 'bull',
color: 1,
row: 0,
col: 7
}];
// Add pawns
for (var col = 0; col < BOARD_WIDTH; col++) {
pieceSetup.push({
type: 'pawn',
color: 0,
row: 7,
col: col
}); // White pawns
pieceSetup.push({
type: 'pawn',
color: 1,
row: 2,
col: col
}); // Black pawns
}
for (var i = 0; i < pieceSetup.length; i++) {
var setup = pieceSetup[i];
var piece = game.addChild(new ChessPiece(setup.type, setup.color, setup.row, setup.col));
var pos = getBoardPosition(setup.row, setup.col);
piece.x = pos.x;
piece.y = pos.y;
pieces.push(piece);
}
}
function clearHighlights() {
for (var i = 0; i < highlightedSquares.length; i++) {
highlightedSquares[i].destroy();
}
highlightedSquares = [];
}
function highlightMoves(moves) {
clearHighlights();
for (var i = 0; i < moves.length; i++) {
var move = moves[i];
var highlight = game.addChild(LK.getAsset('highlightSquare', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
}));
var pos = getBoardPosition(move.row, move.col);
highlight.x = pos.x;
highlight.y = pos.y;
highlightedSquares.push(highlight);
}
}
function selectPiece(piece) {
if (selectedPiece) {
selectedPiece.removeChild(selectedPiece.selectionHighlight);
selectedPiece.selectionHighlight = null;
}
selectedPiece = piece;
if (piece) {
piece.selectionHighlight = piece.addChild(LK.getAsset('selectedSquare', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
}));
var validMoves = piece.getValidMoves();
highlightMoves(validMoves);
} else {
clearHighlights();
}
}
function makeMove(piece, targetRow, targetCol, moveData) {
var originalRow = piece.boardRow;
var originalCol = piece.boardCol;
var capturedPiece = null;
var capturedPieces = [];
// Handle special moves
if (moveData && moveData.isCastling) {
// Move the rook for castling
var rook = getPieceAt(originalRow, moveData.rookFromCol);
if (rook) {
rook.moveTo(originalRow, moveData.rookToCol);
}
} else if (moveData && moveData.isEnPassant) {
// Capture the pawn for en passant
capturedPiece = getPieceAt(moveData.captureRow, moveData.captureCol);
if (capturedPiece) {
capturedPieces.push(capturedPiece);
}
} else if (moveData && moveData.capturesInPath) {
// Handle siegeTower path captures
for (var k = 0; k < moveData.capturesInPath.length; k++) {
var capturePos = moveData.capturesInPath[k];
var pathPiece = getPieceAt(capturePos.row, capturePos.col);
if (pathPiece) {
capturedPieces.push(pathPiece);
}
}
} else {
capturedPiece = getPieceAt(targetRow, targetCol);
if (capturedPiece) {
capturedPieces.push(capturedPiece);
}
}
// Remove all captured pieces
for (var k = 0; k < capturedPieces.length; k++) {
var capPiece = capturedPieces[k];
var index = pieces.indexOf(capPiece);
if (index > -1) {
pieces.splice(index, 1);
}
capPiece.destroy();
}
if (capturedPieces.length > 0) {
LK.getSound('capture').play();
} else {
LK.getSound('move').play();
}
// Store move for en passant detection
lastMove = {
piece: piece,
fromRow: originalRow,
fromCol: originalCol,
toRow: targetRow,
toCol: targetCol
};
piece.moveTo(targetRow, targetCol);
// Check for vizier promotion
if (piece.pieceType === 'queen' && !piece.isPromoted) {
var opponentLastRow = piece.pieceColor === 0 ? 0 : BOARD_HEIGHT - 1;
if (targetRow === opponentLastRow) {
piece.isPromoted = true;
// Visual feedback for promotion
LK.effects.flashObject(piece, 0xFFD700, 1000); // Flash gold
}
}
// Check for minister promotion
if (piece.pieceType === 'minister' && !piece.isPromoted) {
var opponentLastRow = piece.pieceColor === 0 ? 0 : BOARD_HEIGHT - 1;
if (targetRow === opponentLastRow) {
piece.isPromoted = true;
// Visual feedback for promotion
LK.effects.flashObject(piece, 0x9932CC, 1000); // Flash purple
}
}
currentPlayer = 1 - currentPlayer;
selectPiece(null);
// Check for victory conditions
checkGameEnd();
}
function isSquareAttacked(row, col, byColor) {
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.pieceColor !== byColor) {
continue;
}
var moves = piece.getRawMoves();
for (var j = 0; j < moves.length; j++) {
if (moves[j].row === row && moves[j].col === col) {
return true;
}
}
}
return false;
}
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;
}
return isSquareAttacked(king.boardRow, king.boardCol, 1 - color);
}
function isValidMoveConsideringCheck(piece, targetRow, targetCol) {
// Simulate the move
var originalRow = piece.boardRow;
var originalCol = piece.boardCol;
var capturedPiece = getPieceAt(targetRow, targetCol);
var capturedIndex = -1;
if (capturedPiece) {
capturedIndex = pieces.indexOf(capturedPiece);
pieces.splice(capturedIndex, 1);
}
piece.boardRow = targetRow;
piece.boardCol = targetCol;
var stillInCheck = isInCheck(piece.pieceColor);
// Restore the position
piece.boardRow = originalRow;
piece.boardCol = originalCol;
if (capturedPiece && capturedIndex > -1) {
pieces.splice(capturedIndex, 0, capturedPiece);
}
return !stillInCheck;
}
function hasValidMoves(color) {
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece.pieceColor !== color) {
continue;
}
var moves = piece.getRawMoves();
for (var j = 0; j < moves.length; j++) {
if (isValidMoveConsideringCheck(piece, moves[j].row, moves[j].col)) {
return true;
}
}
}
return false;
}
function checkGameEnd() {
var whiteKing = findKing(0);
var blackKing = findKing(1);
if (!whiteKing) {
LK.setScore(1);
LK.showGameOver();
return;
}
if (!blackKing) {
LK.setScore(1);
LK.showGameOver();
return;
}
var inCheck = isInCheck(currentPlayer);
var hasValid = hasValidMoves(currentPlayer);
if (!hasValid) {
if (inCheck) {
// Checkmate
LK.setScore(1);
LK.showGameOver();
} else {
// Stalemate
LK.setScore(0);
LK.showGameOver();
}
}
}
function initializeGame() {
createBoard();
createPieces();
gameStarted = true;
}
// Player turn indicator
var turnText = new Text2('White to move', {
size: 80,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
LK.gui.top.addChild(turnText);
game.down = function (x, y, obj) {
if (!gameStarted) {
return;
}
var coords = getBoardCoordinates(x, y);
if (!isValidSquare(coords.row, coords.col)) {
return;
}
var clickedPiece = getPieceAt(coords.row, coords.col);
if (selectedPiece) {
var validMoves = selectedPiece.getValidMoves();
var isValidMove = false;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].row === coords.row && validMoves[i].col === coords.col) {
isValidMove = true;
break;
}
}
if (isValidMove) {
var moveData = null;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].row === coords.row && validMoves[i].col === coords.col) {
moveData = validMoves[i];
break;
}
}
makeMove(selectedPiece, coords.row, coords.col, moveData);
return;
}
}
if (clickedPiece && clickedPiece.pieceColor === currentPlayer) {
selectPiece(clickedPiece);
} else {
selectPiece(null);
}
};
game.update = function () {
if (!gameStarted) {
initializeGame();
}
var playerText = currentPlayer === 0 ? 'White to move' : 'Black to move';
if (isInCheck(currentPlayer)) {
playerText += ' (Check!)';
}
turnText.setText(playerText);
}; ===================================================================
--- original.js
+++ change.js
@@ -777,8 +777,71 @@
}
}
}
}
+ // Special left/right movement: one diagonal square in front + two squares in direction + unlimited movement
+ var leftRightDirections = [{
+ dr: 0,
+ dc: 1
+ }, {
+ dr: 0,
+ dc: -1
+ }];
+ for (var i = 0; i < leftRightDirections.length; i++) {
+ var moveDir = leftRightDirections[i];
+ // Determine forward direction based on piece color
+ var forwardDir = self.pieceColor === 0 ? -1 : 1;
+ // First check: one diagonal square in front
+ var diagonalRow = self.boardRow + forwardDir;
+ var diagonalCol = self.boardCol + moveDir.dc;
+ if (!isValidSquare(diagonalRow, diagonalCol)) {
+ continue;
+ }
+ var diagonalPiece = getPieceAt(diagonalRow, diagonalCol);
+ if (diagonalPiece) {
+ continue; // Diagonal square must be empty
+ }
+ // Second check: two squares in the direction
+ var twoSquareRow = self.boardRow;
+ var twoSquareCol = self.boardCol + moveDir.dc * 2;
+ if (!isValidSquare(twoSquareRow, twoSquareCol)) {
+ continue;
+ }
+ var twoSquarePiece = getPieceAt(twoSquareRow, twoSquareCol);
+ if (twoSquarePiece) {
+ continue; // Two square position must be empty
+ }
+ // If both squares are empty, can move unlimited in that direction (minimum 3 squares)
+ for (var dist = 3; dist < 11; dist++) {
+ var finalRow = self.boardRow;
+ var finalCol = self.boardCol + moveDir.dc * dist;
+ if (!isValidSquare(finalRow, finalCol)) {
+ break;
+ }
+ // Check if all squares in the path are empty
+ var pathClear = true;
+ for (var k = 1; k <= dist; k++) {
+ var checkRow = self.boardRow;
+ var checkCol = self.boardCol + moveDir.dc * k;
+ var pathPiece = getPieceAt(checkRow, checkCol);
+ if (k < dist && pathPiece) {
+ pathClear = false;
+ break;
+ } else if (k === dist && pathPiece && pathPiece.pieceColor === self.pieceColor) {
+ pathClear = false;
+ break;
+ }
+ }
+ if (pathClear) {
+ moves.push({
+ row: finalRow,
+ col: finalCol
+ });
+ } else {
+ break; // If path is blocked, stop checking further distances
+ }
+ }
+ }
break;
case 'bull':
// Bull can move one column forward or backward
var columnDirections = [{