User prompt
when promoting a pawn to a queen delete pawn after queen spawns
User prompt
make everything bigger and center them all
User prompt
delete the text that says white goes first click a piece to select it, then click a highlighted square to move
User prompt
change text at the top that says smart chess master to Play against MissPiece
User prompt
make everything bigger and center them all
User prompt
change text at the top to Play against MissPiece
User prompt
change the text black's turn to MissPiece's Turn
User prompt
change the text black's turn to MissMate's Turn
User prompt
change text at the top to Play against MissMate
User prompt
remove the letters that are on the chess pieces
User prompt
add a button to reset the game
User prompt
make the board bigger
Code edit (1 edits merged)
Please save this source code
User prompt
Smart Chess Master
Initial prompt
Build a chess game that includes an undo move feature and a strong AI opponent. The undo feature should allow players to take back their last move, and the AI should play at a challenging level, making smart and strategic decisions.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
gameHistory: [],
stats: {
wins: 0,
losses: 0,
draws: 0
}
});
/****
* Classes
****/
var Button = Container.expand(function () {
var self = Container.call(this);
self.init = function (text, width, height, color) {
self.background = self.attachAsset('whiteSquare', {
anchorX: 0,
anchorY: 0,
width: width,
height: height,
tint: color || 0x4488FF
});
self.label = new Text2(text, {
size: 40,
fill: 0xFFFFFF
});
self.label.anchor.set(0.5, 0.5);
self.label.x = width / 2;
self.label.y = height / 2;
self.addChild(self.label);
return self;
};
self.setEnabled = function (enabled) {
self.enabled = enabled;
self.background.alpha = enabled ? 1 : 0.5;
};
self.down = function (x, y, obj) {
if (self.enabled !== false) {
LK.getSound('movePiece').play();
tween(self, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
}
};
self.up = function (x, y, obj) {
if (self.enabled !== false) {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
onFinish: function onFinish() {
if (self.onClick) {
self.onClick();
}
}
});
}
};
return self;
});
var ChessGame = Container.expand(function () {
var self = Container.call(this);
// Game state
self.board = [];
self.selectedSquare = null;
self.possibleMoves = [];
self.currentPlayer = 'white';
self.gameOver = false;
self.moveHistory = [];
self.lastMovedPiece = null;
self.lastMoveFrom = null;
self.lastMoveTo = null;
self.inCheck = {
white: false,
black: false
};
self.init = function () {
self.initializeBoard();
self.setupPieces();
self.createControls();
return self;
};
self.initializeBoard = function () {
for (var row = 0; row < 8; row++) {
self.board[row] = [];
for (var col = 0; col < 8; col++) {
var color = (row + col) % 2 === 0 ? 'white' : 'black';
var square = new ChessSquare().init(row, col, color);
square.x = col * SQUARE_SIZE;
square.y = row * SQUARE_SIZE;
self.addChild(square);
self.board[row][col] = square;
}
}
};
self.setupPieces = function () {
// Place pawns
for (var col = 0; col < 8; col++) {
self.placePiece('pawn', 'white', 6, col);
self.placePiece('pawn', 'black', 1, col);
}
// Place rooks
self.placePiece('rook', 'white', 7, 0);
self.placePiece('rook', 'white', 7, 7);
self.placePiece('rook', 'black', 0, 0);
self.placePiece('rook', 'black', 0, 7);
// Place knights
self.placePiece('knight', 'white', 7, 1);
self.placePiece('knight', 'white', 7, 6);
self.placePiece('knight', 'black', 0, 1);
self.placePiece('knight', 'black', 0, 6);
// Place bishops
self.placePiece('bishop', 'white', 7, 2);
self.placePiece('bishop', 'white', 7, 5);
self.placePiece('bishop', 'black', 0, 2);
self.placePiece('bishop', 'black', 0, 5);
// Place queens
self.placePiece('queen', 'white', 7, 3);
self.placePiece('queen', 'black', 0, 3);
// Place kings
self.placePiece('king', 'white', 7, 4);
self.placePiece('king', 'black', 0, 4);
};
self.createControls = function () {
// Undo button
self.undoButton = new Button().init("UNDO", 200, 80);
self.undoButton.x = BOARD_SIZE + 50;
self.undoButton.y = BOARD_SIZE - 200;
self.addChild(self.undoButton);
self.undoButton.onClick = function () {
self.undoLastMove();
};
self.undoButton.setEnabled(false);
// Reset button
self.resetButton = new Button().init("RESET", 200, 80);
self.resetButton.x = BOARD_SIZE + 50;
self.resetButton.y = BOARD_SIZE - 100;
self.addChild(self.resetButton);
self.resetButton.onClick = function () {
self.resetGame();
};
// Turn indicator
self.turnIndicator = new Text2("White's Turn", {
size: 40,
fill: 0xFFFFFF
});
self.turnIndicator.x = BOARD_SIZE + 150;
self.turnIndicator.y = 50;
self.turnIndicator.anchor.set(0.5, 0);
self.addChild(self.turnIndicator);
// Check indicator
self.checkIndicator = new Text2("", {
size: 40,
fill: 0xFF0000
});
self.checkIndicator.x = BOARD_SIZE + 150;
self.checkIndicator.y = 120;
self.checkIndicator.anchor.set(0.5, 0);
self.addChild(self.checkIndicator);
};
self.placePiece = function (type, color, row, col) {
var piece = new ChessPiece().init(type, color);
self.board[row][col].setPiece(piece);
};
self.squareClicked = function (square) {
if (self.gameOver || self.currentPlayer === 'black' && AI_ENABLED) return;
if (self.selectedSquare) {
// If selected square is clicked again, deselect it
if (self.selectedSquare === square) {
self.clearSelection();
return;
}
// Check if clicked square is a possible move
if (self.isPossibleMove(square)) {
self.movePiece(self.selectedSquare, square);
return;
}
}
// Check if square has a piece of current player's color
if (square.piece && square.piece.color === self.currentPlayer) {
self.selectSquare(square);
}
};
self.selectSquare = function (square) {
self.clearSelection();
self.selectedSquare = square;
square.setSelected(true);
self.possibleMoves = self.calculatePossibleMoves(square);
// Highlight possible moves
for (var i = 0; i < self.possibleMoves.length; i++) {
var move = self.possibleMoves[i];
self.board[move.row][move.col].setHighlight(true);
}
};
self.clearSelection = function () {
if (self.selectedSquare) {
self.selectedSquare.setSelected(false);
self.selectedSquare = null;
}
// Clear highlights
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
self.board[row][col].setHighlight(false);
}
}
self.possibleMoves = [];
};
self.isPossibleMove = function (square) {
for (var i = 0; i < self.possibleMoves.length; i++) {
var move = self.possibleMoves[i];
if (move.row === square.row && move.col === square.col) {
return true;
}
}
return false;
};
self.movePiece = function (fromSquare, toSquare) {
var piece = fromSquare.piece;
var capturedPiece = toSquare.piece;
var moveRecord = {
piece: piece,
from: {
row: fromSquare.row,
col: fromSquare.col
},
to: {
row: toSquare.row,
col: toSquare.col
},
captured: capturedPiece,
firstMove: !piece.hasMoved,
isCheck: false
};
// Clear any previous 'last move' highlights
if (self.lastMoveFrom) {
self.lastMoveFrom.setLastMove(false);
}
if (self.lastMoveTo) {
self.lastMoveTo.setLastMove(false);
}
// Handle castling
var isCastling = piece.type === 'king' && Math.abs(fromSquare.col - toSquare.col) === 2;
if (isCastling) {
var rookCol = toSquare.col === 6 ? 7 : 0;
var newRookCol = toSquare.col === 6 ? 5 : 3;
var rookSquare = self.board[fromSquare.row][rookCol];
var rook = rookSquare.piece;
moveRecord.castling = {
rook: rook,
from: {
row: fromSquare.row,
col: rookCol
},
to: {
row: fromSquare.row,
col: newRookCol
}
};
// Move the rook
rookSquare.setPiece(null);
self.board[fromSquare.row][newRookCol].setPiece(rook);
rook.hasMoved = true;
LK.getSound('castle').play();
} else if (capturedPiece) {
LK.getSound('capture').play();
} else {
LK.getSound('movePiece').play();
}
// Handle pawn promotion
if (piece.type === 'pawn' && (toSquare.row === 0 || toSquare.row === 7)) {
piece.type = 'queen';
toSquare.setPiece(null);
var newQueen = new ChessPiece().init('queen', piece.color);
toSquare.setPiece(newQueen);
moveRecord.promotion = {
from: 'pawn',
to: 'queen'
};
piece = newQueen;
} else {
// Move the piece
fromSquare.setPiece(null);
toSquare.setPiece(piece);
}
// Mark the piece as moved
piece.hasMoved = true;
// Record the last move for highlighting
self.lastMoveFrom = fromSquare;
self.lastMoveTo = toSquare;
fromSquare.setLastMove(true);
toSquare.setLastMove(true);
// Add move to history
self.moveHistory.push(moveRecord);
// Clear selection
self.clearSelection();
// Switch player
self.currentPlayer = self.currentPlayer === 'white' ? 'black' : 'white';
self.turnIndicator.setText(self.currentPlayer.charAt(0).toUpperCase() + self.currentPlayer.slice(1) + "'s Turn");
// Check for check or checkmate
self.checkForCheckAndMate();
// Update undo button state
self.undoButton.setEnabled(self.moveHistory.length > 0);
// If AI is enabled and it's black's turn, make AI move
if (AI_ENABLED && self.currentPlayer === 'black' && !self.gameOver) {
LK.setTimeout(function () {
self.makeAIMove();
}, 500);
}
};
self.checkForCheckAndMate = function () {
// Check if current player is in check
var isInCheck = self.isPlayerInCheck(self.currentPlayer);
self.inCheck[self.currentPlayer] = isInCheck;
if (isInCheck) {
// Check if it's checkmate
var hasLegalMoves = self.playerHasLegalMoves(self.currentPlayer);
if (!hasLegalMoves) {
// Checkmate
self.gameOver = true;
self.checkIndicator.setText("Checkmate! " + (self.currentPlayer === 'white' ? "Black" : "White") + " wins!");
// Update stats
var stats = storage.stats || {
wins: 0,
losses: 0,
draws: 0
};
if (self.currentPlayer === 'white') {
stats.losses++;
} else {
stats.wins++;
}
storage.stats = stats;
} else {
// Just check
self.checkIndicator.setText(self.currentPlayer.charAt(0).toUpperCase() + self.currentPlayer.slice(1) + " is in check!");
LK.getSound('check').play();
}
} else {
// Check for stalemate
var hasLegalMoves = self.playerHasLegalMoves(self.currentPlayer);
if (!hasLegalMoves) {
// Stalemate
self.gameOver = true;
self.checkIndicator.setText("Stalemate! Draw game.");
// Update stats
var stats = storage.stats || {
wins: 0,
losses: 0,
draws: 0
};
stats.draws++;
storage.stats = stats;
} else {
self.checkIndicator.setText("");
}
}
};
self.isPlayerInCheck = function (player) {
// Find player's king
var kingPosition;
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = self.board[row][col].piece;
if (piece && piece.type === 'king' && piece.color === player) {
kingPosition = {
row: row,
col: col
};
break;
}
}
if (kingPosition) break;
}
// Check if any opponent piece can capture the king
var opponent = player === 'white' ? 'black' : 'white';
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var piece = self.board[row][col].piece;
if (piece && piece.color === opponent) {
var moves = self.getRawPieceMoves(self.board[row][col]);
for (var i = 0; i < moves.length; i++) {
if (moves[i].row === kingPosition.row && moves[i].col === kingPosition.col) {
return true;
}
}
}
}
}
return false;
};
self.playerHasLegalMoves = function (player) {
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var square = self.board[row][col];
var piece = square.piece;
if (piece && piece.color === player) {
var moves = self.calculatePossibleMoves(square);
if (moves.length > 0) {
return true;
}
}
}
}
return false;
};
self.undoLastMove = function () {
if (self.moveHistory.length === 0) return;
// Get the last move
var lastMove = self.moveHistory.pop();
// If AI is enabled and we're undoing our move and AI's move
if (AI_ENABLED && self.currentPlayer === 'white' && self.moveHistory.length > 0) {
var aiMove = lastMove;
lastMove = self.moveHistory.pop();
self.undoSingleMove(aiMove);
}
self.undoSingleMove(lastMove);
// Update undo button state
self.undoButton.setEnabled(self.moveHistory.length > 0);
// Clear any check status
self.inCheck = {
white: false,
black: false
};
self.checkIndicator.setText("");
// Ensure game over flag is reset
self.gameOver = false;
};
self.undoSingleMove = function (move) {
// Undo the move
var fromSquare = self.board[move.from.row][move.from.col];
var toSquare = self.board[move.to.row][move.to.col];
var piece = toSquare.piece;
// Handle pawn promotion
if (move.promotion) {
piece = new ChessPiece().init('pawn', piece.color);
}
// Move piece back
toSquare.setPiece(null);
fromSquare.setPiece(piece);
// Restore captured piece
if (move.captured) {
toSquare.setPiece(move.captured);
}
// Undo castling
if (move.castling) {
var rookTo = self.board[move.castling.to.row][move.castling.to.col];
var rookFrom = self.board[move.castling.from.row][move.castling.from.col];
var rook = rookTo.piece;
rookTo.setPiece(null);
rookFrom.setPiece(rook);
if (move.firstMove) {
rook.hasMoved = false;
}
}
// Restore first move status
if (move.firstMove) {
piece.hasMoved = false;
}
// Clear last move highlights
if (self.lastMoveFrom) {
self.lastMoveFrom.setLastMove(false);
}
if (self.lastMoveTo) {
self.lastMoveTo.setLastMove(false);
}
// Find the previous move for highlighting
if (self.moveHistory.length > 0) {
var prevMove = self.moveHistory[self.moveHistory.length - 1];
self.lastMoveFrom = self.board[prevMove.from.row][prevMove.from.col];
self.lastMoveTo = self.board[prevMove.to.row][prevMove.to.col];
self.lastMoveFrom.setLastMove(true);
self.lastMoveTo.setLastMove(true);
} else {
self.lastMoveFrom = null;
self.lastMoveTo = null;
}
// Switch player back
self.currentPlayer = self.currentPlayer === 'white' ? 'black' : 'white';
self.turnIndicator.setText(self.currentPlayer.charAt(0).toUpperCase() + self.currentPlayer.slice(1) + "'s Turn");
};
self.resetGame = function () {
// Clear the entire board
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
if (self.board[row][col].piece) {
self.board[row][col].setPiece(null);
}
// Clear highlights
self.board[row][col].setHighlight(false);
self.board[row][col].setSelected(false);
self.board[row][col].setLastMove(false);
}
}
// Clear game state
self.selectedSquare = null;
self.possibleMoves = [];
self.currentPlayer = 'white';
self.gameOver = false;
self.moveHistory = [];
self.lastMovedPiece = null;
self.lastMoveFrom = null;
self.lastMoveTo = null;
self.inCheck = {
white: false,
black: false
};
// Reset UI
self.turnIndicator.setText("White's Turn");
self.checkIndicator.setText("");
self.undoButton.setEnabled(false);
// Re-populate pieces
self.setupPieces();
// Play move sound
LK.getSound('movePiece').play();
};
self.makeAIMove = function () {
// Simple AI - find all possible moves and choose a random one
// For a smarter AI, you'd implement minimax with alpha-beta pruning
var allMoves = [];
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
var square = self.board[row][col];
if (square.piece && square.piece.color === 'black') {
var moves = self.calculatePossibleMoves(square);
for (var i = 0; i < moves.length; i++) {
allMoves.push({
from: square,
to: self.board[moves[i].row][moves[i].col]
});
}
}
}
}
if (allMoves.length > 0) {
// Prioritize captures and checks
var goodMoves = allMoves.filter(function (move) {
// Is this a capture?
if (move.to.piece) return true;
// Would this move put the opponent in check?
// Simulate the move
var fromPiece = move.from.piece;
var toPiece = move.to.piece;
move.from.piece = null;
move.to.piece = fromPiece;
var wouldCauseCheck = self.isPlayerInCheck('white');
// Undo the simulation
move.from.piece = fromPiece;
move.to.piece = toPiece;
return wouldCauseCheck;
});
// If we have any "good" moves, pick from those
var finalMoves = goodMoves.length > 0 ? goodMoves : allMoves;
// Choose a random move
var randomIndex = Math.floor(Math.random() * finalMoves.length);
var aiMove = finalMoves[randomIndex];
// Make the move
self.movePiece(aiMove.from, aiMove.to);
}
};
self.calculatePossibleMoves = function (square) {
var piece = square.piece;
if (!piece) return [];
var rawMoves = self.getRawPieceMoves(square);
var legalMoves = [];
// Filter out moves that would put or leave the king in check
for (var i = 0; i < rawMoves.length; i++) {
var move = rawMoves[i];
var targetSquare = self.board[move.row][move.col];
// Simulate the move
var capturedPiece = targetSquare.piece;
square.piece = null;
targetSquare.piece = piece;
// Check if the move leaves the king in check
var inCheck = self.isPlayerInCheck(piece.color);
// Undo the simulation
square.piece = piece;
targetSquare.piece = capturedPiece;
if (!inCheck) {
legalMoves.push(move);
}
}
return legalMoves;
};
self.getRawPieceMoves = function (square) {
var piece = square.piece;
if (!piece) return [];
var moves = [];
var row = square.row;
var col = square.col;
switch (piece.type) {
case 'pawn':
self.getPawnMoves(piece, row, col, moves);
break;
case 'rook':
self.getRookMoves(piece, row, col, moves);
break;
case 'knight':
self.getKnightMoves(piece, row, col, moves);
break;
case 'bishop':
self.getBishopMoves(piece, row, col, moves);
break;
case 'queen':
self.getQueenMoves(piece, row, col, moves);
break;
case 'king':
self.getKingMoves(piece, row, col, moves);
break;
}
return moves;
};
self.getPawnMoves = function (piece, row, col, moves) {
var direction = piece.color === 'white' ? -1 : 1;
var startRow = piece.color === 'white' ? 6 : 1;
// Forward move
if (self.isInBounds(row + direction, col) && !self.board[row + direction][col].piece) {
moves.push({
row: row + direction,
col: col
});
// Double move from starting position
if (row === startRow && !self.board[row + 2 * direction][col].piece) {
moves.push({
row: row + 2 * direction,
col: col
});
}
}
// Captures
for (var dcol = -1; dcol <= 1; dcol += 2) {
if (self.isInBounds(row + direction, col + dcol)) {
var targetSquare = self.board[row + direction][col + dcol];
if (targetSquare.piece && targetSquare.piece.color !== piece.color) {
moves.push({
row: row + direction,
col: col + dcol
});
}
}
}
};
self.getRookMoves = function (piece, row, col, moves) {
// Horizontal and vertical moves
var directions = [{
dr: 0,
dc: 1
},
// right
{
dr: 0,
dc: -1
},
// left
{
dr: 1,
dc: 0
},
// down
{
dr: -1,
dc: 0
} // up
];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
for (var dist = 1; dist < 8; dist++) {
var newRow = row + dir.dr * dist;
var newCol = col + dir.dc * dist;
if (!self.isInBounds(newRow, newCol)) break;
var targetSquare = self.board[newRow][newCol];
if (!targetSquare.piece) {
moves.push({
row: newRow,
col: newCol
});
} else {
if (targetSquare.piece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
}
}
};
self.getKnightMoves = function (piece, row, col, moves) {
var knightMoves = [{
dr: -2,
dc: -1
}, {
dr: -2,
dc: 1
}, {
dr: -1,
dc: -2
}, {
dr: -1,
dc: 2
}, {
dr: 1,
dc: -2
}, {
dr: 1,
dc: 2
}, {
dr: 2,
dc: -1
}, {
dr: 2,
dc: 1
}];
for (var i = 0; i < knightMoves.length; i++) {
var move = knightMoves[i];
var newRow = row + move.dr;
var newCol = col + move.dc;
if (self.isInBounds(newRow, newCol)) {
var targetSquare = self.board[newRow][newCol];
if (!targetSquare.piece || targetSquare.piece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
};
self.getBishopMoves = function (piece, row, col, moves) {
// Diagonal moves
var directions = [{
dr: 1,
dc: 1
},
// down-right
{
dr: 1,
dc: -1
},
// down-left
{
dr: -1,
dc: 1
},
// up-right
{
dr: -1,
dc: -1
} // up-left
];
for (var i = 0; i < directions.length; i++) {
var dir = directions[i];
for (var dist = 1; dist < 8; dist++) {
var newRow = row + dir.dr * dist;
var newCol = col + dir.dc * dist;
if (!self.isInBounds(newRow, newCol)) break;
var targetSquare = self.board[newRow][newCol];
if (!targetSquare.piece) {
moves.push({
row: newRow,
col: newCol
});
} else {
if (targetSquare.piece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
break;
}
}
}
};
self.getQueenMoves = function (piece, row, col, moves) {
// Queen = Rook + Bishop
self.getRookMoves(piece, row, col, moves);
self.getBishopMoves(piece, row, col, moves);
};
self.getKingMoves = function (piece, row, col, moves) {
// All 8 directions
for (var dr = -1; dr <= 1; dr++) {
for (var dc = -1; dc <= 1; dc++) {
if (dr === 0 && dc === 0) continue;
var newRow = row + dr;
var newCol = col + dc;
if (self.isInBounds(newRow, newCol)) {
var targetSquare = self.board[newRow][newCol];
if (!targetSquare.piece || targetSquare.piece.color !== piece.color) {
moves.push({
row: newRow,
col: newCol
});
}
}
}
}
// Castling
if (!piece.hasMoved && !self.inCheck[piece.color]) {
// Kingside castling
if (self.canCastle(row, col, 0, 3)) {
moves.push({
row: row,
col: col + 2
});
}
// Queenside castling
if (self.canCastle(row, col, 0, -4)) {
moves.push({
row: row,
col: col - 2
});
}
}
};
self.canCastle = function (row, col, rowOffset, colOffset) {
var direction = colOffset > 0 ? 1 : -1;
var distance = Math.abs(colOffset);
// Check if the rook is there and hasn't moved
var rookCol = direction > 0 ? 7 : 0;
var rookSquare = self.board[row][rookCol];
if (!rookSquare.piece || rookSquare.piece.type !== 'rook' || rookSquare.piece.color !== self.currentPlayer || rookSquare.piece.hasMoved) {
return false;
}
// Check if the squares between king and rook are empty
for (var i = 1; i < distance; i++) {
var checkCol = col + i * direction;
if (self.board[row][checkCol].piece) {
return false;
}
}
// Check if the king passes through or ends up in check
for (var i = 0; i <= 2; i++) {
var checkCol = col + i * direction;
// Simulate the king at this position
var originalSquare = self.board[row][col];
var checkSquare = self.board[row][checkCol];
var kingPiece = originalSquare.piece;
var tempPiece = checkSquare.piece;
originalSquare.piece = null;
checkSquare.piece = kingPiece;
var inCheck = self.isPlayerInCheck(self.currentPlayer);
// Restore board
originalSquare.piece = kingPiece;
checkSquare.piece = tempPiece;
if (inCheck) {
return false;
}
}
return true;
};
self.isInBounds = function (row, col) {
return row >= 0 && row < 8 && col >= 0 && col < 8;
};
return self;
});
var ChessPiece = Container.expand(function () {
var self = Container.call(this);
self.init = function (type, color) {
self.type = type;
self.color = color;
self.hasMoved = false;
var assetId = color + type.charAt(0).toUpperCase() + type.slice(1);
var pieceAsset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Add letter to indicate piece type
var letter = '';
switch (type) {
case 'pawn':
letter = 'P';
break;
case 'rook':
letter = 'R';
break;
case 'knight':
letter = 'N';
break;
case 'bishop':
letter = 'B';
break;
case 'queen':
letter = 'Q';
break;
case 'king':
letter = 'K';
break;
}
var text = new Text2(letter, {
size: 40,
fill: color === 'white' ? "#000000" : "#FFFFFF"
});
text.anchor.set(0.5, 0.5);
self.addChild(text);
return self;
};
return self;
});
var ChessSquare = Container.expand(function () {
var self = Container.call(this);
self.init = function (row, col, color) {
self.row = row;
self.col = col;
self.color = color;
self.piece = null;
var squareAsset = self.attachAsset(color === 'white' ? 'whiteSquare' : 'blackSquare', {
anchorX: 0,
anchorY: 0,
width: SQUARE_SIZE,
height: SQUARE_SIZE
});
self.highlight = self.attachAsset('highlight', {
anchorX: 0,
anchorY: 0,
width: SQUARE_SIZE,
height: SQUARE_SIZE,
alpha: 0
});
self.selected = self.attachAsset('selected', {
anchorX: 0,
anchorY: 0,
width: SQUARE_SIZE,
height: SQUARE_SIZE,
alpha: 0
});
self.lastMove = self.attachAsset('lastMove', {
anchorX: 0,
anchorY: 0,
width: SQUARE_SIZE,
height: SQUARE_SIZE,
alpha: 0
});
return self;
};
self.setHighlight = function (value) {
self.highlight.alpha = value ? 0.5 : 0;
};
self.setSelected = function (value) {
self.selected.alpha = value ? 0.5 : 0;
};
self.setLastMove = function (value) {
self.lastMove.alpha = value ? 0.3 : 0;
};
self.setPiece = function (piece) {
if (self.piece) {
self.removeChild(self.piece);
}
self.piece = piece;
if (piece) {
self.addChild(piece);
piece.x = SQUARE_SIZE / 2;
piece.y = SQUARE_SIZE / 2;
}
};
self.down = function (x, y, obj) {
chessGame.squareClicked(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x333333
});
/****
* Game Code
****/
// Constants
var SQUARE_SIZE = 160;
var BOARD_SIZE = SQUARE_SIZE * 8;
var AI_ENABLED = true;
// Center the board horizontally
var boardOffsetX = (2048 - BOARD_SIZE) / 2;
var boardOffsetY = 100;
// Create chess game
var chessGame = new ChessGame().init();
chessGame.x = boardOffsetX;
chessGame.y = boardOffsetY;
game.addChild(chessGame);
// Add title
var title = new Text2("Smart Chess Master", {
size: 80,
fill: 0xFFFFFF
});
title.anchor.set(0.5, 0);
title.x = 2048 / 2;
title.y = 10;
game.addChild(title);
// Add game instructions
var instructions = new Text2("White goes first. Click a piece to select it,\nthen click a highlighted square to move.", {
size: 30,
fill: 0xCCCCCC,
align: "center"
});
instructions.anchor.set(0.5, 0);
instructions.x = 2048 / 2;
instructions.y = boardOffsetY + BOARD_SIZE + 30;
game.addChild(instructions);
// Play background music
LK.playMusic('bgMusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
}); ===================================================================
--- original.js
+++ change.js
@@ -132,14 +132,22 @@
self.createControls = function () {
// Undo button
self.undoButton = new Button().init("UNDO", 200, 80);
self.undoButton.x = BOARD_SIZE + 50;
- self.undoButton.y = BOARD_SIZE - 100;
+ self.undoButton.y = BOARD_SIZE - 200;
self.addChild(self.undoButton);
self.undoButton.onClick = function () {
self.undoLastMove();
};
self.undoButton.setEnabled(false);
+ // Reset button
+ self.resetButton = new Button().init("RESET", 200, 80);
+ self.resetButton.x = BOARD_SIZE + 50;
+ self.resetButton.y = BOARD_SIZE - 100;
+ self.addChild(self.resetButton);
+ self.resetButton.onClick = function () {
+ self.resetGame();
+ };
// Turn indicator
self.turnIndicator = new Text2("White's Turn", {
size: 40,
fill: 0xFFFFFF
@@ -477,8 +485,43 @@
// Switch player back
self.currentPlayer = self.currentPlayer === 'white' ? 'black' : 'white';
self.turnIndicator.setText(self.currentPlayer.charAt(0).toUpperCase() + self.currentPlayer.slice(1) + "'s Turn");
};
+ self.resetGame = function () {
+ // Clear the entire board
+ for (var row = 0; row < 8; row++) {
+ for (var col = 0; col < 8; col++) {
+ if (self.board[row][col].piece) {
+ self.board[row][col].setPiece(null);
+ }
+ // Clear highlights
+ self.board[row][col].setHighlight(false);
+ self.board[row][col].setSelected(false);
+ self.board[row][col].setLastMove(false);
+ }
+ }
+ // Clear game state
+ self.selectedSquare = null;
+ self.possibleMoves = [];
+ self.currentPlayer = 'white';
+ self.gameOver = false;
+ self.moveHistory = [];
+ self.lastMovedPiece = null;
+ self.lastMoveFrom = null;
+ self.lastMoveTo = null;
+ self.inCheck = {
+ white: false,
+ black: false
+ };
+ // Reset UI
+ self.turnIndicator.setText("White's Turn");
+ self.checkIndicator.setText("");
+ self.undoButton.setEnabled(false);
+ // Re-populate pieces
+ self.setupPieces();
+ // Play move sound
+ LK.getSound('movePiece').play();
+ };
self.makeAIMove = function () {
// Simple AI - find all possible moves and choose a random one
// For a smarter AI, you'd implement minimax with alpha-beta pruning
var allMoves = [];