令人困惑的 Java 语法

发布于 2024-10-10 18:22:39 字数 6794 浏览 0 评论 0原文

我正在尝试将以下代码(来自 Wikipedia)从 Java 转换为 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
 *
 * 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);
    }
}

无论如何,当我遇到一些我不明白的问题时,我进展得相当快:

 /* 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;
     }
 }

我不明白的是为什么“迷宫”参数后面有四组括号而不是只有两组,因为“ maze”是一个二维数组,而不是一个四维数组。

我确信这是有充分理由的。问题是,我就是不明白。

谢谢!

I'm trying to convert the following code (from Wikipedia) from Java to 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
 *
 * 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);
    }
}

Anyway, I was chugging along fairly quickly when I came to a bit that I just don't understand:

 /* 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;
     }
 }

What I don't get is why there are four sets of brackets following the "maze" parameter instead of just two, since "maze" is a two dimensional array, not a four dimensional array.

I'm sure there's a good reason for this. Problem is, I just don't get it.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

亚希 2024-10-17 18:22:39

为了简单地纠正语法,这个答案和任何答案一样好。然而,为了修复算法,Leon 对此有更多见解。


在我看来,代码是错误的,有两组太多的方括号。 maze 被声明并初始化为二维 int 数组。没有理由它应该有更多。也许是错误信息或有错误的代码生成器的结果?

只需从数组访问中删除前面的空方括号 [] (或 ][)即可设置。

To simply correct the syntax, this answer is as good as any. However to fix the algorithm, Leon's has more insight there.


Looks to me like the code is wrong having two too many sets of square brackets. maze is declared and initialized as a 2-dimensional int array. There's no reason it should have more than that. Perhaps the result of a misinformed or buggy code generator?

Just remove the preceding, empty square brackets [] (or ][) from the array accesses and you'll be set.

撩人痒 2024-10-17 18:22:39

我有根据的猜测是缺少一些代码。删除额外的 [] 会使代码编译,但它不会生成迷宫,而是陷入无限循环

我认为 [][d][][d] 应该是迷宫[x+dx[d]][y +dy[d]]。

很明显,d 应该索引到 dx 和 dy 数组中,它们是当前单元格的邻居的偏移量,因为它总是迭代 4 次。另外todo[todonum++] = ((x + dx[d]) << Constants.QUEUED) | (y + dy[d]); 使用 dx[d] 和 dy[y] 作为到邻居的偏移量来索引迷宫数组。

我不确定这是否是最好的方法,因为当 x=0 且 dx 偏移量为 -1 时,您将遇到 OutOfBoundsException。您可能必须明确处理这些情况。

My educated guess would be that there is some code missing. Removing the extra [] makes the code compile but it does not generate a maze but is stuck in an infinite loop

I think [][d][][d] are supposed to be maze[x+dx[d]][y+dy[d]].

It is clear that d is supposed to index into dx and dy arrays, which are offsets into the neighbours of the current cell, as is is always iterated 4 times. Also todo[todonum++] = ((x + dx[d]) << Constants.QUEUED) | (y + dy[d]); indexes the maze array using dx[d] and dy[y] as offsets to the neighbours.

I am not sure whether this is the best way thou, as when x=0 and dx offset is -1 you will have and OutOfBoundsException. You may have to handle those cases explicitly.

过气美图社 2024-10-17 18:22:39

好的,这是 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()

下一步是将其变成六轴 3D 迷宫并转换为 Lua,这是我的实际目标平台。 :)

PS - 我正在尝试对答案进行投票,但它告诉我我需要登录或注册,wtf?

OK, here's the JavaScript version:

/*
 * 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()

Next step is to turn it into a six axis 3D maze and convert to Lua, which is my actual target platform. :)

PS - I'm trying to vote on answers, but it's telling me I need to login or register, wtf?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文