📄 maze.java
字号:
package myGame.main;
import java.util.*;
import javax.microedition.m3g.*;
// This class creates the maze
class Maze {
public static byte MAX_SIZE = 60; // 迷宫的最大长度
private final float mazeSideLength, mazeHeight;// 迷宫的尺寸:边长和高度
private int startX = -1, endX = -1;// 两个变量用来保存迷宫的起点和终点位置
private long[] maze;// 迷宫数组每行的数据保存在长整型的各个bit位中
private float mazeOrigin, spaceBetweenPlanes;
Maze(byte corridorCount, float mazeSideLength, float mazeHeight) {
if (corridorCount > MAX_SIZE) {
// 如歌走廊数目大于迷宫大小限制,则抛出异常,注意根据(31*2)+1=63<64来确定这个限制
throw new IllegalArgumentException("Maze too big");
}
this.mazeSideLength = mazeSideLength;// 获取边长变量mazeSideLength
this.mazeHeight = mazeHeight;// 获取迷宫高度变量mazeHeight
createNew(corridorCount);// 根据走廊数量随机生成一个新的迷宫
}
// creates a plane located at the start of the maze
Plane createStartMark() {
Transform markTransform = new Transform();// 构建一个Transform对象
markTransform.postTranslate(mazeOrigin + startX * spaceBetweenPlanes,
mazeHeight / 2, mazeOrigin);
markTransform.postScale(3 * spaceBetweenPlanes / 4, 1f, 1f);// 设置缩放比例
return new Plane(markTransform, 1f);// 用Transform对象构造Plane对象
}
// creates a plane located at the end of the maze
Plane createEndMark() {
Transform markTransform = new Transform();// 构建一个Transform对象
markTransform.postTranslate(mazeOrigin + endX * spaceBetweenPlanes,
mazeHeight / 2, -mazeOrigin);
markTransform.postScale(3 * spaceBetweenPlanes / 4, 1f, 1f);// 设置缩放比例
markTransform.postRotate(180f, 0f, 1f, 0f);// 绕Y轴旋转180度
return new Plane(markTransform, 1f);// 用Transform对象构造Plane对象
}
// Calculate the start X coordinate
float findStartLocationX() {
return mazeOrigin + (startX + 0.5f) * spaceBetweenPlanes;
}
// Calculate the start Z coordinate
float findStartLocationZ() {
return mazeOrigin + spaceBetweenPlanes;
}
// checks if the location (x, z) is at the end given certain tolerance
boolean isAtTheEnd(float x, float z, float tolerance) {
// just use linear distances
return Math.abs(x - (mazeOrigin + endX * spaceBetweenPlanes)) < tolerance
&& Math.abs(z + mazeOrigin) < tolerance;
}
// creates the horizontal and vertical planes and puts
// them in an enumeration
Enumeration createPlanes() {
// Space between walls
spaceBetweenPlanes = mazeSideLength / (maze.length - 1);
mazeOrigin = -mazeSideLength / 2;
Vector allPlanes = new Vector();// 为墙壁创建一个适量数组
for (int i = 0; i < maze.length; i++) {// 创建水平方向的墙壁,它们都是Plane对象
int startX = -1;
for (int j = 0; j < maze.length; j++) {
long shift = (0x1L << j);
if ((maze[i] & shift) == shift && startX == -1) {
startX = j;
continue;
}
if ((((maze[i] & shift) == 0) || (j == (maze.length - 1)))
&& (startX >= 0)) {
int steps = j - startX;
// Don't create walls of side 1 since they
// will be created on the other direction
if (steps == 1) {// 如果step=1则跳过,因为那代表垂直方向的墙壁
startX = -1;
continue;
}
// compensate that the last item is always 1
if (j == (maze.length - 1)) {
steps++;
}
Transform planeTransform = new Transform();
// Divided by 2 since the original square is of side 2;
float wallWidth = (spaceBetweenPlanes * (steps - 1) / 2);
// System.out.println((int)wallWidth);
// Move to the correct position
planeTransform.postTranslate(mazeOrigin
+ spaceBetweenPlanes * startX + wallWidth,
mazeHeight, mazeOrigin + spaceBetweenPlanes * i);
// give the actual size
planeTransform.postScale(wallWidth, mazeHeight, 1f);
allPlanes.addElement(new Plane(planeTransform, 1f));
startX = -1;
}
}
}
// System.out.println("begin");
for (int i = 0; i < maze.length; i++) {
int startY = -1;
long shift = (0x1L << i);
for (int j = 0; j < maze.length; j++) {
if ((maze[j] & shift) == shift && startY == -1) {
startY = j;
continue;
}
if ((((maze[j] & shift) == 0) || (j == (maze.length - 1)))
&& (startY >= 0)) {
int steps = j - startY;
if (steps == 1) {
startY = -1;
continue;
}
if (j == (maze.length - 1)) {
steps++;
}
Transform planeTransform = new Transform();
// Divided by 2 since the original square is of side 2;
float wallWidth = (spaceBetweenPlanes * (steps - 1) / 2);
// translate to the correct position
planeTransform.postTranslate(mazeOrigin
+ spaceBetweenPlanes * i, mazeHeight, mazeOrigin
+ spaceBetweenPlanes * startY + wallWidth);
// rotate 90 degrees since this is a vertical wall
planeTransform.postRotate(90f, 0f, 1f, 0f);
// 缩放
planeTransform.postScale(wallWidth, mazeHeight, 1f);
allPlanes.addElement(new Plane(planeTransform, 1f));
startY = -1;
}
}
}
// System.out.println(allPlanes.size());
return allPlanes.elements();
}
// 生成随机迷宫
private void createNew(byte mazeSize) {
Random random = new Random();// Random对象用来产生随机数
int totalSize = mazeSize * 2 + 1;// 总的数组大小,mazeSize为走廊数目
maze = new long[totalSize];// 长整型数组,每个树的bit位用来表示迷宫数组的值
int backtrack[] = new int[mazeSize * mazeSize];// 一个类似栈的数组,用来遍历迷宫
int backtrackIndex = 0;// 当前索引值
for (int i = 0; i < maze.length; i++) {
maze[i] = -1;// 初始化数组(将所有的64个bit位设置为1)
}
int x = 1;
int y = 1;
int UP = 0;// 定义方向常量,0表示向上
int DOWN = 1;// 定义方向常量,1表示向上
int LEFT = 2;// 定义方向常量,2表示向上
int RIGHT = 3;// 定义方向常量,3表示向上
while (true) {
// System.out.println("("+x+","+y+")");
maze[x] &= ~(0x1 << y);
int currentBacktrackIndex = backtrackIndex;
int directions[] = new int[4];// 四个方向
int availableSpaces = 0;
// 判断是否可以向上运行
if (y - 2 > 0 && (maze[x] & (0x1 << (y - 2))) != 0) {
directions[availableSpaces++] = UP;
}
// 判断是否可以向下运行
if (y + 2 < totalSize && (maze[x] & (0x1 << (y + 2))) != 0) {
directions[availableSpaces++] = DOWN;
}
// 判断是否可以向左运行
if (x + 2 < totalSize && (maze[x + 2] & (0x1 << y)) != 0) {
directions[availableSpaces++] = LEFT;
}
// 判断是否可以向右运行
if (x - 2 > 0 && (maze[x - 2] & (0x1 << y)) != 0) {
directions[availableSpaces++] = RIGHT;
}
if (availableSpaces > 0) {
int chosenDirection = directions[(random.nextInt() >>> 1)
% availableSpaces];// 随机决定一个方向,并改变迷宫数组的值
backtrack[backtrackIndex++] = chosenDirection;
if (chosenDirection == UP) {// 选择的方向向上
maze[x] &= ~(0x1 << (y - 1));
y -= 2;
}
if (chosenDirection == DOWN) {// 选择的方向向下
maze[x] &= ~(0x1 << (y + 1));
y += 2;
}
if (chosenDirection == LEFT) {// 选择的方向向左
maze[x + 1] &= ~(0x1 << y);
x += 2;
}
if (chosenDirection == RIGHT) {// 选择的方向向右
maze[x - 1] &= ~(0x1 << y);
x -= 2;
}
} else {
if (backtrackIndex == 0) {// 计算结果
break;
}
backtrackIndex--;// 如果都无法运动则后退
if (backtrack[backtrackIndex] == UP) {
y += 2;
} else if (backtrack[backtrackIndex] == DOWN) {
y -= 2;
} else if (backtrack[backtrackIndex] == LEFT) {
x -= 2;
} else if (backtrack[backtrackIndex] == RIGHT) {
x += 2;
}
}
}
while (true) {// 寻找起点和终点
int pos = (random.nextInt() >>> 1) % totalSize;// 随机确定一个位置
if (startX < 0 && (maze[1] & (0x1 << pos)) == 0) {// 如果起点属于某个连通路径
startX = pos;
maze[0] &= ~(0x1 << pos);// 改变maze[0]的值设置起点
}
if (endX < 0 && (maze[maze.length - 2] & (0x1 << pos)) == 0) {// 如果终点属于某个连通路径
endX = pos;
maze[maze.length - 1] &= ~(0x1 << pos);// 改变maze数组最后一行的值
}
if (endX >= 0 && startX >= 0) {
break;
}
}
for (int i = 0; i < maze.length; i++) {
System.out.println(maze[i]);
}
System.out.println(startX);
System.out.println(endX);
for (int i = 0; i < maze.length; i++) {
String value = Integer.toBinaryString(Integer.parseInt(Long
.toString(maze[i])));
for (int j = 0; j < value.length(); j++)
System.out.print(value.charAt(j));
System.out.println();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -