最近迷上了迷宫,研究了一下算法,发出来给大家玩玩!

maze.js

闲着无聊,突然想玩迷宫了,奈何找不到现有的迷宫网站,既然找不到,那就自己做一个吧,主要还是觉得迷宫的算法好玩,研究一下;

仓库地址

https://gitee.com/xiwangdalu/mazejs

效果图

view.png

在线预览

额外补充

因为这个算法我研究出来了,正好我准备给我的游戏服上一个这个迷宫游戏,因此提供一个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());
        }
    }
}