2011-01-07 10 views
5

Estoy tratando de convertir el siguiente código (de Wikipedia) de Java a JavaScript:sintaxis

/* 
* 3 June 2003, [[:en:User:Cyp]]: 
*  Maze, generated by my algorithm 
* 24 October 2006, [[:en:User:quin]]: 
*  Source edited for clarity 
* 25 January 2009, [[:en:User:DebateG]]: 
*  Source edited again for clarity and reusability 
* 1 June 2009, [[:en:User:Nandhp]]: 
*  Source edited to produce SVG file when run from the command-line 
* 
* This program was originally written by [[:en:User:Cyp]], who 
* attached it to the image description page for an image generated by 
* it on en.wikipedia. The image was licensed under CC-BY-SA-3.0/GFDL. 
*/ 

import java.awt.*; 
import java.applet.*; 
import java.util.Random; 

/* Define the bit masks */ 
class Constants { 
    public static final int WALL_ABOVE = 1; 
    public static final int WALL_BELOW = 2; 
    public static final int WALL_LEFT = 4; 
    public static final int WALL_RIGHT = 8; 
    public static final int QUEUED = 16; 
    public static final int IN_MAZE = 32; 
} 

public class Maze extends java.applet.Applet { 
    /* The width and height (in cells) of the maze */ 
    private int width; 
    private int height; 
    private int maze[][]; 
    private static final Random rnd = new Random(); 

    /* The width in pixels of each cell */ 
    private int cell_width; 

    /* Construct a Maze with the default width, height, and cell_width */ 
    public Maze() { 
this(20,20,10); 
    } 

    /* Construct a Maze with specified width, height, and cell_width */ 
    public Maze(int width, int height, int cell_width) { 
this.width = width; 
this.height = height; 
this.cell_width = cell_width; 
    } 

    /* Initialization method that will be called when the program is 
    * run from the command-line. Maze will be written as SVG file. */ 
    public static void main(String[] args) { 
Maze m = new Maze(); 
m.createMaze(); 
m.printSVG(); 
    } 

    /* Initialization method that will be called when the program is 
    * run as an applet. Maze will be displayed on-screen. */ 
    public void init() { 
createMaze(); 
    } 

    /* The maze generation algorithm. */ 
    private void createMaze(){ 
int x, y, n, d; 
int dx[] = { 0, 0, -1, 1 }; 
int dy[] = { -1, 1, 0, 0 }; 

int todo[] = new int[height * width], todonum = 0; 

/* We want to create a maze on a grid. */ 
maze = new int[width][height]; 

/* We start with a grid full of walls. */ 
for (x = 0; x < width; ++x) { 
    for (y = 0; y < height; ++y) { 
    if (x == 0 || x == width - 1 || y == 0 || y == height - 1) { 
     maze[x][y] = Constants.IN_MAZE; 
    } else { 
     maze[x][y] = 63; 
    } 
    } 
} 

/* Select any square of the grid, to start with. */ 
x = 1 + rnd.nextInt (width - 2); 
y = 1 + rnd.nextInt (height - 2); 

/* Mark this square as connected to the maze. */ 
maze[x][y] &= ~48; 

/* Remember the surrounding squares, as we will */ 
for (d = 0; d < 4; ++d) { 
    if ((maze[][d][][d] & Constants.QUEUED) != 0) { 
    /* want to connect them to the maze. */    
    todo[todonum++] = ((x + dx[d]) << Constants.QUEUED) | (y + dy[d]); 
    maze[][d][][d] &= ~Constants.QUEUED; 
    } 
} 

/* We won't be finished until all is connected. */ 
while (todonum > 0) { 
    /* We select one of the squares next to the maze. */ 
    n = rnd.nextInt (todonum); 
    x = todo[n] >> 16; /* the top 2 bytes of the data */ 
    y = todo[n] & 65535; /* the bottom 2 bytes of the data */ 

    /* We will connect it, so remove it from the queue. */ 
    todo[n] = todo[--todonum]; 

    /* Select a direction, which leads to the maze. */ 
    do { 
    d = rnd.nextInt (4); 
    } 
    while ((maze[][d][][d] & Constants.IN_MAZE) != 0); 

    /* Connect this square to the maze. */ 
    maze[x][y] &= ~((1 << d) | Constants.IN_MAZE); 
    maze[][d][][d] &= ~(1 << (d^1)); 

    /* Remember the surrounding squares, which aren't */ 
    for (d = 0; d < 4; ++d) { 
    if ((maze[][d][][d] & Constants.QUEUED) != 0) {  
     /* connected to the maze, and aren't yet queued to be. */ 
     todo[todonum++] = ((x + dx[d]) << Constants.QUEUED) | (y + dy[d]); 
     maze[][d][][d] &= ~Constants.QUEUED; 
    } 
    } 
      /* Repeat until finished. */ 
     } 

     /* Add an entrance and exit. */ 
     maze[1][1] &= ~Constants.WALL_ABOVE; 
     maze[width - 2][height - 2] &= ~Constants.WALL_BELOW; 
    } 

    /* Called by the applet infrastructure to display the maze on-screen. */ 
    public void paint(Graphics g) { 
drawMaze(g); 
    } 

    /* Called to write the maze to an SVG file. */ 
    public void printSVG() { 
System.out.format("<svg width=\"%d\" height=\"%d\" version=\"1.1\"" 
    + " xmlns=\"http://www.w3.org/2000/svg\">\n", 
    width*cell_width, height*cell_width); 
System.out.println(" <g stroke=\"black\" stroke-width=\"1\"" 
     + " stroke-linecap=\"round\">"); 
drawMaze(null); 
System.out.println(" </g>\n</svg>"); 
    } 

    /* Main maze-drawing loop. */ 
    public void drawMaze(Graphics g) { 
     int x, y; 

     for (x = 1; x < width - 1; ++x) { 
      for (y = 1; y < height - 1; ++y) { 
       if ((maze[x][y] & Constants.WALL_ABOVE) != 0) 
     drawLine(  x * cell_width,  y * cell_width, 
     (x + 1) * cell_width,  y * cell_width, g); 
       if ((maze[x][y] & Constants.WALL_BELOW) != 0) 
     drawLine(  x * cell_width, (y + 1) * cell_width, 
     (x + 1) * cell_width, (y + 1) * cell_width, g); 
       if ((maze[x][y] & Constants.WALL_LEFT) != 0) 
     drawLine(  x * cell_width,  y * cell_width, 
       x * cell_width, (y + 1) * cell_width, g); 
       if ((maze[x][y] & Constants.WALL_RIGHT) != 0) 
     drawLine((x + 1) * cell_width,  y * cell_width, 
     (x + 1) * cell_width, (y + 1) * cell_width, g); 
    } 
} 
    } 

    /* Draw a line, either in the SVG file or on the screen. */ 
    public void drawLine(int x1, int y1, int x2, int y2, Graphics g) { 
if (g != null) g.drawLine(x1, y1, x2, y2); 
else System.out.format(" <line x1=\"%d\" y1=\"%d\"" 
      + " x2=\"%d\" y2=\"%d\" />\n", x1, y1, x2, y2); 
    } 
} 

De todos modos, yo estaba resoplando con bastante rapidez cuando llegué a un poco más que simplemente don' entiendo:

/* Remember the surrounding squares, as we will */ 
for (var d = 0; d < 4; ++d) { 
    if ((maze[][d][][d] & Constants.QUEUED) != 0) { 
    /* want to connect them to the maze. */    
    todo[todonum++] = ((x + dx[d]) << Constants.QUEUED) | (y + dy[d]); 
    maze[][d][][d] &= ~Constants.QUEUED; 
    } 
} 

lo que no entiendo es por qué hay cuatro pares de corchetes tras el parámetro "laberinto" en lugar de sólo dos, ya que "laberinto" es una matriz bidimensional, no una matriz de cuatro dimensiones .

Estoy seguro de que hay una buena razón para esto. El problema es que simplemente no lo hago obtengo.

Gracias!

+0

Ignorar [] corchetes vacíos. Esto es solo un error tipográfico y conduce a un error de compilación. –

+0

¿Tiene un enlace al artículo? – OscarRyz

+0

El enlace está en la publicación en la parte superior. – posfan12

Respuesta

4

Para simplemente corregir la sintaxis, esta respuesta es tan buena como cualquiera. Sin embargo, para solucionar el algoritmo, Leon tiene más información allí.


Me parece que el código es incorrecto teniendo dos demasiados conjuntos de corchetes. maze se declara e inicializa como una matriz bidimensional de int. No hay razón por la que debería tener más que eso. ¿Tal vez el resultado de un generador de código mal informado o defectuoso?

Simplemente elimine los corchetes cuadrados anteriores, vacíos [] (o ][) desde los accesos a la matriz y se establecerá.

3

Mi conjetura es que falta un código. Quitar el extra [] hace que el código se compile pero no genera un laberinto, pero está atorado en un bucle infinito

Creo que [] [d] [] [d] se supone que es laberinto [x + dx [d ]] [y + dy [d]].

Está claro que se supone que d indexa las matrices dx y dy, que son desplazamientos en los vecinos de la celda actual, como siempre se itera 4 veces. También todo[todonum++] = ((x + dx[d]) << Constants.QUEUED) | (y + dy[d]); indexa la matriz de laberintos usando dx [d] y dy [y] como desplazamientos a los vecinos.

No estoy seguro de si esta es la mejor manera que tú, ya que cuando x = 0 y dx offset es -1 tendrás y OutOfBoundsException. Es posible que deba manejar esos casos de manera explícita.

+0

mierda. No hay forma de que pueda depurar esto sin el compilador. Parte de la razón por la que estaba tratando de convertirlo a JavaScript. – posfan12

+0

Usar http://www.eclipse.org/downloads/ es realmente bueno y GRATIS – Leon

+0

Al mirar el historial de la página de Wikipedia, parece que solía haber otras versiones que se modificaron con el tiempo. Pero se eliminaron cuando la página se movió a Wikimedia Commons. – posfan12

0

OK, aquí está la versión de JavaScript:

/* 
* 3 June 2003, [[:en:User:Cyp]]: 
*  Maze, generated by my algorithm 
* 24 October 2006, [[:en:User:quin]]: 
*  Source edited for clarity 
* 25 January 2009, [[:en:User:DebateG]]: 
*  Source edited again for clarity and reusability 
* 1 June 2009, [[:en:User:Nandhp]]: 
*  Source edited to produce SVG file when run from the command-line 
* 7 January, 2011 [[:en:User:SharkD]]: 
*  Source converted to JavaScript 
* 
* This program was originally written by [[:en:User:Cyp]], who 
* attached it to the image description page for an image generated by 
* it on en.wikipedia. The image was licensed under CC-BY-SA-3.0/GFDL. 
*/ 

/* Recreate a math function that exists in Java but not JavaScript. */ 
Math.nextInt = function (number) { 
return Math.floor(Math.random() * number) 
} 

/* Recreate a system function that exists in Java but not JavaScript. 
* Uncomment either WScript.Echo() or alert() depending on whether you are 
* running the script from the Windows command-line or a Web page. 
*/ 
function println(string) 
{ 
// if inside Windows Scripting Host 
// WScript.Echo(string) 
// if inside a Web page 
alert(string) 
} 

/* Define the bit masks */ 
var Constants = 
{ 
WALL_ABOVE : 1, 
WALL_BELOW : 2, 
WALL_LEFT : 4, 
WALL_RIGHT : 8, 
QUEUED : 16, 
IN_MAZE : 32 
} 

/* Construct a Maze with specified width, height, and cell_width */ 
function Maze(width, height, cell_width) { 
if (width) 
    this.width = width; 
else 
    this.width = 20; 
if (height) 
    this.height = height; 
else 
    this.height = 20; 
if (cell_width) 
    this.cell_width = cell_width; 
else 
    this.cell_width = 10; 
this.maze = [] 

/* The maze generation algorithm. */ 
this.createMaze = function() { 
    var width = this.width 
    var height = this.height 
    var maze = this.maze 
    var x, y, n, d; 
    var dx = [ 0, 0, -1, 1 ]; 
    var dy = [ -1, 1, 0, 0 ]; 

    var todo = new Array(height * width); 
    var todonum = 0; 

    /* We want to create a maze on a grid. */ 
    /* We start with a grid full of walls. */ 
    for (x = 0; x < width; ++x) { 
    maze[x] = [] 
    for (y = 0; y < height; ++y) { 
    if (x == 0 || x == width - 1 || y == 0 || y == height - 1) { 
    maze[x][y] = Constants.IN_MAZE; 
    } 
    else { 
    maze[x][y] = 63; 
    } 
    } 
    } 

    /* Select any square of the grid, to start with. */ 
    x = 1 + Math.nextInt(width - 2); 
    y = 1 + Math.nextInt(height - 2); 

    /* Mark this square as connected to the maze. */ 
    maze[x][y] &= ~48; 

    /* Remember the surrounding squares, as we will */ 
    for (d = 0; d < 4; ++d) { 
    if ((maze[x + dx[d]][y + dy[d]] & Constants.QUEUED) != 0) { 
    /* want to connect them to the maze. */    
    todo[todonum++] = ((x + dx[d]) << Constants.QUEUED) | (y + dy[d]); 
    maze[x + dx[d]][y + dy[d]] &= ~Constants.QUEUED; 
    } 
    } 

    /* We won't be finished until all is connected. */ 
    while (todonum > 0) { 
    /* We select one of the squares next to the maze. */ 
    n = Math.nextInt(todonum); 
    x = todo[n] >> 16; /* the top 2 bytes of the data */ 
    y = todo[n] & 65535; /* the bottom 2 bytes of the data */ 

    /* We will connect it, so remove it from the queue. */ 
    todo[n] = todo[--todonum]; 

    /* Select a direction, which leads to the maze. */ 
    do { 
    d = Math.nextInt(4); 
    } 
    while ((maze[x + dx[d]][y + dy[d]] & Constants.IN_MAZE) != 0); 

    /* Connect this square to the maze. */ 
    maze[x][y] &= ~((1 << d) | Constants.IN_MAZE); 
    maze[x + dx[d]][y + dy[d]] &= ~(1 << (d^1)); 

    /* Remember the surrounding squares, which aren't */ 
    for (d = 0; d < 4; ++d) { 
    if ((maze[x + dx[d]][y + dy[d]] & Constants.QUEUED) != 0) {  
    /* connected to the maze, and aren't yet queued to be. */ 
    todo[todonum++] = ((x + dx[d]) << Constants.QUEUED) | (y + dy[d]); 
    maze[x + dx[d]][y + dy[d]] &= ~Constants.QUEUED; 
    } 
    } 
    /* Repeat until finished. */ 
    } 

    /* Add an entrance and exit. */ 
    maze[1][1] &= ~Constants.WALL_ABOVE; 
    maze[width - 2][height - 2] &= ~Constants.WALL_BELOW; 
} 
/* Called to write the maze to an SVG file. */ 
this.printSVG = function() { 
    var outstring = "<svg width=\"" + (width * cell_width) + "\" height=\"" + (height*cell_width) + "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n" 
    + " <g stroke=\"black\" stroke-width=\"1\" stroke-linecap=\"round\">\n" 
    + this.drawMaze() 
    + " </g>\n</svg>\n"; 
    println(outstring) 
} 
/* Main maze-drawing loop. */ 
this.drawMaze = function() { 
    var x, y; 
    var width = this.width; 
    var height = this.height; 
    var cell_width = this.cell_width 
    var outstring = "" 
    for (x = 1; x < width - 1; ++x) { 
    for (y = 1; y < height - 1; ++y) { 
    if ((this.maze[x][y] & Constants.WALL_ABOVE) != 0) 
    outstring += this.drawLine(  x * cell_width,  y * cell_width, (x + 1) * cell_width,  y * cell_width); 
    if ((this.maze[x][y] & Constants.WALL_BELOW) != 0) 
    outstring += this.drawLine(  x * cell_width, (y + 1) * cell_width, (x + 1) * cell_width, (y + 1) * cell_width); 
    if ((this.maze[x][y] & Constants.WALL_LEFT) != 0) 
    outstring += this.drawLine(  x * cell_width,  y * cell_width, x * cell_width, (y + 1) * cell_width); 
    if ((this.maze[x][y] & Constants.WALL_RIGHT) != 0) 
    outstring += this.drawLine((x + 1) * cell_width,  y * cell_width, (x + 1) * cell_width, (y + 1) * cell_width); 
    } 
    } 
    return outstring 
} 
/* Draw a line, either in the SVG file or on the screen. */ 
this.drawLine = function (x1, y1, x2, y2) { 
    return " <line x1=\"" + x1 + "\" y1=\"" + y1 + "\" x2=\"" + x2 + "\" y2=\"" + y2 + "\" />\n"; 
} 
} 



/* Initialization method that will be called when the program is 
* run from the command-line. Maze will be written as SVG file. */ 
function main(args) { 
var m = new Maze(); 
m.createMaze(); 
m.printSVG(); 
} 

/* execute the program */ 
main() 

siguiente paso consiste en convertirlo en un laberinto en 3D de seis ejes y convertir a Lua, que es mi plataforma de destino real. :)

PD - Estoy tratando de votar sobre las respuestas, pero me dice que tengo que iniciar sesión o registrarme, wtf?

+0

¿genera un laberinto que quieres? – Leon

+0

Creo que necesita registrarse para votar, no toma mucho tiempo – Leon

+0

¿No estoy registrado ya? – posfan12