User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of undefined (reading 'piece')' in or related to this line: 'var originalPiece = board[move.row][move.col].piece;' Line Number: 1869
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'highlight')' in or related to this line: 'board[row][col].highlight();' Line Number: 1472
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'highlight')' in or related to this line: 'board[row][col].highlight();' Line Number: 1472
User prompt
The game AI freezes when it's in check and has no available moves; make it so that it IS checkmate
User prompt
The game AI freezes when it's in check and has no available moves; make it so that it IS checkmate and fix it so that there's a message " YOUR OPPONENT JUST GOT CHECKMATED! LAUGH AT THEM NOW IF YOU WANNA KEEP PLAYING IN THE CARNIVAL!"
User prompt
Remove the 50 move rule
User prompt
Add new special gamemodes: Transformo-fest (all pieces [except kings] turn into random pieces after every move [but not into kings]); Dragon boss (a dragon boss with the same moves as a queen and a knight combines challenges your king! Try to capture the dragon only using 3 knights and 4 bishops on the board to win!); GOAT-ed challenge (all your pieces [except the king] are permanently Goatified! Try to survive 25 turns to win!); Icy day (Each piece on the board [except kings] has a chance to be frozen after a move; but don't fear! Some pawns turned into Yetis that makes them immune to this madness!)
User prompt
Now daily challenges only Special games instead of chess puzzles and quizzes
User prompt
Please fix the bug: 'Uncaught ReferenceError: BOARD_SIZE is not defined' in or related to this line: 'for (var row = 0; row < BOARD_SIZE; row++) {' Line Number: 1364
User prompt
Implement these special games with special rules (Special games: Fog of war [you con only see the spaces that your pieces can move into]; Backwards pawns [pawns can move backwards]; Capture the king [check and checkmate don't exist; now you will capture the king to win!]; SHREDR bishops [bishop can jump over pieces and move one square horizontally in this special challenge]; Small chess [play a game of chess where the board is twice as thin and you lose all your knights and bishops!]) note that these special gamemodes can only be played in the "Daily challenges" mode
User prompt
Implement Chess challenges and chess questions for daily challenges; daily challenge type changes every 24 hours
User prompt
Daily challenges now come every single morning and are eithr chess puzzles where you need to checkmate black or have a winning position, 5 random questions about chess and some chess games with special rules
User prompt
Tournament mode is replaced with the daily challenges where you need to solve some chess puzzles, answer some questions about chess or just trying to win a game against a bot with some special rules (these daily challenges change every single day)
User prompt
When the king has no available moves it's checkmate and you win!
User prompt
Make the buttons for the bots more spaced out, and add an icon for them to identify them
User prompt
Now when you tap a mode, you will choose a chess bot (Chess bots: Martin [a bot that does a lot of bad moves very often]; Lina [a bot that goes for a more offensive strategy]; Carl [a bot that tries to stall the game as much as possible]; Wizard [this bot uses wizardry that lets him make excellent moves often]; King [a chess bot that always makes the best moves, so good in fact that it doesn't have it's queen]
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'type')' in or related to this line: 'var isPawnMove = piece.type === 'pawn';' Line Number: 822
User prompt
Now Goatified pieces have the "goat" asset instead of turning green and traps use the "Trap" asset now
User prompt
Add new abilities for crazy mode: Teleport (moves one of your pieces to danger!); Goatify (turns one of your pieces into a goat that moves exactly like a king, but has none of the rules of the king for 2 turns [king immune to this ability]); Trap (the AI puts a bear trap on a random tile; if a piece touches it, it gets captured!)
User prompt
Now it's also a draw if: there isn't enough material to checkmate, if no pieces are taken/no pawns move for 50 turns, on crazy mode if the king is the only piece on the board and he gets frozen, it's automatically stalemate
User prompt
Now it's also a draw if:
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var BotSelectionScreen = Container.expand(function () {
	var self = Container.call(this);
	// Bot descriptions and icons
	var botData = {
		Martin: {
			description: 'Martin makes many bad moves.',
			icon: 'martinIcon'
		},
		Lina: {
			description: 'Lina has an offensive strategy.',
			icon: 'linaIcon'
		},
		Carl: {
			description: 'Carl tries to stall the game.',
			icon: 'carlIcon'
		},
		Wizard: {
			description: 'Wizard uses magic for great moves.',
			icon: 'wizardIcon'
		},
		King: {
			description: 'King plays optimally but lacks a Queen.',
			icon: 'kingIcon'
		}
	};
	var bots = ['Martin', 'Lina', 'Carl', 'Wizard', 'King'];
	// Assume these assets ('martinIcon', 'linaIcon', etc.) are defined or will be auto-created by the engine.
	// Example sizes used here are 80x80.
	var startY = -350; // Adjusted start Y for more spacing overall
	var spacingY = 180; // Increased vertical spacing between buttons
	// Create title text
	var titleText = new Text2('Select Your Opponent', {
		size: 80,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.y = startY - 100; // Position title above the first button container
	self.addChild(titleText);
	// Store button containers and backgrounds for interaction setup
	var buttonContainers = [];
	var buttonBackgrounds = [];
	// Create bot buttons with icons and descriptions using Containers
	for (var i = 0; i < bots.length; i++) {
		var botName = bots[i];
		var currentBotData = botData[botName];
		// Create a container for each button entry
		var buttonContainer = new Container();
		buttonContainer.x = 0; // Center container horizontally relative to parent (BotSelectionScreen)
		buttonContainer.y = startY + i * spacingY; // Position container vertically
		self.addChild(buttonContainer);
		buttonContainers.push(buttonContainer); // Store the container
		// Get icon asset
		var icon = LK.getAsset(currentBotData.icon, {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 80,
			height: 80
		});
		icon.x = -200; // Position icon significantly to the left within the container
		icon.y = 0; // Center icon vertically within the container
		// Get bot name text asset
		var botButtonText = new Text2(botName.toUpperCase(), {
			size: 60,
			fill: 0xFFFFFF
		});
		botButtonText.anchor.set(0, 0.5); // Anchor text to its left-middle
		botButtonText.x = icon.x + icon.width / 2 + 20; // Position text right of the icon center + padding
		botButtonText.y = -15; // Position text slightly above the vertical center
		// Get description text asset
		var descriptionText = new Text2(currentBotData.description, {
			size: 30,
			fill: 0xCCCCCC
		});
		descriptionText.anchor.set(0, 0.5); // Anchor text to its left-middle
		descriptionText.x = botButtonText.x; // Align description start with bot name start
		descriptionText.y = 15; // Position description below the vertical center
		// Calculate dynamic width/height needed for the background based on content
		var textBlockWidth = Math.max(botButtonText.width, descriptionText.width);
		var contentWidth = icon.width + 20 + textBlockWidth; // Icon width + padding + max text width
		var contentHeight = Math.max(icon.height, botButtonText.height + descriptionText.height + 10); // Max of icon height or combined text height + spacing
		var bgWidth = contentWidth + 80; // Add horizontal padding to content width
		var bgHeight = contentHeight + 40; // Add vertical padding to content height
		// Create background asset
		var bg = LK.getAsset('blackSquare', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: bgWidth,
			height: bgHeight,
			tint: 0x3a3a3a
		});
		bg.alpha = 0.7;
		// Center the background horizontally around the content block
		bg.x = icon.x - icon.width / 2 + contentWidth / 2;
		bg.y = 0; // Center background vertically in the container
		buttonContainer.addChild(bg); // Add background first so text/icon are on top
		buttonBackgrounds.push(bg); // Store background reference for interaction effects
		// Add icon and text elements on top of the background
		buttonContainer.addChild(icon);
		buttonContainer.addChild(botButtonText);
		buttonContainer.addChild(descriptionText);
		// Make the entire container interactive
		buttonContainer.interactive = true;
		buttonContainer.botIndex = i; // Store the bot index on the container for the click handler
	}
	// Create Back button text
	var backButton = new Text2('< BACK', {
		size: 60,
		fill: 0xFFFFFF
	});
	backButton.anchor.set(0.5, 0.5);
	// Position back button below the last bot container, accounting for increased spacing
	backButton.y = startY + bots.length * spacingY + 60;
	self.addChild(backButton);
	// Create Back button background
	var backBg = LK.getAsset('blackSquare', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: backButton.width + 80,
		height: backButton.height + 40,
		tint: 0x3a3a3a
	});
	backBg.alpha = 0.7;
	backBg.x = backButton.x; // Align background center with text center
	backBg.y = backButton.y; // Align background center with text center
	self.addChild(backBg); // Add background first
	self.addChild(backButton); // Add text on top of background
	// --- Interaction Setup ---
	// Bot button interactions (using stored containers and backgrounds)
	for (var i = 0; i < buttonContainers.length; i++) {
		(function (index) {
			var btnContainer = buttonContainers[index];
			var bg = buttonBackgrounds[index]; // Get the corresponding background
			// Attach down event to the container
			btnContainer.down = function (x, y, obj) {
				// Flash the background alpha on click
				tween(bg, {
					alpha: 1
				}, {
					duration: 100,
					onFinish: function onComplete() {
						// Return alpha to normal after flash
						tween(bg, {
							alpha: 0.7
						}, {
							duration: 100
						});
					}
				});
				// Handle button action: select bot and start game
				game.selectedBot = bots[index]; // Use stored index to get bot name
				game.startGame();
			};
		})(i);
	}
	// Back button interaction
	(function () {
		var btn = backButton; // Reference to the Text2 object
		var bg = backBg; // Reference to the background shape
		btn.interactive = true; // Make the Text2 object interactive
		// Attach down event to the text object
		btn.down = function (x, y, obj) {
			// Flash the background alpha on click
			tween(bg, {
				alpha: 1
			}, {
				duration: 100,
				onFinish: function onComplete() {
					// Return alpha to normal after flash
					tween(bg, {
						alpha: 0.7
					}, {
						duration: 100
					});
				}
			});
			// Handle back button action: show the previous screen
			game.showGameModeScreen();
		};
	})();
	// Update function (can be used for animations later if needed)
	self.update = function () {
		// Optional: Add animations like pulsing if needed
	};
	return self;
});
var ChessPiece = Container.expand(function (type, color) {
	var self = Container.call(this);
	self.type = type;
	self.color = color;
	self.hasMoved = false;
	var pieceId = color + type.charAt(0).toUpperCase() + type.slice(1);
	var pieceGraphics = self.attachAsset(pieceId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var label;
	switch (type) {
		case 'pawn':
			label = '';
			break;
		case 'rook':
			label = 'R';
			break;
		case 'knight':
			label = 'N';
			break;
		case 'bishop':
			label = 'B';
			break;
		case 'queen':
			label = 'Q';
			break;
		case 'king':
			label = 'K';
			break;
	}
	if (label) {
		var text = new Text2(label, {
			size: 40,
			fill: color === 'white' ? "#000000" : "#ffffff"
		});
		text.anchor.set(0.5, 0.5);
		self.addChild(text);
	}
	return self;
});
var ChessSquare = Container.expand(function (row, col, color) {
	var self = Container.call(this);
	self.row = row;
	self.col = col;
	self.color = color;
	self.piece = null;
	var squareGraphics = self.attachAsset(color === 'white' ? 'whiteSquare' : 'blackSquare', {
		anchorX: 0,
		anchorY: 0
	});
	self.highlight = function (type) {
		if (type === 'selected') {
			squareGraphics.tint = 0x829769;
		} else if (type === 'validMove') {
			squareGraphics.tint = 0xcdd26a;
		} else {
			// Reset to original color
			squareGraphics.tint = color === 'white' ? 0xf0d9b5 : 0xb58863;
		}
	};
	self.setPiece = function (piece) {
		if (self.piece) {
			self.removeChild(self.piece);
		}
		self.piece = piece;
		if (piece) {
			self.addChild(piece);
			piece.x = squareGraphics.width / 2;
			piece.y = squareGraphics.height / 2;
		}
	};
	self.down = function (x, y, obj) {
		game.selectSquare(self);
	};
	return self;
});
var CrazyAbility = Container.expand(function () {
	var self = Container.call(this);
	// Available abilities
	self.abilities = [{
		name: 'Freeze',
		description: 'Freezes a white piece for 2 turns'
	}, {
		name: 'Instant Promotion',
		description: 'Promotes a black pawn to a powerful piece'
	}, {
		name: 'Stampede',
		description: 'Removes 3 random pieces from the board'
	}, {
		name: 'Summon',
		description: 'Summons a black rook on an empty square'
	}, {
		name: 'Teleport',
		description: 'Teleports one of your pieces to danger!'
	}, {
		name: 'Goatify',
		description: 'Turns a piece into a goat that moves like a king for 2 turns'
	}, {
		name: 'Trap',
		description: 'Places a bear trap that captures pieces that land on it'
	}];
	// Stores pieces that are frozen
	self.frozenPieces = [];
	// Use a random ability
	self.useRandomAbility = function () {
		var randomIndex = Math.floor(Math.random() * self.abilities.length);
		var ability = self.abilities[randomIndex];
		// Show ability notification
		self.showAbilityNotification(ability.name);
		// Execute ability
		switch (ability.name) {
			case 'Freeze':
				self.freezeRandomPiece();
				break;
			case 'Instant Promotion':
				self.instantPromotion();
				break;
			case 'Stampede':
				self.stampede();
				break;
			case 'Summon':
				self.summonRook();
				break;
			case 'Teleport':
				self.teleport();
				break;
			case 'Goatify':
				self.goatifyPiece();
				break;
			case 'Trap':
				self.placeTrap();
				break;
		}
	};
	// Show notification of ability used
	self.showAbilityNotification = function (abilityName) {
		var notification = new Text2('AI USED: ' + abilityName + '!', {
			size: 50,
			fill: 0xFF0000
		});
		notification.anchor.set(0.5, 0.5);
		notification.x = 2048 / 2;
		notification.y = 2732 / 2 - 300;
		game.addChild(notification);
		// Flash effect
		LK.effects.flashObject(notification, 0xFF0000, 500);
		// Remove after delay
		LK.setTimeout(function () {
			game.removeChild(notification);
		}, 2000);
	};
	// Freeze a random white piece for 2 turns
	self.freezeRandomPiece = function () {
		var whitePieces = [];
		// Find all white pieces
		for (var row = 0; row < BOARD_SIZE; row++) {
			for (var col = 0; col < BOARD_SIZE; col++) {
				var square = board[row][col];
				if (square.piece && square.piece.color === 'white') {
					whitePieces.push({
						square: square,
						row: row,
						col: col
					});
				}
			}
		}
		if (whitePieces.length > 0) {
			// Select random white piece
			var randomIndex = Math.floor(Math.random() * whitePieces.length);
			var targetPiece = whitePieces[randomIndex];
			// Add to frozen list with 2 turns duration
			self.frozenPieces.push({
				row: targetPiece.row,
				col: targetPiece.col,
				turnsLeft: 2
			});
			// Visual effect - tint blue
			targetPiece.square.piece.tint = 0x00AAFF;
		}
	};
	// Turn a random black pawn into a queen, bishop or rook
	self.instantPromotion = function () {
		var blackPawns = [];
		// Find all black pawns
		for (var row = 0; row < BOARD_SIZE; row++) {
			for (var col = 0; col < BOARD_SIZE; col++) {
				var square = board[row][col];
				if (square.piece && square.piece.color === 'black' && square.piece.type === 'pawn') {
					blackPawns.push({
						square: square
					});
				}
			}
		}
		if (blackPawns.length > 0) {
			// Select random black pawn
			var randomIndex = Math.floor(Math.random() * blackPawns.length);
			var targetPawn = blackPawns[randomIndex];
			// Choose random promotion type
			var promotionTypes = ['queen', 'bishop', 'rook'];
			var randomType = promotionTypes[Math.floor(Math.random() * promotionTypes.length)];
			// Promote the pawn
			targetPawn.square.setPiece(new ChessPiece(randomType, 'black'));
			LK.getSound('promotion').play();
		}
	};
	// Remove 3 random pieces from the board
	self.stampede = function () {
		var allPieces = [];
		// Find all pieces, excluding all kings
		for (var row = 0; row < BOARD_SIZE; row++) {
			for (var col = 0; col < BOARD_SIZE; col++) {
				var square = board[row][col];
				if (square.piece && square.piece.type !== 'king') {
					allPieces.push({
						square: square
					});
				}
			}
		}
		// Remove up to 3 random pieces
		var removeCount = Math.min(3, allPieces.length);
		for (var i = 0; i < removeCount; i++) {
			if (allPieces.length > 0) {
				var randomIndex = Math.floor(Math.random() * allPieces.length);
				var targetPiece = allPieces[randomIndex];
				// Remove piece
				targetPiece.square.setPiece(null);
				// Remove from array
				allPieces.splice(randomIndex, 1);
			}
		}
		LK.getSound('capture').play();
	};
	// Summon a black rook on a random empty square
	self.summonRook = function () {
		var emptySquares = [];
		// Find all empty squares
		for (var row = 0; row < BOARD_SIZE; row++) {
			for (var col = 0; col < BOARD_SIZE; col++) {
				var square = board[row][col];
				if (!square.piece) {
					emptySquares.push({
						square: square
					});
				}
			}
		}
		if (emptySquares.length > 0) {
			// Select random empty square
			var randomIndex = Math.floor(Math.random() * emptySquares.length);
			var targetSquare = emptySquares[randomIndex];
			// Add new rook
			targetSquare.square.setPiece(new ChessPiece('rook', 'black'));
		}
	};
	// Decrement frozen piece counters
	self.updateFrozenPieces = function () {
		for (var i = self.frozenPieces.length - 1; i >= 0; i--) {
			self.frozenPieces[i].turnsLeft--;
			// If no turns left, unfreeze the piece
			if (self.frozenPieces[i].turnsLeft <= 0) {
				var row = self.frozenPieces[i].row;
				var col = self.frozenPieces[i].col;
				// Only unfreeze if piece still exists at that position
				if (board[row][col].piece && board[row][col].piece.color === 'white') {
					board[row][col].piece.tint = 0xFFFFFF;
				}
				self.frozenPieces.splice(i, 1);
			}
		}
	};
	// Teleport a white piece to a dangerous position
	self.teleport = function () {
		var whitePieces = [];
		var dangerSquares = [];
		// Find all white pieces (except king)
		for (var row = 0; row < BOARD_SIZE; row++) {
			for (var col = 0; col < BOARD_SIZE; col++) {
				var square = board[row][col];
				if (square.piece && square.piece.color === 'white' && square.piece.type !== 'king') {
					whitePieces.push({
						square: square,
						row: row,
						col: col
					});
				}
			}
		}
		// Find all squares under attack by black pieces
		for (var row = 0; row < BOARD_SIZE; row++) {
			for (var col = 0; col < BOARD_SIZE; col++) {
				// Check if this square is attacked by any black piece
				if (isSquareAttacked(row, col, 'black') && !board[row][col].piece) {
					dangerSquares.push({
						row: row,
						col: col
					});
				}
			}
		}
		// If we have white pieces and danger squares
		if (whitePieces.length > 0 && dangerSquares.length > 0) {
			// Select random white piece
			var randomPieceIndex = Math.floor(Math.random() * whitePieces.length);
			var targetPiece = whitePieces[randomPieceIndex];
			// Select random danger square
			var randomSquareIndex = Math.floor(Math.random() * dangerSquares.length);
			var dangerSquare = dangerSquares[randomSquareIndex];
			// Teleport the piece
			var piece = targetPiece.square.piece;
			targetPiece.square.setPiece(null);
			board[dangerSquare.row][dangerSquare.col].setPiece(piece);
			// Visual effect - flash the teleported piece
			LK.effects.flashObject(board[dangerSquare.row][dangerSquare.col].piece, 0xFF00FF, 500);
		}
	};
	// Stores goatified pieces data
	self.goatifiedPieces = [];
	// Turn a white piece into a goat (moves like king)
	self.goatifyPiece = function () {
		var whitePieces = [];
		// Find all white pieces except the king (king is immune)
		for (var row = 0; row < BOARD_SIZE; row++) {
			for (var col = 0; col < BOARD_SIZE; col++) {
				var square = board[row][col];
				if (square.piece && square.piece.color === 'white' && square.piece.type !== 'king') {
					whitePieces.push({
						square: square,
						row: row,
						col: col,
						type: square.piece.type
					});
				}
			}
		}
		if (whitePieces.length > 0) {
			// Select random white piece
			var randomIndex = Math.floor(Math.random() * whitePieces.length);
			var targetPiece = whitePieces[randomIndex];
			// Add to goatified list with 2 turns duration
			self.goatifiedPieces.push({
				row: targetPiece.row,
				col: targetPiece.col,
				originalType: targetPiece.type,
				turnsLeft: 2
			});
			// Visual effect - tint piece to goat color
			targetPiece.square.piece.tint = 0x88BB33;
			// Show a goat indicator
			var goatText = new Text2("π", {
				size: 30,
				fill: 0xFFFFFF
			});
			goatText.anchor.set(0.5, 0.5);
			goatText.x = targetPiece.square.x + SQUARE_SIZE / 2;
			goatText.y = targetPiece.square.y + SQUARE_SIZE / 2 - 30;
			game.addChild(goatText);
			// Remove indicator after a short time
			LK.setTimeout(function () {
				game.removeChild(goatText);
			}, 1500);
		}
	};
	// Array to track trap positions
	self.trapSquares = [];
	// Place a bear trap on a random empty square
	self.placeTrap = function () {
		var emptySquares = [];
		// Find all empty squares
		for (var row = 0; row < BOARD_SIZE; row++) {
			for (var col = 0; col < BOARD_SIZE; col++) {
				var square = board[row][col];
				if (!square.piece) {
					emptySquares.push({
						row: row,
						col: col
					});
				}
			}
		}
		if (emptySquares.length > 0) {
			// Select random empty square
			var randomIndex = Math.floor(Math.random() * emptySquares.length);
			var trapSquare = emptySquares[randomIndex];
			// Add trap to the list
			self.trapSquares.push({
				row: trapSquare.row,
				col: trapSquare.col
			});
			// Visual indication of trap
			var trapIndicator = new Text2("β οΈ", {
				size: 40,
				fill: 0xFF5500
			});
			trapIndicator.anchor.set(0.5, 0.5);
			trapIndicator.x = board[trapSquare.row][trapSquare.col].x + SQUARE_SIZE / 2;
			trapIndicator.y = board[trapSquare.row][trapSquare.col].y + SQUARE_SIZE / 2;
			game.addChild(trapIndicator);
			board[trapSquare.row][trapSquare.col].trapIndicator = trapIndicator;
		}
	};
	// Update goatified pieces counters
	self.updateGoatifiedPieces = function () {
		for (var i = self.goatifiedPieces.length - 1; i >= 0; i--) {
			self.goatifiedPieces[i].turnsLeft--;
			// If no turns left, restore the piece to its original type
			if (self.goatifiedPieces[i].turnsLeft <= 0) {
				var row = self.goatifiedPieces[i].row;
				var col = self.goatifiedPieces[i].col;
				var originalType = self.goatifiedPieces[i].originalType;
				// Only restore if piece still exists at that position and is white
				if (board[row][col].piece && board[row][col].piece.color === 'white') {
					// Reset tint
					board[row][col].piece.tint = 0xFFFFFF;
				}
				self.goatifiedPieces.splice(i, 1);
			}
		}
	};
	// Check if a piece is goatified
	self.isPieceGoatified = function (row, col) {
		for (var i = 0; i < self.goatifiedPieces.length; i++) {
			if (self.goatifiedPieces[i].row === row && self.goatifiedPieces[i].col === col) {
				return true;
			}
		}
		return false;
	};
	// Check if a square has a trap
	self.hasTrap = function (row, col) {
		for (var i = 0; i < self.trapSquares.length; i++) {
			if (self.trapSquares[i].row === row && self.trapSquares[i].col === col) {
				return true;
			}
		}
		return false;
	};
	// Trigger trap on a square and remove it
	self.triggerTrap = function (row, col) {
		for (var i = 0; i < self.trapSquares.length; i++) {
			if (self.trapSquares[i].row === row && self.trapSquares[i].col === col) {
				// Remove the trap indicator
				if (board[row][col].trapIndicator) {
					game.removeChild(board[row][col].trapIndicator);
					board[row][col].trapIndicator = null;
				}
				// Remove the trap from our list
				self.trapSquares.splice(i, 1);
				return true;
			}
		}
		return false;
	};
	// Check if a piece is frozen
	self.isPieceFrozen = function (row, col) {
		for (var i = 0; i < self.frozenPieces.length; i++) {
			if (self.frozenPieces[i].row === row && self.frozenPieces[i].col === col) {
				return true;
			}
		}
		return false;
	};
	return self;
});
var DailyChallengeScreen = Container.expand(function () {
	var self = Container.call(this);
	// Special rules collection - now the only focus of daily challenges
	var specialRules = [{
		name: 'Fog of War',
		description: 'You can only see squares your pieces can move to.',
		id: 'fogOfWar'
	}, {
		name: 'Backwards Pawns',
		description: 'Pawns can move and capture backwards.',
		id: 'backwardsPawns'
	}, {
		name: 'Capture the King',
		description: 'No check/checkmate. Capture the enemy king to win!',
		id: 'captureKing'
	}, {
		name: 'SHREDR Bishops',
		description: 'Bishops can jump over pieces and move one square horizontally.',
		id: 'shredrBishops'
	}, {
		name: 'Small Chess',
		description: 'Play on a 4x8 board without knights or bishops.',
		id: 'smallChess'
	}, {
		name: 'Transformo-fest',
		description: 'Pieces (except kings) randomly transform after moving!',
		id: 'transformoFest'
	}, {
		name: 'Dragon Boss',
		description: 'Capture the Dragon (Queen+Knight moves) using 3 Knights & 4 Bishops.',
		id: 'dragonBoss'
	}, {
		name: 'GOAT-ed Challenge',
		description: 'Your pieces (except king) are goats! Survive 25 turns.',
		id: 'goatedChallenge'
	}, {
		name: 'Icy Day',
		description: 'Pieces may freeze after moving! Some pawns are immune Yetis.',
		id: 'icyDay'
	}];
	// Select a random special rule for the "day"
	var selectedSpecialRule = specialRules[Math.floor(Math.random() * specialRules.length)];
	// --- UI Elements ---
	// Title Text
	var titleText = new Text2('Daily Challenge: Special Game', {
		size: 70,
		fill: 0xFFFFFF,
		wordWrap: true,
		// Enable word wrap
		wordWrapWidth: 1800 // Set max width before wrapping
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.y = -350; // Position higher up
	self.addChild(titleText);
	// Compile description for the selected special rule
	var finalDescription = 'Special Rule: ' + selectedSpecialRule.name + '\n' + selectedSpecialRule.description;
	// Description Text
	var descriptionText = new Text2(finalDescription, {
		size: 45,
		fill: 0xCCCCCC,
		align: 'center',
		// Center align text
		wordWrap: true,
		// Enable word wrap
		wordWrapWidth: 1600 // Set max width before wrapping
	});
	descriptionText.anchor.set(0.5, 0.5);
	descriptionText.y = -150; // Position below title
	self.addChild(descriptionText);
	// Start Challenge Button
	var startButton = new Text2('START CHALLENGE', {
		size: 70,
		fill: 0xFFFFFF
	});
	startButton.anchor.set(0.5, 0.5);
	startButton.y = 100;
	self.addChild(startButton);
	// Back Button
	var backButton = new Text2('< BACK', {
		size: 60,
		fill: 0xFFFFFF
	});
	backButton.anchor.set(0.5, 0.5);
	backButton.y = 300; // Position further down
	self.addChild(backButton);
	// Add backgrounds for buttons
	var buttons = [startButton, backButton];
	var buttonBackgrounds = [];
	for (var i = 0; i < buttons.length; i++) {
		var btn = buttons[i];
		var bg = LK.getAsset('blackSquare', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: btn.width + 80,
			height: btn.height + 40,
			tint: 0x3a3a3a
		});
		bg.alpha = 0.7;
		bg.x = btn.x;
		bg.y = btn.y;
		buttonBackgrounds.push(bg);
		self.addChild(bg);
		self.addChild(btn); // Re-add button to put it on top
	}
	// --- Interactions ---
	// Start Button Interaction
	(function (index) {
		var btn = buttons[index];
		var bg = buttonBackgrounds[index];
		btn.interactive = true;
		btn.down = function (x, y, obj) {
			// Flash effect
			tween(bg, {
				alpha: 1
			}, {
				duration: 100,
				onFinish: function onComplete() {
					tween(bg, {
						alpha: 0.7
					}, {
						duration: 100
					});
				}
			});
			// Set the game mode and the specific rule
			game.gameMode = 'specialGame';
			game.specialRule = selectedSpecialRule.id; // Store the ID of the rule
			// Remove this screen
			if (game.dailyChallengeScreen) {
				game.removeChild(game.dailyChallengeScreen);
				game.dailyChallengeScreen = null;
			}
			game.showBotSelectionScreen(); // Go to bot selection for special game
		};
	})(0); // Index 0 is the start button
	// Back Button Interaction
	(function (index) {
		var btn = buttons[index];
		var bg = buttonBackgrounds[index];
		btn.interactive = true;
		btn.down = function (x, y, obj) {
			// Flash effect
			tween(bg, {
				alpha: 1
			}, {
				duration: 100,
				onFinish: function onComplete() {
					tween(bg, {
						alpha: 0.7
					}, {
						duration: 100
					});
				}
			});
			// Go back to the game mode selection screen
			game.showGameModeScreen();
		};
	})(1); // Index 1 is the back button
	self.update = function () {
		// Optional: Add animations if needed
	};
	return self;
});
var GameModeScreen = Container.expand(function () {
	var self = Container.call(this);
	// Create title text
	var titleText = new Text2('Select Game Mode', {
		size: 80,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.y = -250;
	self.addChild(titleText);
	// Create mode buttons
	var classicButton = new Text2('CLASSIC', {
		size: 80,
		fill: 0xFFFFFF
	});
	classicButton.anchor.set(0.5, 0.5);
	classicButton.y = -150;
	self.addChild(classicButton);
	var crazyButton = new Text2('CRAZY MODE', {
		size: 80,
		fill: 0xFFFFFF
	});
	crazyButton.anchor.set(0.5, 0.5);
	crazyButton.y = 0;
	self.addChild(crazyButton);
	var dailyChallengeButton = new Text2('DAILY CHALLENGE', {
		size: 80,
		fill: 0xFFFFFF
	});
	dailyChallengeButton.anchor.set(0.5, 0.5);
	dailyChallengeButton.y = 150;
	self.addChild(dailyChallengeButton);
	var backButton = new Text2('< BACK', {
		size: 60,
		fill: 0xFFFFFF
	});
	backButton.anchor.set(0.5, 0.5);
	backButton.y = 350;
	self.addChild(backButton);
	// Add highlighting for buttons
	var buttons = [classicButton, crazyButton, dailyChallengeButton, backButton];
	var buttonBackgrounds = [];
	// Create button backgrounds
	for (var i = 0; i < buttons.length; i++) {
		var btn = buttons[i];
		var bg = LK.getAsset('blackSquare', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: btn.width + 80,
			height: btn.height + 40,
			tint: 0x3a3a3a
		});
		bg.alpha = 0.7;
		bg.x = btn.x;
		bg.y = btn.y;
		buttonBackgrounds.push(bg);
		self.addChild(bg);
		self.addChild(btn); // Re-add button to put it on top
	}
	// Add button hover effects
	for (var i = 0; i < buttons.length; i++) {
		(function (index) {
			var btn = buttons[index];
			var bg = buttonBackgrounds[index];
			btn.interactive = true;
			btn.down = function (x, y, obj) {
				// Flash button when clicked
				tween(bg, {
					alpha: 1
				}, {
					duration: 100,
					onFinish: function onComplete() {
						tween(bg, {
							alpha: 0.7
						}, {
							duration: 100
						});
					}
				});
				// Handle button action
				if (index === 0) {
					// Classic mode
					game.gameMode = 'classic';
					game.showBotSelectionScreen(); // Go to bot selection
				} else if (index === 1) {
					// Crazy mode
					game.gameMode = 'crazy';
					game.showBotSelectionScreen(); // Go to bot selection
				} else if (index === 2) {
					// Daily Challenge mode
					game.gameMode = 'dailyChallenge';
					game.showDailyChallengeScreen(); // Show the dedicated screen
				} else if (index === 3) {
					// Back button
					game.showTitleScreen();
				}
			};
		})(i);
	}
	// Pulse animation for the first button
	var pulseScale = 1;
	var increasing = true;
	self.update = function () {
		// Pulse effect for the Classic button
		if (increasing) {
			pulseScale += 0.002;
			if (pulseScale >= 1.05) {
				increasing = false;
			}
		} else {
			pulseScale -= 0.002;
			if (pulseScale <= 0.95) {
				increasing = true;
			}
		}
		classicButton.scale.set(pulseScale);
		buttonBackgrounds[0].scale.set(pulseScale);
	};
	return self;
});
var TitleScreen = Container.expand(function () {
	var self = Container.call(this);
	// Create title text
	var titleText = new Text2('Crazy Chess', {
		size: 120,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	self.addChild(titleText);
	// Create start button
	var startButton = new Text2('TAP TO START', {
		size: 90,
		fill: 0xFFFFFF
	});
	startButton.anchor.set(0.5, 0.5);
	startButton.y = 250;
	self.addChild(startButton);
	// Add pulsing animation to the start button
	var pulseScale = 1;
	var increasing = true;
	self.update = function () {
		// Pulse effect for start button
		if (increasing) {
			pulseScale += 0.003;
			if (pulseScale >= 1.1) {
				increasing = false;
			}
		} else {
			pulseScale -= 0.003;
			if (pulseScale <= 0.9) {
				increasing = true;
			}
		}
		startButton.scale.set(pulseScale);
	};
	// Handle tap anywhere to start
	self.down = function () {
		game.showGameModeScreen();
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	// No title, no description
	// Always backgroundColor is black
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Game constants - Default to 8x8
var BOARD_SIZE = 8; // Default board size
var BOARD_SIZE_X = 8;
var BOARD_SIZE_Y = 8;
var SQUARE_SIZE = 100;
var BOARD_OFFSET_X = (2048 - BOARD_SIZE_X * SQUARE_SIZE) / 2;
var BOARD_OFFSET_Y = (2732 - BOARD_SIZE_Y * SQUARE_SIZE) / 2;
var BOARD_START_COL = 0; // For small chess adjustment
var BOARD_END_COL = 7; // For small chess adjustment
// Game state variables
var board = [];
var selectedSquare = null;
var validMoves = [];
var currentPlayer = 'white';
var gameState = 'title'; // 'title', 'modeSelect', 'botSelect', 'playing', 'check', 'checkmate', 'stalemate', 'dailyChallenge', 'specialGame'
var specialRule = null; // Stores the active special rule for daily challenges
var aiThinking = false;
var titleScreen = null;
var gameModeScreen = null;
var botSelectionScreen = null; // Add variable for the bot selection screen
var dailyChallengeScreen = null; // Add variable for the daily challenge screen
var selectedBot = ''; // Add variable to store the selected bot
// gameMode is now set on the game object, not as a separate variable
var crazyAbilities = new CrazyAbility();
var crazyAbilityChance = 0.4; // 40% chance of AI using ability after a move
// Special Mode Variables
var goatedTurnCounter = 0;
var ICY_DAY_FREEZE_CHANCE = 0.3; // 30% chance to freeze
var ICY_DAY_FREEZE_TURNS = 2; // Freeze duration
var icyDayFrozenPieces = []; // Stores { row, col, turnsLeft } for Icy Day
var yetiPawns = []; // Stores { row, col } of Yeti pawns
// Variables for draw conditions
var movesSinceCaptureOrPawn = 0; // For 50-move rule
var lastMove = null; // To track piece captures and pawn moves
// Initialize the chess board
function initializeBoard() {
	board = [];
	// Adjust board size and offsets for Small Chess
	if (game.gameMode === 'specialGame' && game.specialRule === 'smallChess') {
		BOARD_SIZE_X = 4;
		BOARD_SIZE_Y = 8;
		BOARD_START_COL = 2;
		BOARD_END_COL = 5;
		BOARD_OFFSET_X = (2048 - BOARD_SIZE_X * SQUARE_SIZE) / 2;
		BOARD_OFFSET_Y = (2732 - BOARD_SIZE_Y * SQUARE_SIZE) / 2;
	} else {
		// Reset to default if not small chess
		BOARD_SIZE_X = 8;
		BOARD_SIZE_Y = 8;
		BOARD_START_COL = 0;
		BOARD_END_COL = 7;
		BOARD_OFFSET_X = (2048 - BOARD_SIZE_X * SQUARE_SIZE) / 2;
		BOARD_OFFSET_Y = (2732 - BOARD_SIZE_Y * SQUARE_SIZE) / 2;
	}
	// Create the chess board based on dimensions
	for (var row = 0; row < BOARD_SIZE_Y; row++) {
		board[row] = [];
		for (var col = 0; col < BOARD_SIZE_X; col++) {
			var boardCol = col + BOARD_START_COL; // Map visual column to board array column
			var squareColor = (row + boardCol) % 2 === 0 ? 'white' : 'black';
			var square = new ChessSquare(row, boardCol, squareColor); // Store the actual board column
			square.x = BOARD_OFFSET_X + col * SQUARE_SIZE; // Visual position based on 0 to BOARD_SIZE_X-1
			square.y = BOARD_OFFSET_Y + row * SQUARE_SIZE;
			// Initialize board array slots, only add visible squares to game
			board[row][boardCol] = square; // Use actual board column index
			game.addChild(square);
		}
		// Initialize non-visible columns for internal logic if needed (e.g. full 8x8 array)
		if (game.gameMode !== 'specialGame' || game.specialRule !== 'smallChess') {
			// Standard 8x8 initialization already covered
		} else {
			// For small chess, fill the rest of the 8x8 array rows with null or placeholder if needed by logic
			// This example assumes logic primarily uses BOARD_START_COL and BOARD_END_COL checks
			for (var r = 0; r < BOARD_SIZE_Y; ++r) {
				for (var c = 0; c < 8; ++c) {
					if (c < BOARD_START_COL || c > BOARD_END_COL) {
						if (!board[r]) {
							board[r] = [];
						}
						board[r][c] = null; // Or a placeholder indicating off-board
					}
				}
			}
		}
	}
	// Place the pieces on the board
	placePieces();
}
// Place all chess pieces in their starting positions
function placePieces() {
	if (game.gameMode === 'specialGame' && game.specialRule === 'smallChess') {
		// Small Chess Setup (4x8 board, cols 2-5)
		// Place pawns
		for (var col = BOARD_START_COL; col <= BOARD_END_COL; col++) {
			board[1][col].setPiece(new ChessPiece('pawn', 'black'));
			board[6][col].setPiece(new ChessPiece('pawn', 'white'));
		}
		// Place rooks
		board[0][BOARD_START_COL].setPiece(new ChessPiece('rook', 'black')); // Col 2
		board[0][BOARD_END_COL].setPiece(new ChessPiece('rook', 'black')); // Col 5
		board[7][BOARD_START_COL].setPiece(new ChessPiece('rook', 'white')); // Col 2
		board[7][BOARD_END_COL].setPiece(new ChessPiece('rook', 'white')); // Col 5
		// Place queens
		board[0][BOARD_START_COL + 1].setPiece(new ChessPiece('queen', 'black')); // Col 3
		board[7][BOARD_START_COL + 1].setPiece(new ChessPiece('queen', 'white')); // Col 3
		// Place kings
		board[0][BOARD_START_COL + 2].setPiece(new ChessPiece('king', 'black')); // Col 4
		board[7][BOARD_START_COL + 2].setPiece(new ChessPiece('king', 'white')); // Col 4
		// No knights or bishops
	} else if (game.gameMode === 'specialGame' && game.specialRule === 'dragonBoss') {
		// Dragon Boss Setup
		// White: King, 4 Bishops, 3 Knights
		board[7][4].setPiece(new ChessPiece('king', 'white')); // e1
		board[7][2].setPiece(new ChessPiece('bishop', 'white')); // c1
		board[7][3].setPiece(new ChessPiece('bishop', 'white')); // d1
		board[7][5].setPiece(new ChessPiece('bishop', 'white')); // f1
		board[7][6].setPiece(new ChessPiece('bishop', 'white')); // g1
		board[7][1].setPiece(new ChessPiece('knight', 'white')); // b1
		board[7][7].setPiece(new ChessPiece('knight', 'white')); // h1
		board[6][4].setPiece(new ChessPiece('knight', 'white')); // e2 - One knight forward
		// Black: Dragon (use Queen asset for now, moves handled separately)
		board[0][4].setPiece(new ChessPiece('queen', 'black')); // Dragon on e8
		board[0][4].piece.isDragon = true; // Mark as Dragon
	} else {
		// Standard Setup
		// Place pawns
		for (var col = 0; col < 8; col++) {
			//{8q} // Use 8 explicitly
			board[1][col].setPiece(new ChessPiece('pawn', 'black'));
			board[6][col].setPiece(new ChessPiece('pawn', 'white'));
		}
		// Place rooks
		board[0][0].setPiece(new ChessPiece('rook', 'black'));
		board[0][7].setPiece(new ChessPiece('rook', 'black'));
		board[7][0].setPiece(new ChessPiece('rook', 'white'));
		board[7][7].setPiece(new ChessPiece('rook', 'white'));
		// Place knights
		board[0][1].setPiece(new ChessPiece('knight', 'black'));
		board[0][6].setPiece(new ChessPiece('knight', 'black'));
		board[7][1].setPiece(new ChessPiece('knight', 'white'));
		board[7][6].setPiece(new ChessPiece('knight', 'white'));
		// Place bishops
		board[0][2].setPiece(new ChessPiece('bishop', 'black'));
		board[0][5].setPiece(new ChessPiece('bishop', 'black'));
		board[7][2].setPiece(new ChessPiece('bishop', 'white'));
		board[7][5].setPiece(new ChessPiece('bishop', 'white'));
		// Place queens
		board[0][3].setPiece(new ChessPiece('queen', 'black'));
		board[7][3].setPiece(new ChessPiece('queen', 'white'));
		// Place kings
		board[0][4].setPiece(new ChessPiece('king', 'black'));
		board[7][4].setPiece(new ChessPiece('king', 'white'));
	}
	// GOAT-ed Challenge: Make all white pieces (except king) goatified
	if (game.gameMode === 'specialGame' && game.specialRule === 'goatedChallenge') {
		for (var r = 0; r < 8; r++) {
			for (var c = 0; c < 8; c++) {
				if (board[r][c] && board[r][c].piece && board[r][c].piece.color === 'white' && board[r][c].piece.type !== 'king') {
					board[r][c].piece.isPermanentlyGoatified = true;
					board[r][c].piece.tint = 0x88BB33; // Goat color tint
				}
			}
		}
		goatedTurnCounter = 0; // Reset turn counter
	}
	// Icy Day: Designate some white pawns as Yetis
	if (game.gameMode === 'specialGame' && game.specialRule === 'icyDay') {
		icyDayFrozenPieces = []; // Reset frozen list
		yetiPawns = []; // Reset yeti list
		// Make pawns on b, d, e, g Yetis
		var yetiCols = [1, 3, 4, 6]; // b, d, e, g columns
		for (var i = 0; i < yetiCols.length; i++) {
			var col = yetiCols[i];
			if (board[6][col] && board[6][col].piece && board[6][col].piece.type === 'pawn') {
				board[6][col].piece.isYeti = true;
				board[6][col].piece.tint = 0xADD8E6; // Light blue tint for Yetis
				yetiPawns.push({
					row: 6,
					col: col
				});
			}
		}
	}
	// Special rule for 'King' bot: remove the black queen
	if (game.selectedBot === 'King' && game.gameMode !== 'specialGame') {
		// Don't apply if it's a special game
		if (board[0][3].piece && board[0][3].piece.type === 'queen' && board[0][3].piece.color === 'black') {
			board[0][3].setPiece(null);
		}
	}
}
// Select a square on the chess board
game.selectSquare = function (square) {
	// If AI is thinking, don't allow moves
	if (aiThinking || gameState === 'checkmate' || gameState === 'stalemate') {
		return;
	}
	// If the current player is not the human player, don't allow moves
	if (currentPlayer !== 'white') {
		return;
	}
	// Check if piece is frozen (Only in Crazy Mode)
	if (game.gameMode === 'crazy' && square.piece && square.piece.color === 'white' && crazyAbilities.isPieceFrozen(square.row, square.col)) {
		// Show notification that piece is frozen
		var notification = new Text2('This piece is frozen!', {
			size: 40,
			fill: 0x00AAFF
		});
		notification.anchor.set(0.5, 0.5);
		notification.x = 2048 / 2;
		notification.y = 2732 / 2 - 200;
		game.addChild(notification);
		// Remove notification after delay
		LK.setTimeout(function () {
			game.removeChild(notification);
		}, 1500);
		return;
	}
	// Check if piece is frozen (Icy Day Mode)
	if (game.gameMode === 'specialGame' && game.specialRule === 'icyDay' && square.piece && square.piece.isFrozenIcy) {
		// Show notification that piece is frozen
		var notificationIcy = new Text2('This piece is frozen!', {
			size: 40,
			//{90} // Reuse ID if appropriate
			fill: 0x00AAFF
		}); //{91} // Reuse ID if appropriate
		notificationIcy.anchor.set(0.5, 0.5); //{92} // Reuse ID if appropriate
		notificationIcy.x = 2048 / 2; //{93} // Reuse ID if appropriate
		notificationIcy.y = 2732 / 2 - 200;
		game.addChild(notificationIcy); //{94} // Reuse ID if appropriate
		// Remove notification after delay
		LK.setTimeout(function () {
			//{95} // Reuse ID if appropriate
			game.removeChild(notificationIcy); //{96} // Reuse ID if appropriate
		}, 1500); //{97} // Reuse ID if appropriate
		return; // Don't allow selection
	}
	// Clear previous selections
	clearHighlights();
	// If a square is already selected and the new square is a valid move
	if (selectedSquare && isValidMove(square)) {
		// Move the piece
		var from = selectedSquare;
		var to = square;
		movePiece(from, to);
		// Reset selection state
		selectedSquare = null;
		validMoves = [];
		clearHighlights(); // Clear highlights after move
		// Check if the move ended the game via specific rules (like king capture)
		// gameState might have been updated in movePiece
		if (gameState === 'checkmate' || gameState === 'stalemate') {
			// endGame was already called in movePiece
			return;
		}
		// Switch to the next player
		switchPlayer(); //{9C} // currentPlayer is now the opponent ('black')
		// Now check the state for the player whose turn it just became
		checkGameState(); //{9B} // Checks state for 'black'
		// If the game ended due to checkmate/stalemate after the switch
		if (gameState === 'checkmate' || gameState === 'stalemate') {
			// Game end message already shown by checkGameState -> endGame
			return;
		}
		// If it's AI's turn (now black) and game is still going
		if (currentPlayer === 'black') {
			aiThinking = true;
			LK.setTimeout(makeAIMove, 1000);
		}
	}
	// If clicking on a piece of the current player
	else if (square.piece && square.piece.color === currentPlayer) {
		// Select the square
		selectedSquare = square;
		square.highlight('selected');
		// Calculate valid moves
		validMoves = calculateValidMoves(square);
		// Highlight valid moves
		for (var i = 0; i < validMoves.length; i++) {
			var move = validMoves[i];
			board[move.row][move.col].highlight('validMove');
		}
	}
};
// Check if a move to the target square is valid
function isValidMove(targetSquare) {
	for (var i = 0; i < validMoves.length; i++) {
		var move = validMoves[i];
		if (move.row === targetSquare.row && move.col === targetSquare.col) {
			return true;
		}
	}
	return false;
}
// Move a piece from one square to another
function movePiece(fromSquare, toSquare) {
	var piece = fromSquare.piece;
	// Check for pawn move or capture (for 50-move rule)
	var isPawnMove = piece.type === 'pawn';
	var isCapture = toSquare.piece !== null;
	// Check for trap only in crazy mode
	var trapTriggered = false;
	if (game.gameMode === 'crazy' && crazyAbilities.hasTrap(toSquare.row, toSquare.col)) {
		// Trigger trap effect
		trapTriggered = crazyAbilities.triggerTrap(toSquare.row, toSquare.col);
		// If trap is triggered and the piece is white (not king - king is immune)
		if (trapTriggered && piece.color === 'white' && piece.type !== 'king') {
			// Show trap activation message
			var trapMessage = new Text2("TRAP TRIGGERED!", {
				size: 50,
				fill: 0xFF0000
			});
			trapMessage.anchor.set(0.5, 0.5);
			trapMessage.x = 2048 / 2;
			trapMessage.y = 2732 / 2 - 250;
			game.addChild(trapMessage);
			// Remove message after delay
			LK.setTimeout(function () {
				game.removeChild(trapMessage);
			}, 1500);
			// Piece is captured by the trap
			fromSquare.setPiece(null);
			LK.getSound('capture').play();
			// Update move counter for 50-move rule
			movesSinceCaptureOrPawn = 0;
			// Store last move information
			lastMove = {
				from: {
					row: fromSquare.row,
					col: fromSquare.col
				},
				to: {
					row: toSquare.row,
					col: toSquare.col
				},
				piece: piece.type,
				color: piece.color,
				isCapture: true,
				isTrap: true
			};
			return; // Skip the rest of the move logic
		}
	}
	// Handle capture
	if (isCapture) {
		LK.getSound('capture').play();
	} else {
		LK.getSound('move').play();
	}
	// Move the piece
	var capturedPiece = toSquare.piece; // Store captured piece before overwriting
	fromSquare.setPiece(null);
	toSquare.setPiece(piece);
	// Mark piece as moved (for castling and pawn double move)
	piece.hasMoved = true;
	// Capture the King Rule: Check if a king was captured
	if (game.gameMode === 'specialGame' && game.specialRule === 'captureKing' && capturedPiece && capturedPiece.type === 'king') {
		gameState = 'checkmate'; // Use checkmate state to signify win
		endGame('King Captured! ' + piece.color + ' wins!');
		return; // End the move function early
	}
	// Handle pawn promotion
	if (piece.type === 'pawn' && (toSquare.row === 0 || toSquare.row === 7)) {
		promotePawn(toSquare);
	}
	// Update move counter for 50-move rule
	if (isPawnMove || isCapture) {
		movesSinceCaptureOrPawn = 0;
	} else {
		movesSinceCaptureOrPawn++;
	}
	// Store last move information
	lastMove = {
		from: {
			row: fromSquare.row,
			col: fromSquare.col
		},
		to: {
			row: toSquare.row,
			col: toSquare.col
		},
		piece: piece.type,
		color: piece.color,
		isCapture: isCapture
	};
	// --- Special Mode Post-Move Actions ---
	// Transformo-fest: Transform piece after moving (if not king)
	if (game.gameMode === 'specialGame' && game.specialRule === 'transformoFest' && piece.type !== 'king') {
		var possibleTypes = ['pawn', 'rook', 'knight', 'bishop', 'queen'];
		var randomType = possibleTypes[Math.floor(Math.random() * possibleTypes.length)];
		toSquare.setPiece(new ChessPiece(randomType, piece.color));
		// Add a small visual indicator? Maybe flash?
		LK.effects.flashObject(toSquare.piece, 0xFFFF00, 300);
	}
	// Icy Day: Chance to freeze moved piece (if not king or yeti)
	if (game.gameMode === 'specialGame' && game.specialRule === 'icyDay' && piece.type !== 'king' && !piece.isYeti) {
		if (Math.random() < ICY_DAY_FREEZE_CHANCE) {
			// Check if already frozen
			var alreadyFrozen = false;
			for (var i = 0; i < icyDayFrozenPieces.length; i++) {
				if (icyDayFrozenPieces[i].row === toSquare.row && icyDayFrozenPieces[i].col === toSquare.col) {
					alreadyFrozen = true;
					break;
				}
			}
			// Freeze if not already frozen
			if (!alreadyFrozen) {
				icyDayFrozenPieces.push({
					row: toSquare.row,
					col: toSquare.col,
					turnsLeft: ICY_DAY_FREEZE_TURNS
				});
				if (toSquare.piece) {
					// Check if piece still exists (could have transformed?)
					toSquare.piece.tint = 0x00AAFF; // Blue tint for frozen
					toSquare.piece.isFrozenIcy = true; // Mark as frozen
				}
				// Optional: Add notification text
				var freezeText = new Text2("FROZEN!", {
					size: 30,
					fill: 0x00AAFF
				});
				freezeText.anchor.set(0.5, 1.0);
				freezeText.x = toSquare.x + SQUARE_SIZE / 2;
				freezeText.y = toSquare.y; // Position above the square
				game.addChild(freezeText);
				LK.setTimeout(function () {
					game.removeChild(freezeText);
				}, 1000);
			}
		}
	}
	// Increment GOAT-ed turn counter after white moves
	if (game.gameMode === 'specialGame' && game.specialRule === 'goatedChallenge' && piece.color === 'white') {
		goatedTurnCounter++;
	}
}
// Promote a pawn to a queen
function promotePawn(square) {
	var piece = square.piece;
	square.setPiece(new ChessPiece('queen', piece.color));
	LK.getSound('promotion').play();
}
// Clear highlights from all squares
function clearHighlights() {
	for (var row = 0; row < BOARD_SIZE; row++) {
		for (var col = 0; col < BOARD_SIZE; col++) {
			if (board[row][col]) {
				board[row][col].highlight();
			}
		}
	}
}
// Calculate valid moves for a piece
function calculateValidMoves(square) {
	var piece = square.piece;
	var moves = [];
	if (!piece) {
		return moves;
	}
	var row = square.row;
	var col = square.col;
	// Check for special movement rules first
	// GOAT-ed Challenge: Permanently goatified white pieces move like kings
	if (game.gameMode === 'specialGame' && game.specialRule === 'goatedChallenge' && piece.color === 'white' && piece.isPermanentlyGoatified) {
		calculateKingMoves(row, col, piece, moves);
	}
	// Dragon Boss: Dragon piece moves like Queen + Knight
	else if (game.gameMode === 'specialGame' && game.specialRule === 'dragonBoss' && piece.isDragon) {
		calculateRookMoves(row, col, piece, moves); // Queen part 1
		calculateBishopMoves(row, col, piece, moves); // Queen part 2
		calculateKnightMoves(row, col, piece, moves); // Knight part
	}
	// Check if piece is temporarily goatified (Crazy Mode)
	else if (game.gameMode === 'crazy' && piece.color === 'white' && crazyAbilities.isPieceGoatified(row, col)) {
		// Goatified pieces move like kings
		calculateKingMoves(row, col, piece, moves);
	} else {
		// Regular move calculation based on piece type (apply special rules within these)
		switch (piece.type) {
			case 'pawn':
				calculatePawnMoves(row, col, piece, moves);
				break;
			case 'rook':
				calculateRookMoves(row, col, piece, moves);
				break;
			case 'knight':
				calculateKnightMoves(row, col, piece, moves);
				break;
			case 'bishop':
				calculateBishopMoves(row, col, piece, moves);
				break;
			case 'queen':
				calculateRookMoves(row, col, piece, moves);
				calculateBishopMoves(row, col, piece, moves);
				break;
			case 'king':
				calculateKingMoves(row, col, piece, moves);
				break;
		}
	}
	// Filter out moves that would put the king in check
	return filterCheckMoves(square, moves);
}
// Calculate valid moves for a pawn
function calculatePawnMoves(row, col, piece, moves) {
	var direction = piece.color === 'white' ? -1 : 1;
	// Move forward one square
	if (isValidSquare(row + direction, col) && !board[row + direction][col].piece) {
		moves.push({
			row: row + direction,
			col: col
		});
		// Move forward two squares from starting position
		if (!piece.hasMoved && isValidSquare(row + 2 * direction, col) && !board[row + 2 * direction][col].piece) {
			moves.push({
				row: row + 2 * direction,
				col: col
			});
		}
	}
	// Captures
	var captureDirections = [{
		row: direction,
		col: -1
	}, {
		row: direction,
		col: 1
	}];
	for (var i = 0; i < captureDirections.length; i++) {
		var dir = captureDirections[i];
		var newRow = row + dir.row;
		var newCol = col + dir.col;
		if (isValidSquare(newRow, newCol) && board[newRow][newCol].piece && board[newRow][newCol].piece.color !== piece.color) {
			moves.push({
				row: newRow,
				col: newCol
			});
		}
	}
	// Backwards Pawns Rule
	if (game.gameMode === 'specialGame' && game.specialRule === 'backwardsPawns') {
		var backwardDirection = -direction; // Opposite direction
		// Move backward one square
		if (isValidSquare(row + backwardDirection, col) && !board[row + backwardDirection][col].piece) {
			moves.push({
				row: row + backwardDirection,
				col: col
			});
			// No double move backwards
		}
		// Backward captures
		var backwardCaptureDirections = [{
			row: backwardDirection,
			col: -1
		}, {
			row: backwardDirection,
			col: 1
		}];
		for (var i = 0; i < backwardCaptureDirections.length; i++) {
			var bDir = backwardCaptureDirections[i];
			var bNewRow = row + bDir.row;
			var bNewCol = col + bDir.col;
			if (isValidSquare(bNewRow, bNewCol) && board[bNewRow][bNewCol].piece && board[bNewRow][bNewCol].piece.color !== piece.color) {
				moves.push({
					row: bNewRow,
					col: bNewCol
				});
			}
		}
	}
}
// Calculate valid moves for a rook
function calculateRookMoves(row, col, piece, moves) {
	var directions = [{
		row: -1,
		col: 0
	},
	// up
	{
		row: 1,
		col: 0
	},
	// down
	{
		row: 0,
		col: -1
	},
	// left
	{
		row: 0,
		col: 1
	} // right
	];
	calculateSlidingMoves(row, col, piece, moves, directions);
}
// Calculate valid moves for a bishop
function calculateBishopMoves(row, col, piece, moves) {
	var directions = [{
		row: -1,
		col: -1
	},
	// up-left
	{
		row: -1,
		col: 1
	},
	// up-right
	{
		row: 1,
		col: -1
	},
	// down-left
	{
		row: 1,
		col: 1
	} // down-right
	];
	var diagonalMoves = []; // Store initial diagonal moves before filtering/adding horizontal
	calculateSlidingMoves(row, col, piece, moves, directions);
	// SHREDR Bishops: Add horizontal move option
	if (game.gameMode === 'specialGame' && game.specialRule === 'shredrBishops') {
		var shredrMoves = [];
		for (var i = 0; i < moves.length; i++) {
			var move = moves[i];
			shredrMoves.push(move); // Keep the original diagonal move
			// Add horizontal moves from the landing square
			var landingRow = move.row;
			var landingCol = move.col;
			// Check horizontal left
			if (isValidSquare(landingRow, landingCol - 1)) {
				var leftSquare = board[landingRow][landingCol - 1];
				if (!leftSquare || !leftSquare.piece || leftSquare.piece.color !== piece.color) {
					shredrMoves.push({
						row: landingRow,
						col: landingCol - 1
					});
				}
			}
			// Check horizontal right
			if (isValidSquare(landingRow, landingCol + 1)) {
				var rightSquare = board[landingRow][landingCol + 1];
				if (!rightSquare || !rightSquare.piece || rightSquare.piece.color !== piece.color) {
					shredrMoves.push({
						row: landingRow,
						col: landingCol + 1
					});
				}
			}
		}
		// Replace original moves with shredr moves (includes original + horizontal)
		// Need to clear original moves and add shredrMoves back.
		// The 'moves' array is passed by reference, modify it directly.
		moves.length = 0; // Clear the array
		for (var k = 0; k < shredrMoves.length; k++) {
			// Avoid duplicates (simple check, might need improvement for complex scenarios)
			var exists = false;
			for (var j = 0; j < moves.length; j++) {
				if (moves[j].row === shredrMoves[k].row && moves[j].col === shredrMoves[k].col) {
					exists = true;
					break;
				}
			}
			if (!exists) {
				moves.push(shredrMoves[k]);
			}
		}
	}
}
// Calculate valid moves for sliding pieces (rook, bishop, queen)
function calculateSlidingMoves(row, col, piece, moves, directions) {
	for (var i = 0; i < directions.length; i++) {
		var dir = directions[i];
		var newRow = row + dir.row;
		var newCol = col + dir.col;
		while (isValidSquare(newRow, newCol)) {
			var targetSquare = board[newRow][newCol];
			if (!targetSquare.piece) {
				// Empty square, can move here
				moves.push({
					row: newRow,
					col: newCol
				});
			} else {
				// Found a piece
				if (targetSquare.piece.color !== piece.color) {
					// Can capture opponent's piece
					moves.push({
						row: newRow,
						col: newCol
					});
				}
				// SHREDR Bishops can jump, so don't break here for them
				if (!(game.gameMode === 'specialGame' && game.specialRule === 'shredrBishops' && piece.type === 'bishop')) {
					// Can't move past a piece (unless SHREDR bishop)
					break;
				}
			}
			newRow += dir.row;
			newCol += dir.col;
		}
	}
}
// Calculate valid moves for a knight
function calculateKnightMoves(row, col, piece, moves) {
	var knightDirections = [{
		row: -2,
		col: -1
	}, {
		row: -2,
		col: 1
	}, {
		row: -1,
		col: -2
	}, {
		row: -1,
		col: 2
	}, {
		row: 1,
		col: -2
	}, {
		row: 1,
		col: 2
	}, {
		row: 2,
		col: -1
	}, {
		row: 2,
		col: 1
	}];
	for (var i = 0; i < knightDirections.length; i++) {
		var dir = knightDirections[i];
		var newRow = row + dir.row;
		var newCol = col + dir.col;
		if (isValidSquare(newRow, newCol)) {
			var targetSquare = board[newRow][newCol];
			if (!targetSquare.piece || targetSquare.piece.color !== piece.color) {
				moves.push({
					row: newRow,
					col: newCol
				});
			}
		}
	}
}
// Calculate valid moves for a king
function calculateKingMoves(row, col, piece, moves) {
	var kingDirections = [{
		row: -1,
		col: -1
	}, {
		row: -1,
		col: 0
	}, {
		row: -1,
		col: 1
	}, {
		row: 0,
		col: -1
	}, {
		row: 0,
		col: 1
	}, {
		row: 1,
		col: -1
	}, {
		row: 1,
		col: 0
	}, {
		row: 1,
		col: 1
	}];
	for (var i = 0; i < kingDirections.length; i++) {
		var dir = kingDirections[i];
		var newRow = row + dir.row;
		var newCol = col + dir.col;
		if (isValidSquare(newRow, newCol)) {
			var targetSquare = board[newRow][newCol];
			if (!targetSquare.piece || targetSquare.piece.color !== piece.color) {
				moves.push({
					row: newRow,
					col: newCol
				});
			}
		}
	}
	// Castling
	if (!piece.hasMoved) {
		// Kingside castling
		if (canCastle(row, col, 0, 3)) {
			moves.push({
				row: row,
				col: col + 2
			});
		}
		// Queenside castling
		if (canCastle(row, col, 0, -4)) {
			moves.push({
				row: row,
				col: col - 2
			});
		}
	}
}
// Check if castling is possible
function canCastle(row, col, rowOffset, colOffset) {
	var rookCol = colOffset > 0 ? 7 : 0;
	var rookRow = row;
	// Check if there's a rook in the corner
	var rookSquare = board[rookRow][rookCol];
	if (!rookSquare.piece || rookSquare.piece.type !== 'rook' || rookSquare.piece.hasMoved) {
		return false;
	}
	// Check if there are pieces between the king and the rook
	var startCol = Math.min(col, rookCol) + 1;
	var endCol = Math.max(col, rookCol) - 1;
	for (var c = startCol; c <= endCol; c++) {
		if (board[row][c].piece) {
			return false;
		}
	}
	// Check if the king would move through or into check
	var direction = colOffset > 0 ? 1 : -1;
	if (isSquareAttacked(row, col, otherPlayer(currentPlayer)) || isSquareAttacked(row, col + direction, otherPlayer(currentPlayer)) || isSquareAttacked(row, col + 2 * direction, otherPlayer(currentPlayer))) {
		return false;
	}
	return true;
}
// Filter out moves that would put the king in check
function filterCheckMoves(fromSquare, moves) {
	var validMoves = [];
	var piece = fromSquare.piece;
	// Capture the King Rule: King doesn't care about checks, skip filtering
	if (game.gameMode === 'specialGame' && game.specialRule === 'captureKing') {
		// Return all moves unfiltered for check
		for (var i = 0; i < moves.length; i++) {
			validMoves.push(moves[i]);
		}
		return validMoves;
	}
	// Standard check filtering
	for (var i = 0; i < moves.length; i++) {
		var move = moves[i];
		// Make sure the move exists and has valid row/col properties
		if (!move || !board[move.row] || !board[move.row][move.col]) {
			continue;
		}
		// Simulate the move
		var originalPiece = board[move.row][move.col].piece;
		board[move.row][move.col].piece = piece;
		board[fromSquare.row][fromSquare.col].piece = null;
		// Check if the king is in check after the move
		var inCheck = isKingInCheck(piece.color);
		// Undo the move
		board[fromSquare.row][fromSquare.col].piece = piece;
		board[move.row][move.col].piece = originalPiece;
		if (!inCheck) {
			validMoves.push(move);
		}
	}
	return validMoves;
}
// Check if a square is valid (within the board)
function isValidSquare(row, col) {
	// Use dynamic board sizes and column limits
	return row >= 0 && row < BOARD_SIZE_Y && col >= BOARD_START_COL && col <= BOARD_END_COL;
}
// Check if the king is in check
function isKingInCheck(color) {
	// Find the king
	var kingSquare = findKing(color);
	if (!kingSquare) {
		return false;
	}
	// Check if the king is attacked by any opponent's piece
	return isSquareAttacked(kingSquare.row, kingSquare.col, otherPlayer(color));
}
// Check if a square is attacked by any piece of the given color
function isSquareAttacked(row, col, attackerColor) {
	for (var r = 0; r < BOARD_SIZE; r++) {
		for (var c = 0; c < BOARD_SIZE; c++) {
			var square = board[r][c];
			if (square.piece && square.piece.color === attackerColor) {
				var moves = [];
				switch (square.piece.type) {
					case 'pawn':
						// Pawns attack diagonally
						var direction = square.piece.color === 'white' ? -1 : 1;
						var attackDirections = [{
							row: direction,
							col: -1
						}, {
							row: direction,
							col: 1
						}];
						for (var i = 0; i < attackDirections.length; i++) {
							var dir = attackDirections[i];
							var attackRow = r + dir.row;
							var attackCol = c + dir.col;
							if (attackRow === row && attackCol === col) {
								return true;
							}
						}
						break;
					case 'rook':
						calculateRookMoves(r, c, square.piece, moves);
						break;
					case 'knight':
						calculateKnightMoves(r, c, square.piece, moves);
						break;
					case 'bishop':
						calculateBishopMoves(r, c, square.piece, moves);
						break;
					case 'queen':
						calculateRookMoves(r, c, square.piece, moves);
						calculateBishopMoves(r, c, square.piece, moves);
						break;
					case 'king':
						var kingDirections = [{
							row: -1,
							col: -1
						}, {
							row: -1,
							col: 0
						}, {
							row: -1,
							col: 1
						}, {
							row: 0,
							col: -1
						}, {
							row: 0,
							col: 1
						}, {
							row: 1,
							col: -1
						}, {
							row: 1,
							col: 0
						}, {
							row: 1,
							col: 1
						}];
						for (var i = 0; i < kingDirections.length; i++) {
							var dir = kingDirections[i];
							var attackRow = r + dir.row;
							var attackCol = c + dir.col;
							if (attackRow === row && attackCol === col) {
								return true;
							}
						}
						break;
				}
				// Check if the square is in the list of moves
				for (var i = 0; i < moves.length; i++) {
					var move = moves[i];
					if (move.row === row && move.col === col) {
						return true;
					}
				}
			}
		}
	}
	return false;
}
// Find the king of the given color
function findKing(color) {
	for (var row = 0; row < BOARD_SIZE; row++) {
		for (var col = 0; col < BOARD_SIZE; col++) {
			var square = board[row][col];
			if (square.piece && square.piece.type === 'king' && square.piece.color === color) {
				return {
					row: row,
					col: col
				};
			}
		}
	}
	return null;
}
// Get the other player's color
function otherPlayer(color) {
	return color === 'white' ? 'black' : 'white';
}
// Switch the current player
function switchPlayer() {
	currentPlayer = otherPlayer(currentPlayer);
	// Icy Day: Update frozen piece counters at the start of the next player's turn
	if (game.gameMode === 'specialGame' && game.specialRule === 'icyDay') {
		updateIcyDayFrozenPieces();
	}
}
// Helper function to update Icy Day frozen pieces
function updateIcyDayFrozenPieces() {
	for (var i = icyDayFrozenPieces.length - 1; i >= 0; i--) {
		var frozen = icyDayFrozenPieces[i];
		frozen.turnsLeft--;
		if (frozen.turnsLeft <= 0) {
			var square = board[frozen.row][frozen.col];
			// Unfreeze if the piece is still there and marked as frozen
			if (square && square.piece && square.piece.isFrozenIcy) {
				// Reset tint based on whether it's a Yeti or regular piece
				if (square.piece.isYeti) {
					square.piece.tint = 0xADD8E6; // Yeti tint
				} else {
					square.piece.tint = 0xFFFFFF; // Default tint
				}
				square.piece.isFrozenIcy = false; // Unmark
			}
			icyDayFrozenPieces.splice(i, 1); // Remove from list
		}
	}
}
// Check the game state (check, checkmate, stalemate)
function checkGameState() {
	// Capture the King Rule: Check/Checkmate logic is different
	if (game.gameMode === 'specialGame' && game.specialRule === 'captureKing') {
		// Stalemate can still occur if no legal moves (excluding king capture scenario handled in movePiece)
		var allMovesCtK = getAllPossibleMoves(currentPlayer);
		if (allMovesCtK.length === 0) {
			// Stalemate if no moves and king not captured
			gameState = 'stalemate'; //{eT} // Reuse stalemate code line ID if appropriate
			endGame('Draw by stalemate!');
			return;
		}
		// Check for 50-move rule - REMOVED
		/* 
		if (movesSinceCaptureOrPawn >= 50) { //{gH} // Keep line ID comment for history
			gameState = 'stalemate'; 
			endGame('Draw by 50-move rule!'); 
			return; 
		} 
		*/ 
		// Check for insufficient material still applies
		if (hasInsufficientMaterial()) {
			gameState = 'stalemate';
			endGame('Draw by insufficient material!');
			return;
		}
		// No check state in this mode
		gameState = 'playing'; //{eV} // Reuse playing state code line ID
		return; // Skip standard check/checkmate logic
	}
	// GOAT-ed Challenge: Check for survival win
	if (game.gameMode === 'specialGame' && game.specialRule === 'goatedChallenge') {
		if (goatedTurnCounter >= 25) {
			gameState = 'checkmate'; // Use checkmate state to signify player win
			endGame('Survived 25 turns! You win!');
			return;
		}
		// Check if AI king is captured (AI loses) - should not happen if AI plays normally
		var blackKing = findKing('black');
		if (!blackKing) {
			gameState = 'checkmate';
			endGame('AI King lost! You win!');
			return;
		}
		// Check if player king is captured (Player loses)
		var whiteKing = findKing('white');
		if (!whiteKing) {
			gameState = 'checkmate'; // Player lost
			endGame('Your King was captured! AI wins!');
			return;
		}
	}
	// Dragon Boss: Check if Dragon is captured (Player wins)
	if (game.gameMode === 'specialGame' && game.specialRule === 'dragonBoss') {
		var dragonFound = false;
		for (var r = 0; r < BOARD_SIZE_Y; r++) {
			for (var c = BOARD_START_COL; c <= BOARD_END_COL; c++) {
				if (board[r][c] && board[r][c].piece && board[r][c].piece.isDragon) {
					dragonFound = true;
					break;
				}
			}
			if (dragonFound) {
				break;
			}
		}
		if (!dragonFound) {
			gameState = 'checkmate'; // Player wins
			endGame('Dragon Captured! You win!');
			return;
		}
		// Check if player king is captured (Player loses)
		var whiteKingDragon = findKing('white');
		if (!whiteKingDragon) {
			gameState = 'checkmate'; // Player lost
			endGame('Your King was captured! Dragon wins!');
			return;
		}
	}
	// --- Standard Check/Checkmate/Stalemate Logic ---
	// Check if the current player's king is in check
	var inCheck = isKingInCheck(currentPlayer);
	// Get all possible moves for the current player
	var allMoves = getAllPossibleMoves(currentPlayer);
	// Check for 50-move rule - REMOVED
	/* 
	if (movesSinceCaptureOrPawn >= 50) { //{hh} // Keep line ID comment for history
		gameState = 'stalemate'; 
		endGame('Draw by 50-move rule!'); 
		return; 
	} 
	*/ 
	// Check for insufficient material
	if (hasInsufficientMaterial()) {
		gameState = 'stalemate';
		endGame('Draw by insufficient material!');
		return;
	}
	// Check crazy mode king only frozen situation
	if (game.gameMode === 'crazy' && isKingOnlyFrozen()) {
		gameState = 'stalemate';
		endGame('Draw! King is frozen and alone.');
		return;
	}
	if (inCheck) {
		if (allMoves.length === 0) {
			// Checkmate
			gameState = 'checkmate';
			endGame('Checkmate! ' + otherPlayer(currentPlayer) + ' wins!');
		} else {
			// Check
			gameState = 'check';
			LK.getSound('check').play();
		}
	} else if (allMoves.length === 0) {
		// Stalemate
		gameState = 'stalemate';
		endGame('Draw by stalemate!');
	} else {
		gameState = 'playing';
	}
}
// Get all possible moves for a player
function getAllPossibleMoves(color) {
	var allMoves = [];
	for (var row = 0; row < BOARD_SIZE; row++) {
		for (var col = 0; col < BOARD_SIZE; col++) {
			var square = board[row][col];
			if (square.piece && square.piece.color === color) {
				var moves = calculateValidMoves(square);
				for (var i = 0; i < moves.length; i++) {
					allMoves.push({
						fromRow: row,
						fromCol: col,
						toRow: moves[i].row,
						toCol: moves[i].col
					});
				}
			}
		}
	}
	return allMoves;
}
// Check for insufficient material (K vs K, K vs KB, K vs KN)
function hasInsufficientMaterial() {
	var pieces = {
		white: {
			count: 0,
			bishop: 0,
			knight: 0
		},
		black: {
			count: 0,
			bishop: 0,
			knight: 0
		}
	};
	// Count all pieces on the board
	for (var row = 0; row < BOARD_SIZE; row++) {
		for (var col = 0; col < BOARD_SIZE; col++) {
			var square = board[row][col];
			if (square.piece) {
				var piece = square.piece;
				pieces[piece.color].count++;
				if (piece.type === 'bishop') {
					pieces[piece.color].bishop++;
				} else if (piece.type === 'knight') {
					pieces[piece.color].knight++;
				} else if (piece.type !== 'king') {
					// If there's any other piece (pawn, rook, queen), material is sufficient
					if (piece.type === 'pawn' || piece.type === 'rook' || piece.type === 'queen') {
						return false;
					}
				}
			}
		}
	}
	// K vs K
	if (pieces.white.count === 1 && pieces.black.count === 1) {
		return true;
	}
	// K vs KB or K vs KN
	if (pieces.white.count === 1 && pieces.black.count === 2 && (pieces.black.bishop === 1 || pieces.black.knight === 1) || pieces.black.count === 1 && pieces.white.count === 2 && (pieces.white.bishop === 1 || pieces.white.knight === 1)) {
		return true;
	}
	return false;
}
// Check for king-only frozen situation in crazy mode
function isKingOnlyFrozen() {
	if (game.gameMode !== 'crazy') {
		return false;
	}
	var whiteCount = 0;
	var whiteKingRow = -1;
	var whiteKingCol = -1;
	var blackCount = 0;
	// Count pieces and find white king
	for (var row = 0; row < BOARD_SIZE; row++) {
		for (var col = 0; col < BOARD_SIZE; col++) {
			var square = board[row][col];
			if (square.piece) {
				if (square.piece.color === 'white') {
					whiteCount++;
					if (square.piece.type === 'king') {
						whiteKingRow = row;
						whiteKingCol = col;
					}
				} else {
					blackCount++;
				}
			}
		}
	}
	// If white only has the king and it's frozen
	return whiteCount === 1 && whiteKingRow !== -1 && crazyAbilities.isPieceFrozen(whiteKingRow, whiteKingCol);
}
// End the game
function endGame(message) {
	var gameOverText = new Text2(message, {
		size: 60,
		fill: 0xFFFFFF
	});
	gameOverText.anchor.set(0.5, 0.5);
	gameOverText.x = 2048 / 2;
	gameOverText.y = 200;
	game.addChild(gameOverText);
	// Update score based on winner
	if (gameState === 'checkmate') {
		if (currentPlayer === 'black') {
			// White wins
			LK.setScore(100);
		} else {
			// Black wins (AI wins)
			LK.setScore(0);
		}
	} else {
		// Draw
		LK.setScore(50);
	}
	// Show game over after a short delay
	LK.setTimeout(function () {
		LK.showGameOver();
	}, 3000);
}
// Make an AI move
function makeAIMove() {
	if (gameState === 'checkmate' || gameState === 'stalemate') {
		aiThinking = false;
		return;
	}
	// Get all possible moves for the AI
	var possibleMoves = getAllPossibleMoves('black');
	if (possibleMoves.length === 0) {
		aiThinking = false;
		return;
	}
	// Simple AI: pick a random move
	var randomMove = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];
	// Make the move
	var fromSquare = board[randomMove.fromRow][randomMove.fromCol];
	var toSquare = board[randomMove.toRow][randomMove.toCol];
	// Highlight the selected square
	fromSquare.highlight('selected');
	// Wait a bit before making the move
	LK.setTimeout(function () {
		// Move the piece
		movePiece(fromSquare, toSquare);
		// Clear highlights
		clearHighlights();
		// Check if the move ended the game (e.g., king capture)
		// gameState might have been updated in movePiece
		if (gameState === 'checkmate' || gameState === 'stalemate') {
			aiThinking = false;
			return; // Exit if movePiece ended the game
		}
		// Use crazy ability ONLY in crazy mode
		if (game.gameMode === 'crazy' && Math.random() < crazyAbilityChance) {
			// Use ability after a short delay
			LK.setTimeout(function () {
				crazyAbilities.useRandomAbility();
				// Note: Ability might change game state, but we check again after switch anyway
			}, 500);
		}
		// Switch back to player
		switchPlayer(); //{iS} // currentPlayer is now 'white'
		// Check for check/checkmate/stalemate for the player whose turn it now is
		checkGameState(); //{iR} // Checks state for 'white'
		// If game ended after check
		if (gameState === 'checkmate' || gameState === 'stalemate') {
			aiThinking = false;
			return;
		}
		// Update crazy mode frozen and goatified pieces ONLY in crazy mode
		if (game.gameMode === 'crazy') {
			crazyAbilities.updateFrozenPieces();
			crazyAbilities.updateGoatifiedPieces();
		}
		// AI turn is over
		aiThinking = false;
	}, 500);
}
// Create score display
var scoreTxt = new Text2('Crazy Chess', {
	size: 60,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create turn display
var turnText = new Text2('Your Turn', {
	size: 40,
	fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
turnText.y = 70;
LK.gui.top.addChild(turnText);
// Game update function
game.update = function () {
	// If in title screen, update title screen
	if (gameState === 'title' && titleScreen) {
		titleScreen.update();
		return;
	}
	// If in game mode selection screen, update that screen
	if (gameState === 'modeSelect' && gameModeScreen) {
		gameModeScreen.update();
		return;
	}
	// If in bot selection screen, update that screen
	if (gameState === 'botSelect' && botSelectionScreen) {
		botSelectionScreen.update();
		return;
	}
	// If in daily challenge screen, update that screen
	if (gameState === 'dailyChallenge' && dailyChallengeScreen) {
		dailyChallengeScreen.update();
		return; // Stop further updates if in this screen
	}
	// Fog of War visual update (placeholder)
	if (game.gameMode === 'specialGame' && game.specialRule === 'fogOfWar') {
		// updateFogOfWar(); // TODO: Implement visual fog logic
	}
	// Update UI Text for Special Modes
	if (game.gameMode === 'specialGame') {
		if (game.specialRule === 'goatedChallenge') {
			scoreTxt.setText('GOAT-ed Challenge');
			turnText.setText('Turn: ' + goatedTurnCounter + '/25');
			if (gameState === 'checkmate' && goatedTurnCounter >= 25) {
				turnText.setText('You Win!');
			} else if (gameState === 'checkmate') {
				turnText.setText('AI Wins!'); // Player lost before 25 turns
			} else if (aiThinking) {
				turnText.setText('AI Thinking...');
			}
			// Don't overwrite win/loss text immediately
			return; // Skip default turn text logic for this mode if not thinking
		} else if (game.specialRule === 'dragonBoss') {
			scoreTxt.setText('Dragon Boss');
			if (gameState === 'checkmate') {
				var whiteKingDragon = findKing('white');
				turnText.setText(whiteKingDragon ? 'You Win!' : 'Dragon Wins!');
			} else if (aiThinking) {
				turnText.setText('Dragon Thinking...');
			} else {
				turnText.setText('Your Turn');
			}
			return; // Skip default turn text logic
		} else if (game.specialRule === 'icyDay') {
			scoreTxt.setText('Icy Day');
			// Use default turn text logic below
		} else if (game.specialRule === 'transformoFest') {
			scoreTxt.setText('Transformo-fest');
			// Use default turn text logic below
		}
		// Add other special rule title updates here if needed
	}
	// Update turn text (Default logic, handles standard game and some special modes)
	if (gameState === 'checkmate') {
		// Capture the King uses 'checkmate' state for win, adjust text
		if (game.gameMode === 'specialGame' && game.specialRule === 'captureKing') {
			// Winner determined in endGame, turnText might be showing winner already
		} else if (currentPlayer === 'black') {
			turnText.setText('You Win!');
		} else {
			turnText.setText('AI Wins!');
		}
	} else if (gameState === 'stalemate') {
		turnText.setText('Draw!');
	} else if (aiThinking) {
		turnText.setText('AI Thinking...');
	} else {
		turnText.setText(currentPlayer === 'white' ? 'Your Turn' : 'AI Turn');
	}
};
// Method to show the game mode selection screen
game.showGameModeScreen = function () {
	// Remove title screen if it exists
	if (titleScreen) {
		game.removeChild(titleScreen);
		titleScreen = null;
	}
	// Remove game mode screen if it already exists
	if (gameModeScreen) {
		game.removeChild(gameModeScreen);
		gameModeScreen = null; // Clear reference
	}
	// Remove bot selection screen if it exists
	if (botSelectionScreen) {
		game.removeChild(botSelectionScreen);
		botSelectionScreen = null;
	}
	// Remove daily challenge screen if it exists
	if (dailyChallengeScreen) {
		game.removeChild(dailyChallengeScreen);
		dailyChallengeScreen = null;
	}
	// Create and add game mode screen
	gameModeScreen = new GameModeScreen();
	gameModeScreen.x = 2048 / 2;
	gameModeScreen.y = 2732 / 2;
	game.addChild(gameModeScreen);
	// Update game state
	gameState = 'modeSelect';
};
// Method to show the title screen
// Method to show the bot selection screen
game.showBotSelectionScreen = function () {
	// Remove game mode screen if it exists
	if (gameModeScreen) {
		game.removeChild(gameModeScreen);
		gameModeScreen = null;
	}
	// Remove title screen just in case (shouldn't happen in normal flow)
	if (titleScreen) {
		game.removeChild(titleScreen);
		titleScreen = null;
	}
	// Remove existing bot selection screen if present
	if (botSelectionScreen) {
		game.removeChild(botSelectionScreen);
		botSelectionScreen = null;
	}
	// Create and add bot selection screen
	botSelectionScreen = new BotSelectionScreen();
	botSelectionScreen.x = 2048 / 2;
	botSelectionScreen.y = 2732 / 2;
	game.addChild(botSelectionScreen);
	// Update game state
	gameState = 'botSelect';
};
// Method to show the daily challenge screen
game.showDailyChallengeScreen = function () {
	// Remove other screens
	if (titleScreen) {
		game.removeChild(titleScreen);
		titleScreen = null;
	}
	if (gameModeScreen) {
		game.removeChild(gameModeScreen);
		gameModeScreen = null;
	}
	if (botSelectionScreen) {
		game.removeChild(botSelectionScreen);
		botSelectionScreen = null;
	}
	if (dailyChallengeScreen) {
		game.removeChild(dailyChallengeScreen);
		dailyChallengeScreen = null;
	}
	// Create and add daily challenge screen
	dailyChallengeScreen = new DailyChallengeScreen();
	dailyChallengeScreen.x = 2048 / 2;
	dailyChallengeScreen.y = 2732 / 2;
	game.addChild(dailyChallengeScreen);
	// Update game state
	gameState = 'dailyChallenge';
};
game.showTitleScreen = function () {
	// Remove game mode screen if it exists
	if (gameModeScreen) {
		game.removeChild(gameModeScreen);
		gameModeScreen = null;
	}
	// Remove bot selection screen if it exists
	if (botSelectionScreen) {
		game.removeChild(botSelectionScreen);
		botSelectionScreen = null;
	}
	// Remove daily challenge screen if it exists
	if (dailyChallengeScreen) {
		game.removeChild(dailyChallengeScreen);
		dailyChallengeScreen = null;
	}
	// Create and add title screen
	titleScreen = new TitleScreen();
	titleScreen.x = 2048 / 2;
	titleScreen.y = 2732 / 2;
	game.addChild(titleScreen);
	// Update game state
	gameState = 'title';
};
// Method to start the game from mode selection screen
game.startGame = function () {
	// Remove game mode screen if it exists
	if (gameModeScreen) {
		game.removeChild(gameModeScreen);
		gameModeScreen = null;
	}
	// Remove bot selection screen if it exists
	if (botSelectionScreen) {
		game.removeChild(botSelectionScreen);
		botSelectionScreen = null;
	}
	// Remove daily challenge screen if it exists (shouldn't be possible to start game from here, but for safety)
	if (dailyChallengeScreen) {
		game.removeChild(dailyChallengeScreen);
		dailyChallengeScreen = null;
	}
	// Change state based on mode
	if (game.gameMode === 'specialGame') {
		gameState = 'specialGame'; // Or keep as 'playing' and rely on game.specialRule
		scoreTxt.setText('Daily Challenge - ' + selectedBot.toUpperCase()); // Or show special rule name?
	} else {
		gameState = 'playing';
		// Update game title based on selected mode
		scoreTxt.setText('Crazy Chess - ' + game.gameMode.toUpperCase());
	}
	// Initialize the chess board
	initializeBoard();
	// Reset special mode variables
	goatedTurnCounter = 0;
	icyDayFrozenPieces = [];
	yetiPawns = [];
	// Show the score and turn text
	scoreTxt.visible = true;
	turnText.visible = true;
};
// Show title screen first
titleScreen = new TitleScreen();
titleScreen.x = 2048 / 2;
titleScreen.y = 2732 / 2;
game.addChild(titleScreen);
// Hide score and turn text initially
scoreTxt.visible = false;
turnText.visible = false;
; ===================================================================
--- original.js
+++ change.js
@@ -1442,9 +1442,9 @@
 // Clear highlights from all squares
 function clearHighlights() {
 	for (var row = 0; row < BOARD_SIZE; row++) {
 		for (var col = 0; col < BOARD_SIZE; col++) {
-			if (isBoardPositionValid(row, col)) {
+			if (board[row][col]) {
 				board[row][col].highlight();
 			}
 		}
 	}
@@ -1499,12 +1499,8 @@
 	}
 	// Filter out moves that would put the king in check
 	return filterCheckMoves(square, moves);
 }
-// Function to check if a board row/col exists
-function isBoardPositionValid(row, col) {
-	return board && row >= 0 && row < board.length && board[row] && col >= 0 && col < board[row].length && board[row][col] !== null;
-}
 // Calculate valid moves for a pawn
 function calculatePawnMoves(row, col, piece, moves) {
 	var direction = piece.color === 'white' ? -1 : 1;
 	// Move forward one square
@@ -1842,8 +1838,12 @@
 	}
 	// Standard check filtering
 	for (var i = 0; i < moves.length; i++) {
 		var move = moves[i];
+		// Make sure the move exists and has valid row/col properties
+		if (!move || !board[move.row] || !board[move.row][move.col]) {
+			continue;
+		}
 		// Simulate the move
 		var originalPiece = board[move.row][move.col].piece;
 		board[move.row][move.col].piece = piece;
 		board[fromSquare.row][fromSquare.col].piece = null;
:quality(85)/https://cdn.frvr.ai/68067ba548febdd40342a72b.png%3F3) 
 Black horse. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067bd348febdd40342a737.png%3F3) 
 White horse. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067c0348febdd40342a745.png%3F3) 
 Black lawnmower. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067c2d48febdd40342a753.png%3F3) 
 White lawnmower. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067c5948febdd40342a760.png%3F3) 
 Black crown. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067c8648febdd40342a76e.png%3F3) 
 White crown. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067cc348febdd40342a778.png%3F3) 
 White cannon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067ddf48febdd40342a7a0.png%3F3) 
 Black cannon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067e3548febdd40342a7aa.png%3F3) 
 Black queen. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067e6b48febdd40342a7b4.png%3F3) 
 White queen. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067e9948febdd40342a7c2.png%3F3) 
 Black pawn. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68067ebe48febdd40342a7cd.png%3F3) 
 White pawn. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/680784dea2fbd5756988b6ee.png%3F3) 
 White goat. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6807850aa2fbd5756988b6f7.png%3F3) 
 Bear trap. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows