简体   繁体   中英

Python Maze Generation Script - Converting to Javascript: Differences in Maths?

I have a maze generator script in Python (3.4) that I am trying to convert to Javascript. The original Python script can be found below:

import random

width = 10
height = 10
difficulty = 5

walls = []
maze = [0] * width

for i in range(height):
    maze[i] = [0] * height

maze[0][1] = 1

walls.append([1, 1, 1])

print(random.random())

def addWalls():
    walls.append([X + 1, Y, 1])
    walls.append([X - 1, Y, 2])
    walls.append([X, Y + 1, 3])
    walls.append([X, Y - 1, 4])
    maze[X][Y] = 1

while len(walls) > 0:
    if len(walls) > difficulty:
        current = len(walls) - round(random.random() * difficulty) - 1
    else:
        current = round(random.random() * (len(walls) - 1))

    cell = walls[current]
    walls.pop(current)

    X = cell[0]
    Y = cell[1]
    Dir = cell[2]

    if Dir == 1:
        if X + 1 < width and maze[X][Y] == 0 and maze[X + 1][Y] == 0 and maze[X + 1][Y - 1] == 0 and maze[X + 1][Y + 1] == 0 and maze[X][Y - 1] == 0 and maze[X][Y + 1] == 0:
            addWalls()
    elif Dir == 2:
        if X - 1 >  - 1 and maze[X][Y] == 0 and maze[X - 1][Y] == 0 and maze[X - 1][Y - 1] == 0 and maze[X - 1][Y + 1] == 0 and maze[X][Y - 1] == 0 and maze[X][Y + 1] == 0:
            addWalls()
    elif Dir == 3:
        if Y + 1 < height and maze[X][Y] == 0 and maze[X][Y + 1] == 0 and maze[X - 1][Y + 1] == 0 and maze[X + 1][Y + 1] == 0 and maze[X - 1][Y] == 0 and maze[X + 1][Y] == 0:
            addWalls()
    elif Dir == 4:
        if Y - 1 >  - 1 and maze[X][Y] == 0 and maze[X][Y - 1] == 0 and maze[X - 1][Y - 1] == 0 and maze[X + 1][Y - 1] == 0 and maze[X - 1][Y] == 0 and maze[X + 1][Y] == 0:
            addWalls()

for y in range(0, height):
    line = ''
    for x in range(0, width):
        if (maze[x][y] == 0):
            line += '0'
        else:
            line += '1'
    print(line)

The script works as it should, however when trying to accomplish the same in Javascript, the maze seems to stop traversing. See the snippet below (0 = wall, 1 = open space in the maze):

 function newLevel(dimensions, difficulty) { // create arrays walls = [ [1, 1, 1] ]; maze = []; for (i = 0; i < dimensions - 1; i++) { maze[i] = [0]; for (j = 0; j < dimensions - 1; j++) { maze[i][j] = [0]; } } // set the cell (0; 1) as the exit maze[0][1] = 1; function addwalls() { walls.push([X + 1, Y, 1]); walls.push([X - 1, Y, 2]); walls.push([X, Y + 1, 3]); walls.push([X, Y - 1, 4]); maze[X][Y] = 1; } while (walls.length > 0) { current = Math.round(Math.random() * (walls.length - 1)); if (walls.length > difficulty) { current = walls.length - Math.round(Math.random() * difficulty) - 1; } cell = walls[current]; walls.pop(current); X = cell[0]; Y = cell[1]; Dir = cell[2]; if (Dir == 1 && X + 1 < dimensions && maze[X][Y] == 0 && maze[X + 1][Y] == 0 && maze[X + 1][Y - 1] == 0 && maze[X + 1][Y + 1] == 0 && maze[X][Y - 1] == 0 && maze[X][Y + 1] == 0) { addwalls(); } if (Dir == 2 && X - 1 > -1 && maze[X][Y] == 0 && maze[X - 1][Y] == 0 && maze[X - 1][Y - 1] == 0 && maze[X - 1][Y + 1] == 0 && maze[X][Y - 1] == 0 && maze[X][Y + 1] == 0) { addwalls() } if (Dir == 3 && Y + 1 < dimensions && maze[X][Y] == 0 && maze[X][Y + 1] == 0 && maze[X - 1][Y + 1] == 0 && maze[X + 1][Y + 1] == 0 && maze[X - 1][Y] == 0 && maze[X + 1][Y] == 0) { addwalls(); } if (Dir == 4 && Y - 1 > -1 && maze[X][Y] == 0 && maze[X][Y - 1] == 0 && maze[X - 1][Y - 1] == 0 && maze[X + 1][Y - 1] == 0 && maze[X - 1][Y] == 0 && maze[X + 1][Y] == 0) { addwalls(); } } cells = maze; for (var row = 0; row < maze.length; row++) { for (var col = 0; col < maze[row].length; col++) { $('body').append(maze[row][col]); } $('body').append('<br />'); } } $(document).ready(function() { newLevel(30, 5); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> </body> 

Are there any major differences in the way that Maths is done between Python and Javascript?

Thanks

EDIT: Thank you very much for your support. Here is the working script:

function newLevel(dimensions, difficulty) {

  // create arrays
  walls = [[1, 1, 1]];
  maze = [];

  for (i = 0; i < dimensions; i++) {
    maze[i] = [0];
    for (j = 0; j < dimensions; j++) {
      maze[i][j] = [0];
    }
  }

  // set the cell (0; 1) as the exit
  maze[0][1] = 1;

  function addwalls() {
    walls.push([X + 1, Y, 1]);
    walls.push([X - 1, Y, 2]);
    walls.push([X, Y + 1, 3]);
    walls.push([X, Y - 1, 4]);
    maze[X][Y] = 1;
  }

  while (walls.length > 0) {
    current = Math.round(Math.random() * (walls.length - 1));
    if (walls.length > difficulty) {
      current = walls.length - Math.round(Math.random() * difficulty) - 1;
    }

    cell = walls[current];
    walls.splice(current, 1)[0];

    X = cell[0];
    Y = cell[1];
    Dir = cell[2];

    if (Dir == 1 && X + 1 < dimensions && maze[X][Y] == 0 && maze[X + 1][Y] == 0 && maze[X + 1][Y - 1] == 0 && maze[X + 1][Y + 1] == 0 && maze[X][Y - 1] == 0 && maze[X][Y + 1] == 0) {
      addwalls();
    }
    if (Dir == 2 && X - 1 >  - 1 && maze[X][Y] == 0 && maze[X - 1][Y] == 0 && maze[X - 1][Y - 1] == 0 && maze[X - 1][Y + 1] == 0 && maze[X][Y - 1] == 0 && maze[X][Y + 1] == 0) {
      addwalls()
    }
    if (Dir == 3 && Y + 1 < dimensions && maze[X][Y] == 0 && maze[X][Y + 1] == 0 && maze[X - 1][Y + 1] == 0 && maze[X + 1][Y + 1] == 0 && maze[X - 1][Y] == 0 && maze[X + 1][Y] == 0) {
      addwalls();
    }
    if (Dir == 4 && Y - 1 >  - 1 && maze[X][Y] == 0 && maze[X][Y - 1] == 0 && maze[X - 1][Y - 1] == 0 && maze[X + 1][Y - 1] == 0 && maze[X - 1][Y] == 0 && maze[X + 1][Y] == 0) {
      addwalls();
    }
  }
  return cells;
}

The difference is that, in python, pop appears to be able to remove any element from an array. In javascript, pop removes the last element of an array, and it takes no arguments. To remove an arbitrary element from an array in javscript, use splice , which can remove and add elements at a given index:

cell = walls[current];
walls.pop(current);

becomes

cell = walls.splice(current, 1)[0];

What this does is it removes 1 element from the array walls starting at the index current. Splice returns an array of elements removed, so cell is the first element of that array.

There are a lot of tiny but easily neck-breaking differences between Python and JavaScript.

The loop in Python

for i in range(10)

rolls from 0 up to 9 in ten steps. You translated it into

for (i = 0; i < 10 - 1; i++)

which rolls from 0 to 8 in nine steps (assuming the value of height is equal to dimensions ).

You cannot choose which element to pop out of a JavaScript array you need Array.splice() to do so (or roll your own, of course).

Regarding the integer problem: JavaScript's Number object is a 64-bit floating point number, better known as an IEEE-754 binary64 double. That restricts the range of integers to -2^53 < x < 2^53 . You can "persuade" the engine to handle some numbers x as signed integers by x|0 and as unsigned integers as by x>>>0 but the automatic conversion tries to sneak in in every possible way, preferable the most unexpected ones.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM