随机生成一个迷宫并探索一条路径的JAVA实现
2018-02-08 10:16
507 查看
问题:实现一个随机迷宫,可以想象是一个二维数组,入口在左上角,出口在右下角。
要求:
1、不能超过边界
2、路线不能重复,也就是说每个点只能经过一次
3、走出迷宫的路线是随机生成的,每次生成的路线都应该不一样
4、迷宫的大小可以任意指定,也就是说明二维数组的大小可以随意变化
5、最终生成的迷宫需要打印出来
迷宫实体类MazePoint:
迷宫类Maze:
测试的main类:
运行截图:
代码下载链接:完整代码下载
要求:
1、不能超过边界
2、路线不能重复,也就是说每个点只能经过一次
3、走出迷宫的路线是随机生成的,每次生成的路线都应该不一样
4、迷宫的大小可以任意指定,也就是说明二维数组的大小可以随意变化
5、最终生成的迷宫需要打印出来
迷宫实体类MazePoint:
public class MazePoint { private boolean isVisited = false; private boolean wallUp = true; private boolean wallRight = true; private boolean wallDown = true; private boolean wallLeft = true; public boolean isVisited() { return isVisited; } public void setVisited(boolean isVisited) { this.isVisited = isVisited; } public boolean isWallUp() { return wallUp; } public void setWallUp(boolean wallUp) { this.wallUp = wallUp; } public boolean isWallRight() { return wallRight; } public void setWallRight(boolean wallRight) { this.wallRight = wallRight; } public boolean isWallDown() { return wallDown; } public void setWallDown(boolean wallDown) { this.wallDown = wallDown; } public boolean isWallLeft() { return wallLeft; } public void setWallLeft(boolean wallLeft) { this.wallLeft = wallLeft; } }
迷宫类Maze:
import java.util.Random; import java.util.Scanner; import java.util.Stack; public class Maze { private final static int dirUp = 0; private final static int dirRight = 1; private final static int dirDown = 2; private final static int dirLeft = 3; private final static int gridWall = 1; private final static int gridEmpty = 0; private final static int gridBlind = -1; private final static int gridPath = 2; private int width; private int height; private MazePoint[][] matrix; private int[][] maze; /* * 构造一个迷宫,初始化迷宫的宽度和高度,同时初始化包含MazePoint的点阵 */ public Maze(int height, int width) { this.width = width; this.height = height; this.matrix = new MazePoint[height][width]; for (int i=0; i<height; i++) for (int j=0; j<width; j++) matrix[i][j] = new MazePoint(); this.maze = new int[2*height+1][2*width+1]; //构建宽为2*height+1、长为2*width+1的迷宫 } /* * 检查目标点的上下左右的邻居是否可以被访问,如果目标点超出界限则视为已被访问 */ public boolean isNeighborOK(int x, int y, int dir) { boolean isNeighborVisited = false; switch ( dir ) { case dirUp: if ( x <= 0 ) isNeighborVisited = true; //越界视为已被访问 else isNeighborVisited = matrix[x-1][y].isVisited(); break; case dirRight: if ( y >= width - 1 ) isNeighborVisited = true; else isNeighborVisited = matrix[x][y+1].isVisited(); break; case dirDown: if ( x >= height - 1 ) isNeighborVisited = true; else isNeighborVisited = matrix[x+1][y].isVisited(); break; case dirLeft: if ( y <= 0 ) isNeighborVisited = true; else isNeighborVisited = matrix[x][y-1].isVisited(); break; } return !isNeighborVisited; //若点未被访问过(isNeighborVisited为false),则返回值为true,表示有邻居可以被访问 } /* * 检查目标点的上下左右是否至少有一个可以访问 */ public boolean isNeighborOK(int x, int y) { return (this.isNeighborOK(x, y, dirUp) || this.isNeighborOK(x, y, dirRight) || this.isNeighborOK(x, y, dirDown) || this.isNeighborOK(x, y, dirLeft)); } /* * 获得一个可以被访问的方向 */ public int getRandomDir(int x, int y) { int dir = -1; Random rand = new Random(); if ( isNeighborOK(x, y) ) { do { dir = rand.nextInt(4); } while ( !isNeighborOK(x, y, dir) ); //(x,y)的dir方向不可被访问,重新选择方向 } return dir; } /* * 将相邻可以访问的点设置为通路 */ public void pushWall(int x, int y, int dir) { switch ( dir ) { case dirUp: matrix[x][y].setWallUp(false); matrix[x-1][y].setWallDown(false); //将该点与其上面相邻的点设置通路 break; case dirRight: matrix[x][y].setWallRight(false); matrix[x][y+1].setWallLeft(false); //将该点与其右面相邻的点设置通路 break; case dirDown: matrix[x][y].setWallDown(false); matrix[x+1][y].setWallUp(false); //将该点与其下面相邻的点设置通路 break; case dirLeft: matrix[x][y].setWallLeft(false); matrix[x][y-1].setWallRight(false); //将该点与其左面相邻的点设置通路 break; } } /* * 深度优先遍历 */ public void traversal() { int x = 0; int y = 0; Stack<Integer> stackX = new Stack<Integer>(); Stack<Integer> stackY = new Stack<Integer>(); do { MazePoint p = matrix[x][y]; if ( !p.isVisited() ) { p.setVisited(true); } if ( isNeighborOK(x, y) ) { int dir = this.getRandomDir(x, y); //获得一个随机可访问的方向 this.pushWall(x, y, dir); //设置通路 stackX.add(x); //保存坐标信息 stackY.add(y); //保存坐标信息 switch ( dir ) { case dirUp: x--; break; case dirRight: y++; break; case dirDown: x++; break; case dirLeft: y--; break; } } else { x = stackX.pop(); y = stackY.pop(); } } while ( !stackX.isEmpty() ); } /* * 根据MazePoint点阵右侧和下侧的墙构建迷宫 */ public void create() { // } /* * 打印迷宫 */ public void print() { for (int i=0; i<2*height+1; i++) { for (int j=0; j<2*width+1; j++) if ( maze[i][j] == gridWall ) System.out.print("□"); else if ( maze[i][j] == gridPath ) System.out.print("."); adf6 //通路标记为".",其他设置为"□" else System.out.print("□"); System.out.println(); } } /* * 在迷宫数组中去获得一个访问的方向 */ public int getBreakOutDir(int x, int y) { int dir = -1; if ( maze[x][y+1] == 0 ) dir = dirRight; else if ( maze[x+1][y] == 0 ) dir = dirDown; else if ( maze[x][y-1] == 0 ) dir = dirLeft; else if ( maze[x-1][y] == 0 ) dir = dirUp; return dir; } /* * 找到从点 (1, 1) 到点 (2*height-1, 2*width-1) 的一条路径 */ public void findPath() { int x = 1; int y = 1; Stack<Integer> stackX = new Stack<Integer>(); Stack<Integer> stackY = new Stack<Integer>(); do { int dir = this.getBreakOutDir(x, y); if ( dir == -1 ) { maze[x][y] = gridBlind; //方向不存在的设置为盲点 x = stackX.pop(); y = stackY.pop(); } else { maze[x][y] = gridPath; stackX.add(x); stackY.add(y); //保存通路点坐标信息 switch ( dir ) { case dirUp: x--; break; case dirRight: y++; break; case dirDown: x++; break; case dirLeft: y--; break; } } } while ( !(x == 2*height-1 && y == 2*width-1) ); maze[x][y] = gridPath; } /* * 清除迷宫中的路径 */ public void reset() { for (int i=0; i<2*height+1; i++) for (int j=0; j<2*width+1; j++) if ( maze[i][j] != gridWall ) maze[i][j] = gridEmpty; } }
测试的main类:
public static void main(String[] args) { // TODO Auto-generated method stub Scanner scanner = new Scanner(System.in); System.out.println("请输入n:迷宫的行数为2n+1(包括上下两道墙)"); int row = scanner.nextInt(); System.out.println("请输入m:迷宫的列数为2m+1"); int col = scanner.nextInt(); Maze maze = new Maze(row, col); maze.traversal(); //遍历 maze.create(); //构建迷宫 maze.findPath(); //找到路径 maze.print(); //打印迷宫 maze.reset(); //清除迷宫 }
运行截图:
代码下载链接:完整代码下载
相关文章推荐
- 生成前N个整数的一个随机置换java实现
- 队列实现求迷宫最短路径(包含每一步的尝试状态,迷宫随机生成)
- C++控制台实现随机生成路径迷宫游戏
- (学习java)写一个完整的程序,实现随机生成20个元素的链表,快速查找中间结点的值并显示
- java实现一个在窗口显示一个随机生成的号码
- java图的深度优先遍历实现随机生成迷宫
- java随机验证码生成实现实例代码
- 分享一个C#实现的迷宫生成程序,继续演示LINQ语法在C#中的运用
- 【小程序】JAVA实现从10~50中随机生成50个数,统计出现的数字及次数,输出出现最多的次数及对应的数字,按数字升序排列。
- 转:java写一个方法实现统计一条英文语句忠每个单词的个数
- 单源最短路径、最小生成树及堆的Java实现
- java 实现生成随机大整数
- java生成随机密码的一个方法
- 中软面试(一):java写一个随机生成四位数的程序 每位数字不重复
- Java实现产生一个随机验证码
- 大学常见算法的java实现及思考-小老鼠走迷宫(找出一条可行路径即可)
- Java实现页面验证功能随机生成图片
- 计算任意一个图生成树的个数——Kirchhoff 的Matrix Tree 方法Java实现
- 一个矩阵存储的迷宫地图,可行走的点是0,不可走的点是1,程序输出一条可以行走的路径
- java生成随机密码的一个方法