~ 5 min read
Solving an ASCII Maze with a Neural Network in JavaScript

Wouldn’t it be cool if we could use neural networks to solve a maze? Well, we can! You’ll also find the complete code on GitHub.
Basically we’re going to train a neural network to find the path from the start (S) to the end (E) of a maze represented in ASCII format. The maze will be represented as a grid of characters, where #
represents walls,
(space) represents open paths, S
is the start point, and E
is the end point.
Imagine something like this. Actually, you don’t need to imagine. The maze is in ASCII 😆 so you can literally take a look:
{error: 0.004700880403111688, iterations: 75}
Solution found!
Path through the maze:
# # # # # # #
S * * * # #
# # # * # #
# * * * #
# # # # * #
# # * E
# # # # # # #
Ever wondered how artificial intelligence can navigate complex mazes? Let’s set out to explore how to train a neural network to solve mazes using JavaScript and the brain.js library. By the end, you’ll have a practical understanding of maze representation, training data generation, and neural network application in Node.js. Let’s dive in!
This is what we are going to build:
Prerequisites
Before we start, ensure you have the following:
- Node.js: Version 14 or higher.
- npm: Version 6 or higher.
- brain.js: Install via
npm install brain.js
. - Basic understanding of JavaScript and Node.js.
Represent the Maze in Code
To solve a maze, we first need to represent it in a way that our neural network can understand. We’ll use a 2D array where each cell can be a wall (#
), a start point (S
), an end point (E
), or a path (
).
1. Define the Maze Structure
Why this matters: A clear representation allows us to map positions to coordinates, which is crucial for processing and training.
const maze = [
['#', '#', '#', '#', '#', '#'],
['#', 'S', ' ', ' ', 'E', '#'],
['#', ' ', '#', ' ', '#', '#'],
['#', ' ', '#', ' ', ' ', '#'],
['#', '#', '#', '#', '#', '#']
];
2. Map Positions to Coordinates
Mapping positions helps in tracking the agent’s movement through the maze.
function getCoordinates(maze) {
const coordinates = [];
maze.forEach((row, y) => {
row.forEach((cell, x) => {
if (cell !== '#') {
coordinates.push({ x, y });
}
});
});
return coordinates;
}
const coordinates = getCoordinates(maze);
console.log('Maze Coordinates:', coordinates);
Generate Training Data
Training data is essential for teaching the neural network how to navigate the maze. We’ll create examples based on valid moves from each non-wall cell.
3. Create Training Examples
Why this matters: Training examples guide the neural network in learning valid moves and optimal paths.
function generateTrainingData(maze) {
const trainingData = [];
const directions = ['up', 'down', 'left', 'right'];
coordinates.forEach(({ x, y }) => {
directions.forEach(direction => {
const input = { x, y, direction };
const output = isValidMove(maze, x, y, direction);
trainingData.push({ input, output });
});
});
return trainingData;
}
function isValidMove(maze, x, y, direction) {
// Logic to determine if a move is valid
// Returns 1 for valid, 0 for invalid
}
const trainingData = generateTrainingData(maze);
console.log('Sample Training Data:', trainingData.slice(0, 5));
Set Up the Neural Network
With our training data ready, it’s time to set up the neural network using brain.js.
4. Configure the Neural Network
Why this matters: A well-configured network can efficiently learn and predict the best moves.
const brain = require('brain.js');
const net = new brain.NeuralNetwork({
hiddenLayers: [3]
});
net.train(trainingData, {
errorThresh: 0.005, // Aim for a low error threshold
iterations: 20000,
log: true,
logPeriod: 100
});
Solve the Maze
Now, let’s use the trained neural network to solve the maze.
5. Traverse the Maze
Why this matters: This step demonstrates the neural network’s ability to make decisions and find the path to the exit.
function solveMaze(maze, net) {
let position = { x: 1, y: 1 }; // Starting position
const path = [];
while (maze[position.y][position.x] !== 'E') {
const output = net.run(position);
const direction = getBestDirection(output);
position = move(position, direction);
path.push(position);
}
return path;
}
const solution = solveMaze(maze, net);
console.log('Solution Path:', solution);
Visualize the Process
Visualizing the maze and the path taken by the neural network can provide insights into its decision-making process.
6. Visualize Maze States
Why this matters: Visualization helps in understanding how the neural network navigates the maze.
function visualizeMazeAtPosition(maze, currentPosition) {
const visualMaze = maze.map(row => [...row]);
const { x, y } = currentPosition;
visualMaze[y][x] = '*';
console.log('\nPath through the maze:');
visualMaze.forEach(row => console.log(row.join(' ')));
}
visualizeMazeAtPosition(maze, { x: 1, y: 1 });
Troubleshooting & Pitfalls
- Common Error: Neural network not converging.
- Fix: Increase the number of iterations or adjust the learning rate.
- Pitfall: Infinite loops in maze traversal.
- Fix: Implement a mechanism to avoid revisiting positions.
Automate and Extend
Consider automating the training and solving process using CI/CD pipelines. You can also extend this project by experimenting with larger mazes or more complex neural networks.
Conclusion & Next Steps
By following this guide, you’ve learned how to train a neural network to solve mazes using Node.js and brain.js. Feel free to experiment with different mazes and explore further applications of neural networks in game AI or robotics.
Don’t forget you can check out the complete code on my GitHub profile at the following code repository: lirantal/neural-network-solves-maze.
Happy coding and deploying!