User prompt
Faster movement
User prompt
Make the maze bigger and the ai move faster
Code edit (1 edits merged)
Please save this source code
User prompt
Maze Master: AI Learning Adventure
Initial prompt
A randomly generated maze with a bot that uses RL to learn the maze when it reaches a dead end it restarts with its info still the same but everytime you load the game its brain resets
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AIBot = Container.expand(function () { var self = Container.call(this); self.visual = self.attachAsset('bot', { anchorX: 0.5, anchorY: 0.5 }); self.gridX = 0; self.gridY = 0; self.memory = {}; // Stores path memory self.currentPath = []; // Stores current path self.possibleMoves = []; // Stores possible moves from current position self.isMoving = false; self.hasWon = false; self.moveTo = function (x, y, duration) { if (self.isMoving) { return; } self.isMoving = true; tween(self, { x: x, y: y }, { duration: duration || 300, easing: tween.easeInOut, onFinish: function onFinish() { self.isMoving = false; } }); }; self.setGridPosition = function (x, y) { self.gridX = x; self.gridY = y; }; self.getMemoryKey = function (x, y) { return x + ',' + y; }; self.rememberCell = function (x, y, value) { var key = self.getMemoryKey(x, y); self.memory[key] = value; }; self.getCellMemory = function (x, y) { var key = self.getMemoryKey(x, y); return self.memory[key]; }; self.addToPath = function (x, y) { self.currentPath.push({ x: x, y: y }); }; self.reset = function () { self.currentPath = []; self.possibleMoves = []; self.isMoving = false; self.hasWon = false; }; self.clearMemory = function () { self.memory = {}; }; return self; }); var MazeCell = Container.expand(function (x, y, type) { var self = Container.call(this); self.gridX = x; self.gridY = y; self.type = type || 'wall'; self.visited = false; self.deadEnd = false; // Visual representation self.visual = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5 }); self.setType = function (newType) { self.type = newType; self.removeChild(self.visual); self.visual = self.attachAsset(newType, { anchorX: 0.5, anchorY: 0.5 }); }; self.markVisited = function () { if (self.type === 'path' && !self.visited) { self.visited = true; self.removeChild(self.visual); self.visual = self.attachAsset('visited', { anchorX: 0.5, anchorY: 0.5 }); } }; self.markDeadEnd = function () { if (self.type === 'path' && !self.deadEnd) { self.deadEnd = true; self.removeChild(self.visual); self.visual = self.attachAsset('deadEnd', { anchorX: 0.5, anchorY: 0.5 }); } }; return self; }); var MazeGame = Container.expand(function () { var self = Container.call(this); // Maze properties self.mazeWidth = 15; self.mazeHeight = 15; self.cellSize = 40; self.cells = []; self.startCell = { x: 1, y: 1 }; self.endCell = { x: self.mazeWidth - 2, y: self.mazeHeight - 2 }; // AI Bot self.bot = new AIBot(); self.addChild(self.bot); // Game state self.gameRunning = false; self.moveInterval = null; self.moveDelay = 300; // milliseconds between moves self.consecutiveDeadEnds = 0; self.initialize = function () { self.generateMaze(); self.positionBot(); self.bot.clearMemory(); LK.playMusic('bgMusic'); }; self.generateMaze = function () { // Clear existing cells for (var i = 0; i < self.cells.length; i++) { for (var j = 0; j < self.cells[i].length; j++) { if (self.cells[i][j]) { self.removeChild(self.cells[i][j]); } } } // Initialize all cells as walls self.cells = []; for (var x = 0; x < self.mazeWidth; x++) { self.cells[x] = []; for (var y = 0; y < self.mazeHeight; y++) { var cell = new MazeCell(x, y, 'wall'); cell.x = x * self.cellSize; cell.y = y * self.cellSize; self.cells[x][y] = cell; self.addChild(cell); } } // Generate maze using recursive backtracking self.generateMazeRecursive(self.startCell.x, self.startCell.y); // Set start and end cells self.cells[self.startCell.x][self.startCell.y].setType('start'); self.cells[self.endCell.x][self.endCell.y].setType('end'); }; self.generateMazeRecursive = function (x, y) { // Mark current cell as path self.cells[x][y].setType('path'); // Define directions: up, right, down, left var directions = [{ dx: 0, dy: -2 }, // up { dx: 2, dy: 0 }, // right { dx: 0, dy: 2 }, // down { dx: -2, dy: 0 } // left ]; // Shuffle directions shuffleArray(directions); // Explore each direction for (var i = 0; i < directions.length; i++) { var dx = directions[i].dx; var dy = directions[i].dy; var newX = x + dx; var newY = y + dy; // Check if the new cell is within bounds and is a wall if (newX > 0 && newX < self.mazeWidth - 1 && newY > 0 && newY < self.mazeHeight - 1 && self.cells[newX][newY].type === 'wall') { // Create a passage by making the cell between current and new a path self.cells[x + dx / 2][y + dy / 2].setType('path'); // Continue maze generation from the new cell self.generateMazeRecursive(newX, newY); } } }; self.positionBot = function () { // Position bot at start cell self.bot.setGridPosition(self.startCell.x, self.startCell.y); self.bot.x = self.startCell.x * self.cellSize; self.bot.y = self.startCell.y * self.cellSize; self.bot.addToPath(self.startCell.x, self.startCell.y); }; self.startGame = function () { if (self.gameRunning) { return; } self.gameRunning = true; self.moveInterval = LK.setInterval(function () { self.makeAIMove(); }, self.moveDelay); }; self.stopGame = function () { if (!self.gameRunning) { return; } self.gameRunning = false; if (self.moveInterval) { LK.clearInterval(self.moveInterval); self.moveInterval = null; } }; self.makeAIMove = function () { if (!self.gameRunning || self.bot.isMoving) { return; } // Check if bot reached the end if (self.bot.gridX === self.endCell.x && self.bot.gridY === self.endCell.y) { self.onBotReachedEnd(); return; } // Get possible moves self.getPossibleMoves(); // If no moves are available, backtrack if (self.bot.possibleMoves.length === 0) { self.onDeadEnd(); return; } // Choose best move based on memory var bestMove = self.chooseBestMove(); // Mark current cell as visited self.cells[self.bot.gridX][self.bot.gridY].markVisited(); // Remember this cell self.bot.rememberCell(self.bot.gridX, self.bot.gridY, 'visited'); // Update bot position self.bot.setGridPosition(bestMove.x, bestMove.y); self.bot.addToPath(bestMove.x, bestMove.y); // Move bot visually self.bot.moveTo(bestMove.x * self.cellSize, bestMove.y * self.cellSize); // Play move sound LK.getSound('move').play(); }; self.getPossibleMoves = function () { var x = self.bot.gridX; var y = self.bot.gridY; self.bot.possibleMoves = []; // Check four directions var directions = [{ x: x, y: y - 1 }, // up { x: x + 1, y: y }, // right { x: x, y: y + 1 }, // down { x: x - 1, y: y } // left ]; for (var i = 0; i < directions.length; i++) { var nx = directions[i].x; var ny = directions[i].y; // Check if the cell is within bounds and is a path or end if (nx >= 0 && nx < self.mazeWidth && ny >= 0 && ny < self.mazeHeight && (self.cells[nx][ny].type === 'path' || self.cells[nx][ny].type === 'end' || self.cells[nx][ny].type === 'start')) { // Check if the cell is not marked as dead end in memory var cellMemory = self.bot.getCellMemory(nx, ny); if (cellMemory !== 'deadEnd') { self.bot.possibleMoves.push({ x: nx, y: ny }); } } } }; self.chooseBestMove = function () { var moves = self.bot.possibleMoves; var bestMoves = []; var bestScore = -Infinity; // Score each move for (var i = 0; i < moves.length; i++) { var move = moves[i]; var score = self.scoreMove(move); if (score > bestScore) { bestScore = score; bestMoves = [move]; } else if (score === bestScore) { bestMoves.push(move); } } // Randomly choose among best moves return bestMoves[Math.floor(Math.random() * bestMoves.length)]; }; self.scoreMove = function (move) { var memory = self.bot.getCellMemory(move.x, move.y); // Prioritize the end cell if (move.x === self.endCell.x && move.y === self.endCell.y) { return 100; } // Avoid visited cells if (memory === 'visited') { return -10; } // Prefer unexplored cells return 10; }; self.onDeadEnd = function () { self.consecutiveDeadEnds++; // Mark current path as dead end in memory for (var i = self.bot.currentPath.length - 1; i >= 0; i--) { var pathCell = self.bot.currentPath[i]; var cellMemory = self.bot.getCellMemory(pathCell.x, pathCell.y); if (cellMemory !== 'deadEnd') { self.bot.rememberCell(pathCell.x, pathCell.y, 'deadEnd'); self.cells[pathCell.x][pathCell.y].markDeadEnd(); // Break if we find a cell with multiple exits self.getPossibleMovesForCell(pathCell.x, pathCell.y); if (self.bot.possibleMoves.length > 1) { break; } } } // Play dead end sound LK.getSound('deadend').play(); // Reset bot to start self.bot.reset(); self.positionBot(); // If we're stuck in a loop, slow down and eventually reset if (self.consecutiveDeadEnds > 10) { self.moveDelay = Math.min(1000, self.moveDelay + 50); if (self.consecutiveDeadEnds > 20) { self.initialize(); self.consecutiveDeadEnds = 0; self.moveDelay = 300; } } }; self.getPossibleMovesForCell = function (x, y) { self.bot.possibleMoves = []; // Check four directions var directions = [{ x: x, y: y - 1 }, // up { x: x + 1, y: y }, // right { x: x, y: y + 1 }, // down { x: x - 1, y: y } // left ]; for (var i = 0; i < directions.length; i++) { var nx = directions[i].x; var ny = directions[i].y; // Check if the cell is within bounds and is a path or end if (nx >= 0 && nx < self.mazeWidth && ny >= 0 && ny < self.mazeHeight && (self.cells[nx][ny].type === 'path' || self.cells[nx][ny].type === 'end' || self.cells[nx][ny].type === 'start')) { self.bot.possibleMoves.push({ x: nx, y: ny }); } } }; self.onBotReachedEnd = function () { self.stopGame(); self.bot.hasWon = true; // Play win sound LK.getSound('win').play(); // Show winning message LK.showYouWin(); }; return self; }); /**** * Initialize Game ****/ // Utility function to shuffle an array var game = new LK.Game({ backgroundColor: 0x121212 }); /**** * Game Code ****/ // Utility function to shuffle an array // Create status text function shuffleArray(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; } var statusText = new Text2('AI Maze Learning', { size: 40, fill: 0xFFFFFF }); statusText.anchor.set(0.5, 0); LK.gui.top.addChild(statusText); // Create stats text var statsText = new Text2('Moves: 0 | Memory: 0', { size: 30, fill: 0xCCCCCC }); statsText.anchor.set(0.5, 0); statsText.y = 50; LK.gui.top.addChild(statsText); // Create instructions text var instructionsText = new Text2('Watch the AI learn to solve the maze.\nGreen blocks mark visited paths.\nRed blocks mark dead ends.', { size: 25, fill: 0xAAAAAA }); instructionsText.anchor.set(0.5, 1); LK.gui.bottom.addChild(instructionsText); // Create reset button var resetButton = new Text2('RESET MAZE', { size: 35, fill: 0xFFFFFF }); resetButton.anchor.set(0.5, 1); resetButton.y = -60; resetButton.interactive = true; LK.gui.bottom.addChild(resetButton); // Create maze game var mazeGame = new MazeGame(); game.addChild(mazeGame); // Position the maze in the center of the screen var centerMaze = function centerMaze() { var mazePixelWidth = mazeGame.mazeWidth * mazeGame.cellSize; var mazePixelHeight = mazeGame.mazeHeight * mazeGame.cellSize; mazeGame.x = (2048 - mazePixelWidth) / 2; mazeGame.y = (2732 - mazePixelHeight) / 2; }; // Initialize the game var initGame = function initGame() { mazeGame.initialize(); centerMaze(); mazeGame.startGame(); updateStats(); }; // Reset button handlers resetButton.down = function () { initGame(); }; // Update stats display var updateStats = function updateStats() { var memoryCount = Object.keys(mazeGame.bot.memory).length; statsText.setText('Moves: ' + mazeGame.bot.currentPath.length + ' | Memory: ' + memoryCount); }; // Initialize the game when loaded initGame(); // Game update function game.update = function () { // Update stats if game is running if (mazeGame.gameRunning) { updateStats(); } };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,501 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var AIBot = Container.expand(function () {
+ var self = Container.call(this);
+ self.visual = self.attachAsset('bot', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.gridX = 0;
+ self.gridY = 0;
+ self.memory = {}; // Stores path memory
+ self.currentPath = []; // Stores current path
+ self.possibleMoves = []; // Stores possible moves from current position
+ self.isMoving = false;
+ self.hasWon = false;
+ self.moveTo = function (x, y, duration) {
+ if (self.isMoving) {
+ return;
+ }
+ self.isMoving = true;
+ tween(self, {
+ x: x,
+ y: y
+ }, {
+ duration: duration || 300,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ self.isMoving = false;
+ }
+ });
+ };
+ self.setGridPosition = function (x, y) {
+ self.gridX = x;
+ self.gridY = y;
+ };
+ self.getMemoryKey = function (x, y) {
+ return x + ',' + y;
+ };
+ self.rememberCell = function (x, y, value) {
+ var key = self.getMemoryKey(x, y);
+ self.memory[key] = value;
+ };
+ self.getCellMemory = function (x, y) {
+ var key = self.getMemoryKey(x, y);
+ return self.memory[key];
+ };
+ self.addToPath = function (x, y) {
+ self.currentPath.push({
+ x: x,
+ y: y
+ });
+ };
+ self.reset = function () {
+ self.currentPath = [];
+ self.possibleMoves = [];
+ self.isMoving = false;
+ self.hasWon = false;
+ };
+ self.clearMemory = function () {
+ self.memory = {};
+ };
+ return self;
+});
+var MazeCell = Container.expand(function (x, y, type) {
+ var self = Container.call(this);
+ self.gridX = x;
+ self.gridY = y;
+ self.type = type || 'wall';
+ self.visited = false;
+ self.deadEnd = false;
+ // Visual representation
+ self.visual = self.attachAsset(self.type, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.setType = function (newType) {
+ self.type = newType;
+ self.removeChild(self.visual);
+ self.visual = self.attachAsset(newType, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ };
+ self.markVisited = function () {
+ if (self.type === 'path' && !self.visited) {
+ self.visited = true;
+ self.removeChild(self.visual);
+ self.visual = self.attachAsset('visited', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ }
+ };
+ self.markDeadEnd = function () {
+ if (self.type === 'path' && !self.deadEnd) {
+ self.deadEnd = true;
+ self.removeChild(self.visual);
+ self.visual = self.attachAsset('deadEnd', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ }
+ };
+ return self;
+});
+var MazeGame = Container.expand(function () {
+ var self = Container.call(this);
+ // Maze properties
+ self.mazeWidth = 15;
+ self.mazeHeight = 15;
+ self.cellSize = 40;
+ self.cells = [];
+ self.startCell = {
+ x: 1,
+ y: 1
+ };
+ self.endCell = {
+ x: self.mazeWidth - 2,
+ y: self.mazeHeight - 2
+ };
+ // AI Bot
+ self.bot = new AIBot();
+ self.addChild(self.bot);
+ // Game state
+ self.gameRunning = false;
+ self.moveInterval = null;
+ self.moveDelay = 300; // milliseconds between moves
+ self.consecutiveDeadEnds = 0;
+ self.initialize = function () {
+ self.generateMaze();
+ self.positionBot();
+ self.bot.clearMemory();
+ LK.playMusic('bgMusic');
+ };
+ self.generateMaze = function () {
+ // Clear existing cells
+ for (var i = 0; i < self.cells.length; i++) {
+ for (var j = 0; j < self.cells[i].length; j++) {
+ if (self.cells[i][j]) {
+ self.removeChild(self.cells[i][j]);
+ }
+ }
+ }
+ // Initialize all cells as walls
+ self.cells = [];
+ for (var x = 0; x < self.mazeWidth; x++) {
+ self.cells[x] = [];
+ for (var y = 0; y < self.mazeHeight; y++) {
+ var cell = new MazeCell(x, y, 'wall');
+ cell.x = x * self.cellSize;
+ cell.y = y * self.cellSize;
+ self.cells[x][y] = cell;
+ self.addChild(cell);
+ }
+ }
+ // Generate maze using recursive backtracking
+ self.generateMazeRecursive(self.startCell.x, self.startCell.y);
+ // Set start and end cells
+ self.cells[self.startCell.x][self.startCell.y].setType('start');
+ self.cells[self.endCell.x][self.endCell.y].setType('end');
+ };
+ self.generateMazeRecursive = function (x, y) {
+ // Mark current cell as path
+ self.cells[x][y].setType('path');
+ // Define directions: up, right, down, left
+ var directions = [{
+ dx: 0,
+ dy: -2
+ },
+ // up
+ {
+ dx: 2,
+ dy: 0
+ },
+ // right
+ {
+ dx: 0,
+ dy: 2
+ },
+ // down
+ {
+ dx: -2,
+ dy: 0
+ } // left
+ ];
+ // Shuffle directions
+ shuffleArray(directions);
+ // Explore each direction
+ for (var i = 0; i < directions.length; i++) {
+ var dx = directions[i].dx;
+ var dy = directions[i].dy;
+ var newX = x + dx;
+ var newY = y + dy;
+ // Check if the new cell is within bounds and is a wall
+ if (newX > 0 && newX < self.mazeWidth - 1 && newY > 0 && newY < self.mazeHeight - 1 && self.cells[newX][newY].type === 'wall') {
+ // Create a passage by making the cell between current and new a path
+ self.cells[x + dx / 2][y + dy / 2].setType('path');
+ // Continue maze generation from the new cell
+ self.generateMazeRecursive(newX, newY);
+ }
+ }
+ };
+ self.positionBot = function () {
+ // Position bot at start cell
+ self.bot.setGridPosition(self.startCell.x, self.startCell.y);
+ self.bot.x = self.startCell.x * self.cellSize;
+ self.bot.y = self.startCell.y * self.cellSize;
+ self.bot.addToPath(self.startCell.x, self.startCell.y);
+ };
+ self.startGame = function () {
+ if (self.gameRunning) {
+ return;
+ }
+ self.gameRunning = true;
+ self.moveInterval = LK.setInterval(function () {
+ self.makeAIMove();
+ }, self.moveDelay);
+ };
+ self.stopGame = function () {
+ if (!self.gameRunning) {
+ return;
+ }
+ self.gameRunning = false;
+ if (self.moveInterval) {
+ LK.clearInterval(self.moveInterval);
+ self.moveInterval = null;
+ }
+ };
+ self.makeAIMove = function () {
+ if (!self.gameRunning || self.bot.isMoving) {
+ return;
+ }
+ // Check if bot reached the end
+ if (self.bot.gridX === self.endCell.x && self.bot.gridY === self.endCell.y) {
+ self.onBotReachedEnd();
+ return;
+ }
+ // Get possible moves
+ self.getPossibleMoves();
+ // If no moves are available, backtrack
+ if (self.bot.possibleMoves.length === 0) {
+ self.onDeadEnd();
+ return;
+ }
+ // Choose best move based on memory
+ var bestMove = self.chooseBestMove();
+ // Mark current cell as visited
+ self.cells[self.bot.gridX][self.bot.gridY].markVisited();
+ // Remember this cell
+ self.bot.rememberCell(self.bot.gridX, self.bot.gridY, 'visited');
+ // Update bot position
+ self.bot.setGridPosition(bestMove.x, bestMove.y);
+ self.bot.addToPath(bestMove.x, bestMove.y);
+ // Move bot visually
+ self.bot.moveTo(bestMove.x * self.cellSize, bestMove.y * self.cellSize);
+ // Play move sound
+ LK.getSound('move').play();
+ };
+ self.getPossibleMoves = function () {
+ var x = self.bot.gridX;
+ var y = self.bot.gridY;
+ self.bot.possibleMoves = [];
+ // Check four directions
+ var directions = [{
+ x: x,
+ y: y - 1
+ },
+ // up
+ {
+ x: x + 1,
+ y: y
+ },
+ // right
+ {
+ x: x,
+ y: y + 1
+ },
+ // down
+ {
+ x: x - 1,
+ y: y
+ } // left
+ ];
+ for (var i = 0; i < directions.length; i++) {
+ var nx = directions[i].x;
+ var ny = directions[i].y;
+ // Check if the cell is within bounds and is a path or end
+ if (nx >= 0 && nx < self.mazeWidth && ny >= 0 && ny < self.mazeHeight && (self.cells[nx][ny].type === 'path' || self.cells[nx][ny].type === 'end' || self.cells[nx][ny].type === 'start')) {
+ // Check if the cell is not marked as dead end in memory
+ var cellMemory = self.bot.getCellMemory(nx, ny);
+ if (cellMemory !== 'deadEnd') {
+ self.bot.possibleMoves.push({
+ x: nx,
+ y: ny
+ });
+ }
+ }
+ }
+ };
+ self.chooseBestMove = function () {
+ var moves = self.bot.possibleMoves;
+ var bestMoves = [];
+ var bestScore = -Infinity;
+ // Score each move
+ for (var i = 0; i < moves.length; i++) {
+ var move = moves[i];
+ var score = self.scoreMove(move);
+ if (score > bestScore) {
+ bestScore = score;
+ bestMoves = [move];
+ } else if (score === bestScore) {
+ bestMoves.push(move);
+ }
+ }
+ // Randomly choose among best moves
+ return bestMoves[Math.floor(Math.random() * bestMoves.length)];
+ };
+ self.scoreMove = function (move) {
+ var memory = self.bot.getCellMemory(move.x, move.y);
+ // Prioritize the end cell
+ if (move.x === self.endCell.x && move.y === self.endCell.y) {
+ return 100;
+ }
+ // Avoid visited cells
+ if (memory === 'visited') {
+ return -10;
+ }
+ // Prefer unexplored cells
+ return 10;
+ };
+ self.onDeadEnd = function () {
+ self.consecutiveDeadEnds++;
+ // Mark current path as dead end in memory
+ for (var i = self.bot.currentPath.length - 1; i >= 0; i--) {
+ var pathCell = self.bot.currentPath[i];
+ var cellMemory = self.bot.getCellMemory(pathCell.x, pathCell.y);
+ if (cellMemory !== 'deadEnd') {
+ self.bot.rememberCell(pathCell.x, pathCell.y, 'deadEnd');
+ self.cells[pathCell.x][pathCell.y].markDeadEnd();
+ // Break if we find a cell with multiple exits
+ self.getPossibleMovesForCell(pathCell.x, pathCell.y);
+ if (self.bot.possibleMoves.length > 1) {
+ break;
+ }
+ }
+ }
+ // Play dead end sound
+ LK.getSound('deadend').play();
+ // Reset bot to start
+ self.bot.reset();
+ self.positionBot();
+ // If we're stuck in a loop, slow down and eventually reset
+ if (self.consecutiveDeadEnds > 10) {
+ self.moveDelay = Math.min(1000, self.moveDelay + 50);
+ if (self.consecutiveDeadEnds > 20) {
+ self.initialize();
+ self.consecutiveDeadEnds = 0;
+ self.moveDelay = 300;
+ }
+ }
+ };
+ self.getPossibleMovesForCell = function (x, y) {
+ self.bot.possibleMoves = [];
+ // Check four directions
+ var directions = [{
+ x: x,
+ y: y - 1
+ },
+ // up
+ {
+ x: x + 1,
+ y: y
+ },
+ // right
+ {
+ x: x,
+ y: y + 1
+ },
+ // down
+ {
+ x: x - 1,
+ y: y
+ } // left
+ ];
+ for (var i = 0; i < directions.length; i++) {
+ var nx = directions[i].x;
+ var ny = directions[i].y;
+ // Check if the cell is within bounds and is a path or end
+ if (nx >= 0 && nx < self.mazeWidth && ny >= 0 && ny < self.mazeHeight && (self.cells[nx][ny].type === 'path' || self.cells[nx][ny].type === 'end' || self.cells[nx][ny].type === 'start')) {
+ self.bot.possibleMoves.push({
+ x: nx,
+ y: ny
+ });
+ }
+ }
+ };
+ self.onBotReachedEnd = function () {
+ self.stopGame();
+ self.bot.hasWon = true;
+ // Play win sound
+ LK.getSound('win').play();
+ // Show winning message
+ LK.showYouWin();
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
+// Utility function to shuffle an array
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x121212
+});
+
+/****
+* Game Code
+****/
+// Utility function to shuffle an array
+// Create status text
+function shuffleArray(array) {
+ for (var i = array.length - 1; i > 0; i--) {
+ var j = Math.floor(Math.random() * (i + 1));
+ var temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ }
+ return array;
+}
+var statusText = new Text2('AI Maze Learning', {
+ size: 40,
+ fill: 0xFFFFFF
+});
+statusText.anchor.set(0.5, 0);
+LK.gui.top.addChild(statusText);
+// Create stats text
+var statsText = new Text2('Moves: 0 | Memory: 0', {
+ size: 30,
+ fill: 0xCCCCCC
+});
+statsText.anchor.set(0.5, 0);
+statsText.y = 50;
+LK.gui.top.addChild(statsText);
+// Create instructions text
+var instructionsText = new Text2('Watch the AI learn to solve the maze.\nGreen blocks mark visited paths.\nRed blocks mark dead ends.', {
+ size: 25,
+ fill: 0xAAAAAA
+});
+instructionsText.anchor.set(0.5, 1);
+LK.gui.bottom.addChild(instructionsText);
+// Create reset button
+var resetButton = new Text2('RESET MAZE', {
+ size: 35,
+ fill: 0xFFFFFF
+});
+resetButton.anchor.set(0.5, 1);
+resetButton.y = -60;
+resetButton.interactive = true;
+LK.gui.bottom.addChild(resetButton);
+// Create maze game
+var mazeGame = new MazeGame();
+game.addChild(mazeGame);
+// Position the maze in the center of the screen
+var centerMaze = function centerMaze() {
+ var mazePixelWidth = mazeGame.mazeWidth * mazeGame.cellSize;
+ var mazePixelHeight = mazeGame.mazeHeight * mazeGame.cellSize;
+ mazeGame.x = (2048 - mazePixelWidth) / 2;
+ mazeGame.y = (2732 - mazePixelHeight) / 2;
+};
+// Initialize the game
+var initGame = function initGame() {
+ mazeGame.initialize();
+ centerMaze();
+ mazeGame.startGame();
+ updateStats();
+};
+// Reset button handlers
+resetButton.down = function () {
+ initGame();
+};
+// Update stats display
+var updateStats = function updateStats() {
+ var memoryCount = Object.keys(mazeGame.bot.memory).length;
+ statsText.setText('Moves: ' + mazeGame.bot.currentPath.length + ' | Memory: ' + memoryCount);
+};
+// Initialize the game when loaded
+initGame();
+// Game update function
+game.update = function () {
+ // Update stats if game is running
+ if (mazeGame.gameRunning) {
+ updateStats();
+ }
+};
\ No newline at end of file