User prompt
The giraffe cannot take a step around
User prompt
Move the giraffe one step diagonally, then make a castle-like move
User prompt
valid_distances = [3, 4, 5, 6, 7, 8] # disallow 1 and 2 for dx1, dy1 in [(-1, -1), (-1, 1), (1, -1), (1, 1)]: x1, y1 = x + dx1, y + dy1 if not is_empty(x1, y1): continue for dx2, dy2 in [(1,0), (-1,0), (0,1), (0,-1)]: for step in valid_distances: x2 = x1 + dx2 * step y2 = y1 + dy2 * step if not is_on_board(x2, y2): break if all(is_empty(x1 + dx2 * i, y1 + dy2 * i) for i in range(1, step)): if is_empty(x2, y2) or is_enemy(x2, y2): moves.append((x2, y2))
User prompt
valid_distances = [3, 4, 5, 6, 7, 8] # disallow 1 and 2 for dx1, dy1 in [(-1, -1), (-1, 1), (1, -1), (1, 1)]: x1, y1 = x + dx1, y + dy1 if not is_empty(x1, y1): continue for dx2, dy2 in [(1,0), (-1,0), (0,1), (0,-1)]: for step in valid_distances: x2 = x1 + dx2 * step y2 = y1 + dy2 * step if not is_on_board(x2, y2): break if all(is_empty(x1 + dx2 * i, y1 + dy2 * i) for i in range(1, step)): if is_empty(x2, y2) or is_enemy(x2, y2): moves.append((x2, y2))
User prompt
{ "piece": "Giraffe", "movement": { "type": "two-step", "steps": [ { "name": "diagonal_step", "directions": [ [1,1], [1,-1], [-1,1], [-1,-1] ], "distance": 1, "must_be_empty": true }, { "name": "straight_line", "directions": [ [1,0], [-1,0], [0,1], [0,-1] ], "allowed_distances": [3, 4, 5, 6, 7, 8], "each_square_must_be_empty": true, "last_square_can_capture_enemy": true } ] }, "constraints": { "cannot_jump": true, "cannot_pass_through_friendly_pieces": true, "must_stay_on_board": true }, "notes": "Zürafa may only move in the pattern of 1 square diagonally followed by a straight orthogonal move of **exactly 3 or more squares**. Distances of 1 or 2 squares in the straight segment are **explicitly disallowed**." }
User prompt
“min_distance”: 3 and “max_distance”: 8 → Open range, AI can try these distances in a loop. “execution_order” → Clarifies that it is cross first, then straight. “each_square_must_be_empty”: true → Clarifies that it is not a jumper. “last_square_can_capture_enemy”: true → Permission to capture if there is an enemy in the last square
User prompt
for dx1, dy1 in [(-1,-1), (-1,1), (1,-1), (1,1)]: x1, y1 = x + dx1, y + dy1 if not is_empty(x1, y1): continue # Phase 2: move at least 3 squares orthogonally for dx2, dy2 in [(1,0), (-1,0), (0,1), (0,-1)]: for step in range(3, 9): # Min 3, Max 8 x2 = x1 + dx2 * step y2 = y1 + dy2 * step # Check path squares are empty path_clear = all( is_empty(x1 + dx2 * i, y1 + dy2 * i) for i in range(1, step) ) if not path_clear: break # Add move if last square is empty or has enemy if is_empty(x2, y2) or is_enemy(x2, y2): moves.append((x2, y2))
User prompt
for dx1, dy1 in [(-1,-1), (-1,1), (1,-1), (1,1)]: x1, y1 = x + dx1, y + dy1 if not is_empty(x1, y1): continue # Phase 2: move at least 3 squares orthogonally for dx2, dy2 in [(1,0), (-1,0), (0,1), (0,-1)]: for step in range(3, 9): # Min 3, Max 8 x2 = x1 + dx2 * step y2 = y1 + dy2 * step # Check path squares are empty path_clear = all( is_empty(x1 + dx2 * i, y1 + dy2 * i) for i in range(1, step) ) if not path_clear: break # Add move if last square is empty or has enemy if is_empty(x2, y2) or is_enemy(x2, y2): moves.append((x2, y2))
User prompt
{ "piece": "Giraffe", "type": "compound-step", "movement": { "phase_1": { "direction": "diagonal", "dx": [+1, -1], "dy": [+1, -1], "distance": 1, "must_be_empty": true }, "phase_2": { "direction": "orthogonal", "axes": ["horizontal", "vertical"], "min_distance": 3, "max_distance": 8, "each_square_must_be_empty": true, "last_square_can_capture_enemy": true } }, "constraints": { "cannot_jump_over_pieces": true, "cannot_pass_through_friendly_pieces": true, "must_remain_on_board": true }, "execution_order": [ "phase_1", "phase_2" ], "description": "The Giraffe moves in two phases. First, it moves exactly 1 square diagonally in any of the 4 diagonal directions. Then, from the new square, it moves in a straight orthogonal line (up, down, left, or right) for a minimum of 3 squares and up to a maximum of 8, passing through only empty squares. It may capture an enemy piece only on the final square." }
User prompt
“compound-step” → The movement is not single-step, but two-step. First step is diagonal: “distance”: 1 Second step is straight: “min_distance”: 3, can be unlimited length. “must_be_empty”: true → Cannot move over stones. “can_capture_on_last_square”: true → Can capture an enemy on the last square. “cannot_jump”: true → Cannot jump like a knight.
User prompt
The giraffe moves in a long L shape or can move as it pleases
User prompt
Do not give the giraffe any movement characteristics; delete all of its movements
User prompt
The giraffe draws a long L but cannot jump.
User prompt
The giraffe moves one square diagonally, then one square vertically
User prompt
The giraffe can move one square diagonally.
User prompt
Reset moveset of giraffe
User prompt
The giraffe's movements are rewritten as a two-step walk: first, exactly one square diagonally, then at least three squares straight ahead. It cannot jump over stones, and all squares it passes along the way must be empty. This stone is not a jumper, but a sliding stone that moves in a special pattern
User prompt
The giraffe piece moves in two stages: first, exactly one square diagonally, then at least three squares straight. It cannot jump over other pieces, and all squares it passes through must be empty. This piece does not jump, but slides along a special pattern.
User prompt
def giraffe_moves(board, x, y): directions = [ (1,1), (1,-1), (-1,1), (-1,-1) ] moves = [] for dx1, dy1 in directions: inter_x, inter_y = x + dx1, y + dy1 # Eğer ilk çapraz kare tahtadaysa ve boşsa devam et if not is_on_board(inter_x, inter_y) or not is_empty(board, inter_x, inter_y): continue # Dört düz yön: sağ, sol, yukarı, aşağı for dx2, dy2 in [(1,0), (-1,0), (0,1), (0,-1)]: for step in range(3, board_size): # en az 3 kare gitmeli final_x = inter_x + dx2 * step final_y = inter_y + dy2 * step if not is_on_board(final_x, final_y): break # Yol üzerindeki kareler boş mu? path_clear = True for i in range(1, step): mid_x = inter_x + dx2 * i mid_y = inter_y + dy2 * i if not is_empty(board, mid_x, mid_y): path_clear = False break if path_clear: if is_empty(board, final_x, final_y) or is_enemy(board, x, y, final_x, final_y): moves.append((final_x, final_y)) else: break return moves
User prompt
Zürafa taşı iki aşamalı hareket eder: Aşama 1 (çapraz): (±1, ±1) Aşama 2 (düz): Dikey: (0, ±n) Yatay: (±n, 0) Burada n ≥ 3 (en az 3 kare düz) Yani örnek bir tam hareket dizisi:
User prompt
def giraffe_moves(x, y): moves = [] for dx1 in [+1, -1]: for dy1 in [+1, -1]: for straight in [(3,0),(-3,0),(0,3),(0,-3)]: nx = x + dx1 + straight[0] ny = y + dy1 + straight[1] moves.append((nx, ny)) return moves
User prompt
The squares that the giraffe stone can move to in one move can be defined by the following eight vectors: scss Copy Edit (+3, +1), (+3, -1), (-3, +1), (-3, -1) (+1, +3), (+1, -3), (-1, +3), (-1, -3) This moves like a Knight piece, but the vector is longer (±2,±1 for the Knight; ±3,±1 for the Giraffe).
User prompt
Rewrite the giraffe move: moves one square diagonally and then a minimum of three squares horizontally or vertically
User prompt
Add to the giraffe movement After moving, it must move at least 3 squares vertically or horizontally. Do not change the remaining movements
User prompt
Add to giraffe movement After moving, it must move at least 3 squares vertically or horizontally
/****
* 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':
// Giraffe: 1 square diagonally, then 3+ squares orthogonally
var diagonalDirections = [{
dr: 1,
dc: 1
}, {
dr: 1,
dc: -1
}, {
dr: -1,
dc: 1
}, {
dr: -1,
dc: -1
}];
var orthogonalDirections = [{
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
}, {
dr: 0,
dc: 1
}, {
dr: 0,
dc: -1
}];
// Try diagonal step first, then orthogonal moves
for (var i = 0; i < diagonalDirections.length; i++) {
var diagDir = diagonalDirections[i];
var diagRow = self.boardRow + diagDir.dr;
var diagCol = self.boardCol + diagDir.dc;
// First square (diagonal) must be empty
if (!isValidSquare(diagRow, diagCol)) {
continue;
}
var diagPiece = getPieceAt(diagRow, diagCol);
if (diagPiece) {
continue; // Must be empty
}
// From diagonal position, try orthogonal moves of 3+ squares
for (var j = 0; j < orthogonalDirections.length; j++) {
var orthDir = orthogonalDirections[j];
// Try distances 3, 4, 5, 6, 7, 8
for (var dist = 3; dist <= 8; dist++) {
var finalRow = diagRow + orthDir.dr * dist;
var finalCol = diagCol + orthDir.dc * dist;
if (!isValidSquare(finalRow, finalCol)) {
break; // Out of bounds
}
// Check if path is clear
var pathBlocked = false;
for (var checkDist = 1; checkDist <= dist; checkDist++) {
var checkRow = diagRow + orthDir.dr * checkDist;
var checkCol = diagCol + orthDir.dc * checkDist;
var pathPiece = getPieceAt(checkRow, checkCol);
if (pathPiece) {
if (checkDist === dist) {
// Last square - can capture enemy
if (pathPiece.pieceColor !== self.pieceColor) {
moves.push({
row: finalRow,
col: finalCol
});
}
} else {
// Path must be clear
pathBlocked = true;
}
break;
}
}
if (pathBlocked) {
break; // Can't continue in this direction
}
if (!getPieceAt(finalRow, finalCol)) {
moves.push({
row: finalRow,
col: finalCol
});
}
}
}
}
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
@@ -702,11 +702,10 @@
}
}
break;
case 'giraffe':
- // Giraffe moves in cross pattern first, then straight
- // Distance range 3-8, cannot jump over pieces
- var crossDirections = [{
+ // Giraffe: 1 square diagonally, then 3+ squares orthogonally
+ var diagonalDirections = [{
dr: 1,
dc: 1
}, {
dr: 1,
@@ -717,101 +716,75 @@
}, {
dr: -1,
dc: -1
}];
- var straightDirections = [{
- dr: 0,
- dc: 1
- }, {
- dr: 0,
- dc: -1
- }, {
+ var orthogonalDirections = [{
dr: 1,
dc: 0
}, {
dr: -1,
dc: 0
+ }, {
+ dr: 0,
+ dc: 1
+ }, {
+ dr: 0,
+ dc: -1
}];
- // Try each distance from 3 to 8
- for (var dist = 3; dist <= 8; dist++) {
- // First, move cross (diagonally)
- for (var i = 0; i < crossDirections.length; i++) {
- var crossDir = crossDirections[i];
- var crossRow = self.boardRow + crossDir.dr * dist;
- var crossCol = self.boardCol + crossDir.dc * dist;
- if (!isValidSquare(crossRow, crossCol)) {
- continue;
- }
- // Check if cross path is blocked
- var crossBlocked = false;
- for (var checkDist = 1; checkDist <= dist; checkDist++) {
- var checkRow = self.boardRow + crossDir.dr * checkDist;
- var checkCol = self.boardCol + crossDir.dc * checkDist;
- var pathPiece = getPieceAt(checkRow, checkCol);
- if (pathPiece) {
- if (checkDist === dist) {
- // Last square - can capture enemy
- if (pathPiece.pieceColor !== self.pieceColor) {
- moves.push({
- row: crossRow,
- col: crossCol
- });
+ // Try diagonal step first, then orthogonal moves
+ for (var i = 0; i < diagonalDirections.length; i++) {
+ var diagDir = diagonalDirections[i];
+ var diagRow = self.boardRow + diagDir.dr;
+ var diagCol = self.boardCol + diagDir.dc;
+ // First square (diagonal) must be empty
+ if (!isValidSquare(diagRow, diagCol)) {
+ continue;
+ }
+ var diagPiece = getPieceAt(diagRow, diagCol);
+ if (diagPiece) {
+ continue; // Must be empty
+ }
+ // From diagonal position, try orthogonal moves of 3+ squares
+ for (var j = 0; j < orthogonalDirections.length; j++) {
+ var orthDir = orthogonalDirections[j];
+ // Try distances 3, 4, 5, 6, 7, 8
+ for (var dist = 3; dist <= 8; dist++) {
+ var finalRow = diagRow + orthDir.dr * dist;
+ var finalCol = diagCol + orthDir.dc * dist;
+ if (!isValidSquare(finalRow, finalCol)) {
+ break; // Out of bounds
+ }
+ // Check if path is clear
+ var pathBlocked = false;
+ for (var checkDist = 1; checkDist <= dist; checkDist++) {
+ var checkRow = diagRow + orthDir.dr * checkDist;
+ var checkCol = diagCol + orthDir.dc * checkDist;
+ var pathPiece = getPieceAt(checkRow, checkCol);
+ if (pathPiece) {
+ if (checkDist === dist) {
+ // Last square - can capture enemy
+ if (pathPiece.pieceColor !== self.pieceColor) {
+ moves.push({
+ row: finalRow,
+ col: finalCol
+ });
+ }
+ } else {
+ // Path must be clear
+ pathBlocked = true;
}
- } else {
- // Intermediate square must be empty
- crossBlocked = true;
break;
}
}
- }
- if (!crossBlocked) {
- var crossPiece = getPieceAt(crossRow, crossCol);
- if (!crossPiece) {
+ if (pathBlocked) {
+ break; // Can't continue in this direction
+ }
+ if (!getPieceAt(finalRow, finalCol)) {
moves.push({
- row: crossRow,
- col: crossCol
+ row: finalRow,
+ col: finalCol
});
}
- // Then move straight from cross position
- for (var j = 0; j < straightDirections.length; j++) {
- var straightDir = straightDirections[j];
- var finalRow = crossRow + straightDir.dr * dist;
- var finalCol = crossCol + straightDir.dc * dist;
- if (!isValidSquare(finalRow, finalCol)) {
- continue;
- }
- // Check if straight path is blocked
- var straightBlocked = false;
- for (var checkDist = 1; checkDist <= dist; checkDist++) {
- var checkRow = crossRow + straightDir.dr * checkDist;
- var checkCol = crossCol + straightDir.dc * checkDist;
- var pathPiece = getPieceAt(checkRow, checkCol);
- if (pathPiece) {
- if (checkDist === dist) {
- // Last square - can capture enemy
- if (pathPiece.pieceColor !== self.pieceColor) {
- moves.push({
- row: finalRow,
- col: finalCol
- });
- }
- } else {
- // Intermediate square must be empty
- straightBlocked = true;
- break;
- }
- }
- }
- if (!straightBlocked) {
- var finalPiece = getPieceAt(finalRow, finalCol);
- if (!finalPiece) {
- moves.push({
- row: finalRow,
- col: finalCol
- });
- }
- }
- }
}
}
}
break;