Building a Maze Game in Node.js
Tags: javascript, beginners, tutorial, codenewbie
Published: 2024-02-02 15:43:18

Hi in this tutorial i will show you how to create a simple maze game in Node.js. The player will have to navigate through a field of holes to find their hat or whatever you want it to be without falling into any holes. This project is ideal for people that have a basic understanding of JavaScript and wanting to grow you're skills.

Before we start coding, here's what you need to know:

No External Dependencies: This game uses only Node.js. There are no external libraries or frameworks to install.
Single File Setup: The entire game is contained within a single JavaScript file.
Pre-requisites: Ensure you have Node.js installed on your computer. You can download it from Node.js official website if it's not already installed.

All you need to do is create a new JavaScript file (mazeGame.js) and follow along with this tutorial.

Step 1: Setting Up
First, we need to import the readline module to handle command line input:

```
const readline = require('readline');

```

Step 2: Defining the Game Characters
We'll use different characters to represent elements in the game:

```
const hat = '^';          // The hat
const hole = 'O';         // The holes
const fieldCharacter = '░';  // Open field
const pathCharacter = '*';   // The path taken

```

Step 3: Creating the Field
The initializeField function generates the maze:

```
function initializeField(height, width, percentage) {
  // Create a 2D array representing the field
  const field = new Array(height).fill(0).map(el => new Array(width));

  // Fill the field with holes and open spaces
  for (let y = 0; y < height; y++) {
    for (let x = 0; x < width; x++) {
      const prob = Math.random();
      field[y][x] = prob > percentage ? fieldCharacter : hole;
    }
  }
  return field;
}

```

Step 4: Placing the Hat
The setHatLocation function places the hat randomly in the field:

```
function setHatLocation(field, height, width) {
  let hatLocation;

  // Ensure the hat is not at the starting position
  do {
    hatLocation = {
      x: Math.floor(Math.random() * width),
      y: Math.floor(Math.random() * height)
    };
  } while (hatLocation.x === 0 && hatLocation.y === 0);

  field[hatLocation.y][hatLocation.x] = hat;
  return field;
}

```

Step 5: Displaying the Field
The printField function prints the current state of the field:

```
function printField(field) {
  const displayString = field.map(row => row.join('')).join('\n');
  console.log(displayString);
}

```

Step 6: Running the Game
The runGame function contains the main game loop:

```
// Main function to run the game.
function runGame(field) {
  let locationX = 0;
  let locationY = 0;
  field[0][0] = pathCharacter; // Set the starting point.

  let playing = true;
  printField(field);

  // Initialize readline interface for user input.
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  // Function to handle user input.
  const handleInput = (answer) => {
    field[locationY][locationX] = fieldCharacter; // Clear the previous path character.

    // Move the player based on input.
    switch (answer.toUpperCase()) {
      case 'U':
        locationY -= 1;
        break;
      case 'D':
        locationY += 1;
        break;
      case 'L':
        locationX -= 1;
        break;
      case 'R':
        locationX += 1;
        break;
      default:
        console.log('Enter U, D, L, or R.');
        rl.prompt();
        return;
    }

    // Check for various conditions (out of bounds, falling in a hole, finding the hat).
    if (!isInBounds(field, locationX, locationY)) {
      console.log('Out of bounds instruction!');
      playing = false;
    } else if (isHole(field, locationX, locationY)) {
      console.log('Sorry, you fell down a hole!');
      playing = false;
    } else if (isHat(field, locationX, locationY)) {
      console.log('Congrats, you found your hat!');
      playing = false;
    }

    // Continue the game or end it based on the player's state.
    if (playing) {
      field[locationY][locationX] = pathCharacter;
      printField(field);
      rl.prompt();
    } else {
      rl.close();
    }
  };

  // Set up readline to listen for user input.
  rl.on('line', handleInput);
  rl.setPrompt('Which way? ');
  rl.prompt();
}
```

Step 7: Helper Functions
We use isInBounds, isHat, and isHole to check the player's status:

```
// Helper functions to check the player's state.
function isInBounds(field, x, y) {
  return y >= 0 && x >= 0 && y < field.length && x < field[0].length;
}

function isHat(field, x, y) {
  return field[y][x] === hat;
}

function isHole(field, x, y) {
  return field[y][x] === hole;
}
```
Step 8: Starting the Game
Finally, we initialize the game with the field size and start it:

```
// Game settings.
const height = 10;
const width = 10;
const percentage = 0.2;

// Initialize the game field and start the game.
const myField = setHatLocation(initializeField(height, width, percentage), height, width);
runGame(myField);

```


There you have it only about 130 lines of code and it's a fun game to play and also make and build on it make it you're own and i hope this improves you're skills. Feel free to comment on how you have built on it and made it bigger and better.