最近迷上了迷宫,研究了一下算法,发出来给大家玩玩!
maze.js
闲着无聊,突然想玩迷宫了,奈何找不到现有的迷宫网站,既然找不到,那就自己做一个吧,主要还是觉得迷宫的算法好玩,研究一下;
仓库地址
https://gitee.com/xiwangdalu/mazejs
效果图
在线预览
- DOM渲染:index.html
- Canvas渲染:canvas.html
额外补充
因为这个算法我研究出来了,正好我准备给我的游戏服上一个这个迷宫游戏,因此提供一个Java版本代码
坐标点类
package com.xiwangdalu.mazegenerator.maze;
/**
* 点类,方便调用
*/
public class Point {
private int x;
private int y;
/**
* 初始化
*
* @param x X值
* @param y Y值
*/
public Point(int x, int y) {
this.x = x;
this.y = y;
}
/**
* 获取Y值
*
* @return
*/
public int getY() {
return y;
}
/**
* 设置X
*
* @param x
*/
public void setX(int x) {
this.x = x;
}
/**
* 设置Y
*
* @param y
*/
public void setY(int y) {
this.y = y;
}
/**
* 获取X值
*
* @return
*/
public int getX() {
return x;
}
}
生成器类
package com.xiwangdalu.mazegenerator.maze;
import java.util.ArrayList;
import java.util.List;
/**
* 迷宫路径生成器
*/
public class Generator {
private final int rowNumber;
private final int colNumber;
private final int mapWidth;
private final int mapHeight;
private final List<Point> rules = new ArrayList<>();
private List<Point> paths = new ArrayList<>();
List<List<Integer>> grids = new ArrayList<>();
public Generator(int rowNumber, int colNumber) {
this.rowNumber = rowNumber;
this.colNumber = colNumber;
// 四周点规格
rules.add(new Point(0, -2));
rules.add(new Point(0, 2));
rules.add(new Point(-2, 0));
rules.add(new Point(2, 0));
// 地图大小
this.mapWidth = colNumber * 2 + 1;
this.mapHeight = rowNumber * 2 + 1;
// 生成网格
this.initGrid();
// 绘制路径
this.drawAllRoad();
}
/**
* 绘制所有路径
*/
private void drawAllRoad() {
// 起点位置
Point startXY = new Point(1, 0);
// 终点位置
Point endXY = new Point(this.mapHeight - 1, this.mapWidth - 2);
// 打通起点和终点
this.updateGrid(startXY, 0);
this.updateGrid(endXY, 0);
// 绘制主路
Point mainXY = new Point(1, 1);
this.drawRoad(mainXY);
// 主线走完了,把旧的路线重新走一遍(填充剩余区域)
for (int i = 0; i < paths.size(); i++) {
Point point = paths.get(i);
drawRoad(point);
}
}
/**
* 绘制单条路
*
* @param startXY 点数据
*/
private void drawRoad(Point startXY) {
// 更新起点值为路
this.updateGrid(startXY, 0);
// 获取点
List<Point> points = this.findNextPoint(startXY);
// 如果有可选点
if (points.size() > 0) {
Point point = points.get((int) Math.floor(Math.random() * points.size()));
// 中间路
Point gutter = new Point(startXY.getX(), startXY.getY());
if (startXY.getX() != point.getX()) gutter.setX(Math.min(startXY.getX(), point.getX()) + 1);
if (startXY.getY() != point.getY()) gutter.setY(Math.min(startXY.getY(), point.getY()) + 1);
// 打通路
this.updateGrid(gutter, 0);
// 保存路径
paths.add(point);
drawRoad(point);
}
}
/**
* 寻找四个方向可用的路
*
* @param startXY 起点数据
* @return
*/
private List<Point> findNextPoint(Point startXY) {
List<Point> points = new ArrayList<>();
for (Point point : rules) {
int newX = startXY.getX() + point.getX();
int newY = startXY.getY() + point.getY();
if (newX > 0 && newX < mapHeight - 1 && newY > 0 && newY < mapWidth - 1) {
boolean isRoad = getGrids().get(newX).get(newY) == 0;
if (!isRoad) {
points.add(new Point(newX, newY));
}
}
}
return points;
}
/**
* 获取规则配置
*
* @return 规则
*/
public List<Point> getRules() {
return rules;
}
/**
* 更新网格数据
*
* @param point 点
* @param value 新值
*/
private void updateGrid(Point point, int value) {
List<Integer> row = this.grids.get(point.getX());
row.set(point.getY(), value);
this.grids.set(point.getX(), row);
}
/**
* 初始化网格数据
*/
private void initGrid() {
for (int i = 0; i < mapHeight; i++) {
List<Integer> row = new ArrayList<>();
for (int j = 0; j < mapWidth; j++) {
row.add(1);
}
this.grids.add(row);
}
}
/**
* 获取行数
*
* @return 行数
*/
public int getRowNumber() {
return rowNumber;
}
/**
* 获取列数
*
* @return 列
*/
public int getColNumber() {
return colNumber;
}
/**
* 获取网格数据
*
* @return 网格
*/
public List<List<Integer>> getGrids() {
return grids;
}
}
调用示例
package com.xiwangdalu.mazegenerator;
import com.xiwangdalu.mazegenerator.maze.Generator;
import java.util.List;
public class Debug {
public static void main(String[] args) {
Generator maze = new Generator(10, 10);
for (List<Integer> row : maze.getGrids()) {
System.out.println(row.toString());
}
}
}