1

:) I'm creating a maze using JS and P5, with a two dimensional array filled with numbers 0-8. 0 are empty spots, 1 are walls, 2 is the character you walk with, 3 is the exit and 4-8 are items that randomly spawn. In order to exit the maze (through 3, which is set on a fixed spot), all items need to be collected (if you walk over an item, the value of this spot changes back to 0), so every value in the array should be below 4 in order to exit. Now I need a way to check if this is the case.

I tried it with every() but I guess this only works for regular arrays. I suppose I need a for loop but I don't know this should look. So that's where I need help!

My maze consists of 18 rows and columns, like so (but then 15 more rows)

let maze = [
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,2,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,3],
    [1,1,1,1,1,0,1,0,0,0,1,1,0,0,0,0,1,0,1,0,1,0,1]
]

The items spawn randomly, this already works. Now I tried checking if every value is <= 3, with the every, like so

function checkBoard(mazenumbers){
  return mazenumbers <= 3;
}

function alertMazenumbers() {
   alert(maze.every(checkBoard));
}

And want this to display through an alert, once you walk into the exit location, like this

else if(direction === 'right') {
        if(maze[playerPos.y][playerPos.x + 1] == 3) {
            alertMazenumbers();
        }

I want to get an alert with true if every value is <= 3, and false if not. Currently, with this every(), I do get the alert but it only returns false, even when all items are cleared and it should return true.

A. Domingo
  • 13
  • 4
  • *"I tried it with every() but I guess this only works for regular arrays"*. A 2D array is an array of arrays. Which means you should look into the internal arrays, which are the elements of the external one. – Denys Séguret May 07 '19 at 12:01
  • _I want to get an alert with true if every value is <= 3_ You mean every value of the **current row**? If so, it's just `maze[playerPos.y].every(checkBoard)` – briosheje May 07 '19 at 12:04
  • @DenysSéguret Thank you for the clarification :) I'm new to JS so I don't really know the ins and outs of the terminology yet. – A. Domingo May 07 '19 at 12:06
  • @briosheje I need to check it for every row in the 2D array, there cannot be a single value above 3 for it to display true. – A. Domingo May 07 '19 at 12:07

3 Answers3

1

You are on the right track using every!

The maze is an array of arrays (as Denys mentioned in his comment), so you have to use every twice, like so:

function canExitMaze(maze) {
  return maze.every(row => row.every(cell => cell <= 3))
}

If you don't recognize the arrow function syntax (=>) this article explains it.

Hope this helps!

Wouter Raateland
  • 1,007
  • 8
  • 13
0

Method 1: Check if every array only contains numbers that are <= 3

let maze = [
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 3],
  [1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
];

function testMaze(maze) {
  return maze.every(row => row.every(itemIsValid));
}

function itemIsValid(item) {
  return item <= 3;
}

console.log(testMaze(maze));
maze[2][4] = 4;
console.log(testMaze(maze));

Method 2: Merge the arrays and search the numbers

var maze = [
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 3],
  [1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
];

function testMaze(maze) {
  return [].concat(...maze).every(itemIsValid);
}

function itemIsValid(item) {
return item <= 3;
}

console.log(testMaze(maze));
maze[2][4] = 4;
console.log(testMaze(maze));

Method 3: Convert the maze to a string and use regex

var maze = [
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 3],
  [1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
];

function testMaze(maze) {

  //or maze.toString().match(/\d+/g).every(x => itemIsValid(+x));
  return !/[4-8]/g.test(`${maze}`);
}

function itemIsValid(item) {
  return item <= 3;
}

console.log(testMaze(maze));
maze[2][4] = 4;
console.log(testMaze(maze));
nick zoum
  • 7,216
  • 7
  • 36
  • 80
  • When I tried this, my character movement didn't work anymore for some reason and I got both true and false through the console log. – A. Domingo May 07 '19 at 12:21
  • @A.Domingo Sorry, I was in the middle of editing. I now also 2 more ways that might be easier for you to use. Please check the new examples. – nick zoum May 07 '19 at 12:35
0

You can check if every point in the maze is <=3 by doing this

const isTrue = num => num <= 3; // is a single cell true

const isRowTrue = row => row.every(isTrue); // are all cells in a row true
const isMazeTrue = rows => rows.every(isTrue); // are all cells in all rows true

const maze = [
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 3],
  [1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
];

console.log(isMazeTrue(maze));
Aron
  • 8,696
  • 6
  • 33
  • 59
  • I don't think I can use this method as my maze isn't a const, since in my item spawn function, 0's in my maze array get replaced by 4-8's. – A. Domingo May 07 '19 at 12:19
  • Why does that matter? Just replace the const with a let. It doesn't make any difference to the function implementation. – Aron May 07 '19 at 12:21