迷宫

迷宫游戏

深度优先遍历(DFS)

顾名思义DFS就是从一个节点出发直到不能访问然后回转到上一层 也就是所说的“回溯+递归”
该方法我学习了老师PPT上的内容,可以这样理解:
(1)访问顶点v

在这里插入图片描述
(2)从v的未被访问的邻接点中选取一个顶点w,重复第一步,如果没有未被访问的邻接点,回溯至上一顶点
(3)重复前两步,直至图中所有和v路径相通的顶点都被访问到

总的来说就是,回溯+递归

此算法参照老师PPT教学上的代码,基本可以看懂。
C++部分代码实现:

void Creat_Map01(int x_index, int y_index)
{
	int x_tmp, y_tmp;
	int tag = 0;//做标记,看当前位置的四周是否还有有效通道Road
	int rand_Direction;//随机生成四个方向
		rand_Direction = rand() % 4;//随机生成四个方向
 		if (rand_Direction == 0 && x_index >= 3 && map[x_index - 2][y_index] == Road)//向上
          	{ x_index = x_index - 2;}
  		else if (rand_Direction == 1 && x_index < count - 3 && map[x_index + 2][y_index] == Road)//向上
         	{ x_index = x_index + 2;}
  		else if (rand_Direction == 2 && y_index > 3 && map[x_index][y_index - 2] == Road)//向左
         	{ y_index = y_index - 2;}
  		else if (rand_Direction == 3 && y_index < count - 3 && map[x_index][y_index + 2] == Road)//向右
        	{ y_index = y_index + 2;}
	while (1)
	{	tag = IsHaveNeighbor(x_index, y_index);
		if (tag == 0)	
            return;
		else
		{
		    map[x_index][y_index] = Red;
		    x_tmp = x_index;
		    y_tmp = y_index;
                                 //产生四个随机方向的新坐标;
		   map[(x_tmp + x_index) / 2][(y_tmp + y_index) / 2] = Red;
		   map[x_index][y_index] = Red;
		   Creat_Map01(x_index, y_index);
		}
	}
}

A*算法

在计算机科学中,A*算法作为Dijkstra(迪杰斯特拉)算法的扩展,是一种静态路网中求解最短路径有效的直接搜索方法,因其高效性被广泛应用于寻路及图的遍历中
首先明确几个概念:

搜索区域

搜索区域可以划分为正方形格子,但不限于此,六边形,矩形,平行四边形都可以。因此他们的中心点通常称为节点,而不是方格。

路径排序

下一步怎么移动由以下公式确定:F(n)=G+H。F(n)为估价函数,G代表的是从初始位置Start沿着已生成的路径到指定待检测结点移动开销。H表示待检测结点到目标节点B的估计移动开销。

启发函数

H为启发函数,可以看作是一种试探,由于在找到唯一路径前,不确定在前面会出现什么障碍物,因此用了一种计算H的算法,具体可以根据实际情况决定。为了简化问题,H采用的是传统的曼哈顿距离,也就是横纵向走的距离之和。

开放列表

将寻路过程中待检测的结点存放于Open List中,而已检测过的结点则存放于Close List中。

以上是A* 的关键点,尤其是启发函数,如果没有启发函数,则A* 就退化成了Dijkstra算法,是运行效率重要还是找到最佳路径重要,全靠启发函数来调节,因此也被归为启发式算法。

A*算法的具体步骤

  1. 把起点加入openlist
  2. 遍历openlist,找到F值最小的节点,把它作为当前处理的节点,并把该节点加入closelist中
  3. 对该节点的8个相邻格子进行判断, 如果格子是不可抵达的或者在closelist中,则忽略它,否则如下操作:
    a. 如果相邻格子不在openlist中,把它加入,并将parent设置为该节点和计算f,g,h值
    b.如果相邻格子已在openlist中,并且新的G值比旧的G值小,则把相邻格子的parent设置为该节点,并且重新计算f值。
  4. 重复2,3步,直到终点加入了openlist中,表示找到路径;或者openlist空了,表示没有路径。

参考文章:
A算法详解
A算法入门
https://blog.csdn.net/yghlqgt/article/details/109608550

A* 算法部分,参照了网络上的大量资料,虽然原理基本可以理解,但真正实现起来还是有些困难,故参考了CSDN上的各位大神的部分代码。

public static Grid aStarSearch(Grid start, Grid end) {
		//准备两个链表,分别存储 将要选择的节点  和  已经走过的节点
		ArrayList<Grid> openlist=new ArrayList<Grid>();
		ArrayList<Grid> closelist=new ArrayList<Grid>();
		//将起点加入链表,准备开始寻路。
		openlist.add(start);
		//只要链表不为空,就重复这个寻路的过程
		while(openlist.size()>0) {
			//找到 openlist中 F值最小的那个 方格(节点)
			Grid currentgrid=findMinGrid(openlist);
			//从 openlist中删除找到的那个  F值 最小的那个节点
			openlist.remove(currentgrid);
			//将这个  F值 最小的节点,加入到  closelist 中
			closelist.add(currentgrid);
			//寻找  当前找到的这个 F值最小的节点的  邻居节点 ——上下左右,四个方向上的节点,要判断它们是否为合法可用的节点。
			List<Grid> neighbors=findNeighbors(currentgrid, openlist, closelist);
			//对合法可用的邻居节点进行初始化,并加入到  openlist中
			for(Grid grid : neighbors) {
				if(!openlist.contains(grid)) {
					grid.initGrid(currentgrid,end);
					openlist.add(grid);
				}
			}
			//邻居节点加入  openlist 后,判断openlist中,是否包含  终点节点,如果包含终点,直接返回并退出。
			for(Grid grid : openlist) {
				if((grid.x==end.x) && (grid.y==end.y)) {
					return grid;
				}
			}
		}
		return null;
	}
	//寻找邻居节点的方法,返回值为  链表  ——创建一个合理的邻居链表
	private static ArrayList<Grid> findNeighbors(Grid grid, List<Grid> openlist, List<Grid> closelist) {
		ArrayList<Grid> gridlist=new ArrayList<Grid>();
		//判断上下左右邻居节点的合理性,没问题就加入到邻居链表中。
		if(isValidGrid(grid.x, grid.y-1, openlist, closelist)) {//下
			gridlist.add(new Grid(grid.x, grid.y-1));
		}
		if(isValidGrid(grid.x, grid.y+1, openlist, closelist)) {//上
			gridlist.add(new Grid(grid.x, grid.y+1));
		}
		if(isValidGrid(grid.x-1, grid.y, openlist, closelist)) {//左
			gridlist.add(new Grid(grid.x-1, grid.y));
		}
		if(isValidGrid(grid.x+1, grid.y, openlist, closelist)) {//右
			gridlist.add(new Grid(grid.x+1, grid.y));
		}
		return gridlist;
	}
	//判断当前位置的节点是否合理
	private static boolean isValidGrid(int x, int y, List<Grid> openlist, List<Grid> closelist) {
		//当前节点是否越界,不再MAZE数组范围内了,注意二位数组的长度计算方法及含意
		//MAZE。length表示行的长度
		//MAZE[0]。length表示列的长度
		if(x<0 || x>=MAZE.length || y<0 || y>=MAZE[0].length) {
			return false;
		}
		//当前节点是否为障碍节点
		if(MAZE[x][y]==1) {
			return false;
		}
		//判断当前节点是否在 openlist中
		if(containgrid(openlist, x, y)) {
			return false;
		}
		//判断当前节点是否在 closelist中
		if(containgrid(closelist, x, y)) {
			return false;
		}
		return true;
	}
	//判断当前链表中是否包含当前的节点
	private static boolean containgrid(List<Grid> grids, int x, int y) {
		for(Grid grid : grids) {
			if((grid.x==x) && (grid.y==y)) {
				return true;
			}
		}
		return false;
	}
	//寻找当前链表中的节点F值 最小的那个节点,并返回这个节点。
	private static Grid findMinGrid(ArrayList<Grid> openlist) {
		Grid tempgrid=openlist.get(0);
		for(Grid grid : openlist) {
			if(grid.f<tempgrid.f) {
				tempgrid=grid;
			}
		}
		return tempgrid;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int b1=0,b2=0;//起始坐标
		int c1=0,c2=6;
		Grid startgrid=new Grid(b2,b1);
		System.out.println("起点坐标为:"+"("+b1+","+b2+")");
		Grid endgrid=new Grid(c2,c1);
		System.out.println("终点坐标为:"+"("+c1+","+c2+")");
		Grid resultgrid=aStarSearch(startgrid,endgrid);
		//创建回溯链表
		ArrayList<Grid> path=new ArrayList<Grid>();
		while(resultgrid!=null) {
			path.add(new Grid(resultgrid.x, resultgrid.y));
			resultgrid=resultgrid.parent;
		}
		//打印输出当前寻路路径
		int count=0;
		for(int i=0; i<MAZE.length; i++) {
			for(int j=0; j<MAZE[0].length; j++) {
				if(containgrid(path, i, j)) {
					System.out.print("走, ");
					count++;
				}
				else
				{
					System.out.print(MAZE[i][j]+ ", ");
				}
			}
			System.out.println();
		}
		System.out.println("最短路径长度为:"+count);
	}

参考链接:
https://blog.csdn.net/xgf415/article/details/75200047
https://blog.csdn.net/Dog_dream/article/details/80270398
https://mochen.blog.csdn.net/article/details/109558689
https://blog.csdn.net/little_mind/article/details/45920961
https://blog.csdn.net/weixin_46037153/article/details/107136560
https://blog.csdn.net/u010944926/article/details/20635829
https://blog.csdn.net/ws_PersonalSpace/article/details/83420458

完整代码

package MazeTwo;
/* 本类提供打开迷宫游戏的方法*/
public class Maze {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		start();
	}
	
	public static void start(){
		Figure maze=new Figure();
		maze.init();
	}
}

package MazeTwo;

/* 本类中对迷宫进行路径搜索,保存合格迷宫的相关信息(合格迷宫只有1条路径)*/
public class Path {
	//调用创建迷宫类
		CreateMaze newMaze;
		//保存迷宫路径
		boolean[] path;
		//保存合格迷宫
		Place[] maze=null;
		int entrance;
		int exit;
		private int searchPathNumber(){
			maze=newMaze.getMaze();
			int pathAll=0;
			//保存当前路径
			Place [][] path=new Place [maze.length][];
			for(int i=1;i<path.length;i++){
				path [i] = new Place [5];
			}
			//当前路径数组下标
			int pathTop=0;
			//当前位置的下一位置的可能数下标
			int [] top=new int [maze.length];
			for(int i=1;i<top.length;i++){
				top[i]=-1;
			}
			//寻找迷宫路径数
			if(maze[entrance].getWall()==0){
				pathTop++;
				top[pathTop]++;
				path[pathTop][top[pathTop]]=maze[entrance];
				while(pathTop>0){
					//判断当前位置是否为结束位置,是,保存迷宫路径,退回上一位置,否,寻找下一不重复位置
					if(path[pathTop][0]==maze[exit]){
						pathAll++;
						top[pathTop]--;
						pathTop--;
					}else if(!path[pathTop][top[0]].isSearch()){
						//寻找当前位置的下一位置的可能数
						if(path[pathTop][0].getEast()!=null&&path[pathTop][0].getEast()!=path[pathTop][0].getLast()&&!path[pathTop][0].getEast().isSearch()){
							path[pathTop][++top[pathTop]]=path[pathTop][0].getEast();
						}
						if(path[pathTop][0].getSouth()!=null&&path[pathTop][0].getSouth()!=path[pathTop][0].getLast()&&!path[pathTop][0].getSouth().isSearch()){
							path[pathTop][++top[pathTop]]=path[pathTop][0].getSouth();
						}
						if(path[pathTop][0].getWest()!=null&&path[pathTop][0].getWest()!=path[pathTop][0].getLast()&&!path[pathTop][0].getWest().isSearch()){
							path[pathTop][++top[pathTop]]=path[pathTop][0].getWest();
						}					
						if(path[pathTop][0].getNorth()!=null&&path[pathTop][0].getNorth()!=path[pathTop][0].getLast()&&!path[pathTop][0].getNorth().isSearch()){
							path[pathTop][++top[pathTop]]=path[pathTop][0].getNorth();
						}
						path[pathTop][0].setSearch(true);
					}
					//当前位置的下一位置的所有可能依次查询,无下一位置则回退到上一位置
					if(top[pathTop]==0){
						path[pathTop][0].setLast(null);
						path[pathTop][0].setSearch(false);
						top[pathTop]--;
						pathTop--;
					}else{
						pathTop++;
						top[pathTop]++;
						path[pathTop][0]=path[pathTop-1][top[pathTop-1]--];
						path[pathTop][0].setLast(path[pathTop-1][0]);
					}
				}
			}
			return pathAll;
		}
		//设置路径
		private void setPath(){
			//保存当前路径
			Place [][] path=new Place [maze.length][];
			for(int i=1;i<path.length;i++){
				path [i] = new Place [5];
			}
			//当前路径数组下标
			int pathTop=0;
			//当前位置的下一位置的可能数下标
			int [] top=new int [maze.length];
			for(int i=1;i<top.length;i++){
				top[i]=-1;
			}
			//寻找迷宫路径数
			if(maze[entrance].getWall()==0){
				pathTop++;
				top[pathTop]++;
				path[pathTop][top[pathTop]]=maze[entrance];
				while(pathTop>0){
					//判断当前位置是否为结束位置,是,保存迷宫路径,退回上一位置,否,寻找下一不重复位置
					if(path[pathTop][0]==maze[exit]){
						for(int i=1;i<=pathTop;i++){
							this.path[path[i][0].getIndex()]=true;
						}
						top[pathTop]--;
						pathTop--;
						break;
					}else if(!path[pathTop][top[0]].isSearch()){
						//寻找当前位置的下一位置的可能数
						if(path[pathTop][0].getEast()!=null&&path[pathTop][0].getEast()!=path[pathTop][0].getLast()&&!path[pathTop][0].getEast().isSearch()){
							path[pathTop][++top[pathTop]]=path[pathTop][0].getEast();
						}
						if(path[pathTop][0].getSouth()!=null&&path[pathTop][0].getSouth()!=path[pathTop][0].getLast()&&!path[pathTop][0].getSouth().isSearch()){
							path[pathTop][++top[pathTop]]=path[pathTop][0].getSouth();
						}
						if(path[pathTop][0].getWest()!=null&&path[pathTop][0].getWest()!=path[pathTop][0].getLast()&&!path[pathTop][0].getWest().isSearch()){
							path[pathTop][++top[pathTop]]=path[pathTop][0].getWest();
						}					
						if(path[pathTop][0].getNorth()!=null&&path[pathTop][0].getNorth()!=path[pathTop][0].getLast()&&!path[pathTop][0].getNorth().isSearch()){
							path[pathTop][++top[pathTop]]=path[pathTop][0].getNorth();
						}
						path[pathTop][0].setSearch(true);
					}
					//当前位置的下一位置的所有可能依次查询,无下一位置则回退到上一位置
					if(top[pathTop]==0){
						path[pathTop][0].setLast(null);
						path[pathTop][0].setSearch(false);
						top[pathTop]--;
						pathTop--;
					}else{
						pathTop++;
						top[pathTop]++;
						path[pathTop][0]=path[pathTop-1][top[pathTop-1]--];
						path[pathTop][0].setLast(path[pathTop-1][0]);
					}
				}
			}
		}
		//当路径唯一时设置路径
		private void searchPath(){
			while(true){
				if(searchPathNumber()==1){
					setPath();
					break;
				}
			}
		}
		//重载构造函数
		public Path(){
			newMaze=new CreateMaze();
			path=new boolean [newMaze.getSize()*newMaze.getSize()+1];
			this.entrance=newMaze.getEntrance();
			this.exit=newMaze.getExit();
		}
		//重载构造函数
		public Path(int size,int entrance,int exit){
			newMaze=new CreateMaze(size,entrance,exit);
			path=new boolean [newMaze.getSize()*newMaze.getSize()+1];
			this.entrance=newMaze.getEntrance();
			this.exit=newMaze.getExit();
		}
		//获取当前格子
		public Place[] getMaze() {
			searchPath();
			return maze;
		}
		//获取新迷宫大小
		public int getSize(){
			return newMaze.getSize();
		}
		//获取入口
		public int getEntrance() {
			return entrance;
		}
		//获取出口
		public int getExit() {
			return exit;
		}
		//返回当前格子为路或墙
		public boolean[] getPath() {
			return path;
		}
		//返回迷宫
		public CreateMaze getNewMaze() {
			return newMaze;
		}
}

package MazeTwo;

import java.awt.*;
import java.awt.event.*;

/* 本类保存迷宫中每一个格子的信息*/

public class Place {
	//定义当前格子是否可走,若wall为0,则表示可走;若wall为1,则表示不可走。
	private int wall;
	//表示当前格子是否被搜索过。
	private boolean search=false;
	//表示当前格子的四个方向分别是哪些格子,搜索时的上一个格子。
	private Place east=null,south=null,west=null,north=null,last=null;
	//保存迷宫格子位置
	private int index=0;
	public Place(int wall){
		this.wall=wall;
	}
	public int getWall() {
		return wall;
	}
	public void setWall(int wall) {
		this.wall = wall;
	}
	public boolean isSearch() {
		return search;
	}
	public void setSearch(boolean search) {
		this.search = search;
	}
	public Place getEast() {
		return east;
	}
	public void setEast(Place east) {
		this.east = east;
	}
	public Place getSouth() {
		return south;
	}
	public void setSouth(Place south) {
		this.south = south;
	}
	public Place getWest() {
		return west;
	}
	public void setWest(Place west) {
		this.west = west;
	}
	public Place getNorth() {
		return north;
	}
	public void setNorth(Place north) {
		this.north = north;
	}
	public Place getLast() {
		return last;
	}
	public void setLast(Place last) {
		this.last = last;
	}
	public int getIndex() {
		return index;
	}
	public void setIndex(int index) {
		this.index = index;
	}

}
package MazeTwo;

/* 本类中保存迷宫的相关参数,并提供方法创建迷宫*/

public class CreateMaze {
	//定义迷宫规模
		private int size;
		//定义迷宫的入口和出口
		private int entrance,exit;
		//用一维数组表示迷宫,0号下标位置空出
		private Place[] maze=null;
		//设置迷宫中每一个格子的方向
		private void setDirections(Place[] maze){
			for(int i=1;i<=size*size;i++){
				if(i%size!=0&&maze[i+1].getWall()==0&&maze[i+1]!=null){
					maze[i].setEast(maze[i+1]);
				}
				if(i<=size*(size-1)&&maze[i+size].getWall()==0&&maze[i+size]!=null){
					maze[i].setSouth(maze[i+size]);
				}
				if(i%size!=1&&maze[i-1].getWall()==0&&maze[i-1]!=null){
					maze[i].setWest(maze[i-1]);
				}
				if(i>size&&maze[i-size].getWall()==0&&maze[i-size]!=null){
					maze[i].setNorth(maze[i-size]);
				}
			}
		}
		
		//迷宫参数
		public CreateMaze(){
			this.size=10;
			this.entrance=1;
			this.exit=this.size*this.size;
		}
		//调用有参构造函数获取新迷宫大小及入口和出口
		public CreateMaze(int size,int entrance,int exit){
			this.size=size;
			this.entrance=entrance;
			this.exit=exit;
		}
		//返回当前迷宫格随机状态
		public Place[] getMaze() {
			maze=new Place[size*size+1];
			for(int i=1;i<=size*size;i++){
				maze[i]=new Place((int)(Math.random()*2));
				maze[i].setIndex(i);
			}
			setDirections(maze);
			return maze;
		}
		//返回入口索引
		public int getEntrance() {
			return entrance;
		}
		//设置入口索引
		public void setEntrance(int entrance) {
			this.entrance = entrance;
		}
		public int getExit() {
			return exit;
		}
		public void setExit(int exit) {
			this.exit = exit;
		}
		public int getSize() {
			return size;
		}
		public void setSize(int size) {
			this.size = size;
		}
}

package MazeTwo;

import java.awt.*;
import java.awt.event.*;

/* 本类为迷宫游戏提供图形化界面*/

public class Figure {
	Path path;
	Place[] maze=null;
	Button[] button=null;
	boolean[] isPath=null;
	
	//自动寻路界面
	 class FindMaze extends Frame implements ActionListener {
	        public FindMaze() {
	            super("A* Maze");
	            // 界面大小
	            this.setSize(500, 500);
	            // 返回默认工具箱
	            Toolkit kit = Toolkit.getDefaultToolkit();
	            // 获取屏幕尺寸
	            Dimension screenSize = kit.getScreenSize();
	            // 获取屏幕宽度
	            int screenWidth = screenSize.width;
	            // 获取屏幕高度
	            int screenHeight = screenSize.height;
	            // 获取界面窗口宽度
	            int windowWidth = this.getWidth();
	            // 获取界面窗口高度
	            int windowHeight = this.getHeight();
	            // 界面居中
	            this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
	            // 四行一列布局
	            this.setLayout(new GridLayout(path.getSize(), path.getSize()));
	            maze = path.getMaze();
	            int entrance = path.getEntrance();
	            int exit = path.getExit();
	            button = new Button[maze.length];
	            for (int i = 1; i < maze.length; ++i) {
	                // 当前格子是路则设置活动指令为 0,背景颜色为白色
	                if (maze[i].getWall() == 0) {
	                    button[i] = new Button("");
	                    button[i].setActionCommand("路");
	                    button[i].setBackground(Color.WHITE);
	                }
	                // 当前格子为墙则设置活动指令为 1,标记为灰色
	                if (maze[i].getWall() == 1) {
	                    button[i] = new Button("墙");
	                    button[i].setActionCommand("墙");
	                    button[i].setBackground(Color.LIGHT_GRAY);
	                }
	            }
	            for (int i = 1; i < button.length; i++) {
	                button[i].addActionListener(this);
	                add(button[i]);
	            }
	            button[path.getSize() * path.getSize()].setActionCommand("退出");
	            button[path.getSize() * path.getSize()].setText("退出");
	            button[path.getSize() * path.getSize()].setFont(new Font("宋体", 0, 7));
	            addWindowListener(new closeWin());
	            this.setVisible(true);
	        }

	        public void actionPerformed(ActionEvent e) {
	            if (e.getActionCommand().equals("退出")) {
	                dispose();
	                Figure figure = new Figure();
	                figure.init();
	            }
	        }
	    }
	 //启动游戏界面
	class MazeGameFigure extends Frame implements ActionListener{
		public MazeGameFigure(){
			super("迷宫游戏");
		}
		public void init(){
			// 界面大小
			this.setSize(500, 500);
			this.setBackground(Color.WHITE);
			// 返回默认工具箱
			Toolkit kit =Toolkit.getDefaultToolkit();
			 // 获取屏幕尺寸
			Dimension screenSize=kit.getScreenSize();
			// 获取屏幕宽度
			int screenWidth=screenSize.width;
			// 获取屏幕高度
			int screenHeight=screenSize.height;
			// 获取界面窗口宽度
			int windowWidth=this.getWidth();
			// 获取界面窗口高度
			int windowHeight=this.getHeight();
			 // 界面居中
			this.setLocation((screenWidth-windowWidth)/2,(screenHeight-windowHeight)/2 );
			// 五行一列布局
			this.setLayout(new GridLayout(5,1));
			Label welcom=new Label("欢迎进入迷宫游戏!");
			welcom.setBackground(Color.LIGHT_GRAY);
			Button find=new Button("自动寻路");
			Button start=new Button("开始游戏");
			Button set=new Button("游戏设置");
			Button end=new Button("退出游戏");
			find.setBackground(Color.ORANGE);
			start.setBackground(Color.ORANGE);
			set.setBackground(Color.ORANGE);
			end.setBackground(Color.ORANGE);
			add(welcom);
			add(find);
			add(start);
			add(set);
			add(end);
			find.addActionListener(this);
			start.addActionListener(this);
			set.addActionListener(this);
			end.addActionListener(this);
			addWindowListener(new closeWin());
			this.setVisible(true);
		}
		public void actionPerformed(ActionEvent e){
			if (e.getActionCommand().equals("自动 寻路")) {
                dispose();
                new FindMaze();
            }
			// 点击开始游戏生成迷宫
			if(e.getActionCommand().equals("开始游戏")){
				MazeFigure mazeFigure=new MazeFigure();
				mazeFigure.init();
				dispose();
			}
			// 点击进入设置模式
			if(e.getActionCommand().equals("游戏设置")){
				MazeSetFigure mazeSetFigure=new MazeSetFigure();
				mazeSetFigure.init();
				dispose();
			}
			if(e.getActionCommand().equals("退出游戏")){
				dispose();
			}
		}
	}
	// 启动游戏界面
	class MazeFigure extends Frame implements ActionListener{
		public MazeFigure(){
			super("迷宫");
		}
		public void init(){
			// 界面大小
			this.setSize(500, 500);
			this.setBackground(Color.BLACK);
			// 返回默认工具箱
			Toolkit kit =Toolkit.getDefaultToolkit();
			// 获取屏幕尺寸
			Dimension screenSize=kit.getScreenSize();
			// 获取屏幕宽度
			int screenWidth=screenSize.width;
			// 获取屏幕高度
			int screenHeight=screenSize.height;
			// 获取界面窗口宽度
			int windowWidth=this.getWidth();
			// 获取界面窗口高度
			int windowHeight=this.getHeight();
			// 界面居中
			this.setLocation((screenWidth-windowWidth)/2,(screenHeight-windowHeight)/2 );
			// 获取迷宫尺寸设计按钮布局
			this.setLayout(new GridLayout(path.getSize(),path.getSize()));
			maze=path.getMaze();
			int entrance=path.getEntrance();
			int exit=path.getExit();
			button=new Button[maze.length];
			for(int i=1;i<maze.length;i++){
				// 当前格子是路则设置活动指令为 1,背景颜色为白色
				if(maze[i].getWall()==0){
					button[i]=new Button("");
					button[i].setActionCommand("路");
					button[i].setBackground(Color.WHITE);					
				}
				// 当前格子为墙则设置活动指令为 0,标记为浅灰色
				if(maze[i].getWall()==1){
					button[i]=new Button("墙");
					button[i].setActionCommand("墙");
					button[i].setBackground(Color.LIGHT_GRAY);
				}
			}
			button[entrance].setLabel("入口");
			button[exit].setLabel("出口");
			// 为每个按钮添加监听器
			for(int i=1;i<button.length;i++){
				button[i].addActionListener(this);
				add(button[i]);
			}
			addWindowListener(new closeWin());
			this.setVisible(true);
		}
		// 判断是否完成通路
		private boolean isComplete(){
			isPath=path.getPath();
			for(int i=1;i<isPath.length;i++){
				if(isPath[i]&&button[i].getBackground()!=Color.ORANGE){
					return false;
				}
			}
			return true;
		}
		public void actionPerformed(ActionEvent e){
			Button button=(Button)e.getSource();
			if(button.getActionCommand().equals("路")){
				if(button.getBackground()==Color.WHITE){
					button.setBackground(Color.ORANGE);
				}else if(button.getBackground()==Color.ORANGE){
					button.setBackground(Color.WHITE);
				}
			}
			if(isComplete()){
				CongratulationFigure congratulationFigure=new CongratulationFigure();
				congratulationFigure.init();
				this.dispose();
			}
		}
	}
	// 迷宫设置界面
	class MazeSetFigure extends Frame implements ActionListener ,TextListener{
		String newSize,newEntrance,newExit;
		TextField setMaze,setEntrance,setExit;
		int size,entrance,exit;
		public MazeSetFigure(){
			super("迷宫设置");
		}
		public void init(){
			this.setSize(500, 400);
			this.setBackground(Color.WHITE);
			Toolkit kit =Toolkit.getDefaultToolkit();
			Dimension screenSize=kit.getScreenSize();
			int screenWidth=screenSize.width;
			int screenHeight=screenSize.height;
			int windowWidth=this.getWidth();
			int windowHeight=this.getHeight();
			this.setLocation((screenWidth-windowWidth)/2,(screenHeight-windowHeight)/2 );
			GridLayout layout=new GridLayout(4,2);
			this.setLayout(layout);
			Label size=new Label("迷宫规模");
			Label entrance=new Label("迷宫入口");
			Label exit=new Label("迷宫出口");
			Button menu=new Button("返回菜单");
			Button set=new Button("设置完成");
			setMaze= new TextField("10");
			setEntrance= new TextField("左上角");
			setExit= new TextField("右下角");
			add(size);
			add(setMaze);
			add(entrance);
			add(setEntrance);
			add(exit);
			add(setExit);
			add(menu);
			add(set);
			menu.addActionListener(this);
			set.addActionListener(this);
			setMaze.addTextListener(this);
			setEntrance.addTextListener(this);
			setExit.addTextListener(this);
			addWindowListener(new closeWin());
			this.setVisible(true);
		}
		public void actionPerformed(ActionEvent e){
			if(e.getActionCommand().equals("返回菜单")){
				dispose();
				Figure figure=new Figure();
				figure.init();
			}
			if(e.getActionCommand().equals("设置完成")){
				boolean isSizeReasonable=true;
				boolean isEntranceReasonable=true;
				boolean isExitReasonable=true;
				newSize=setMaze.getText();
				newEntrance=setEntrance.getText();
				newExit=setExit.getText();
				try{
					size=Integer.parseInt(newSize);
				}catch(Exception ex){
					isSizeReasonable=false;
				}
				if(isSizeReasonable==true){
					if(newEntrance.equals("左上角")){
						entrance=1;
					}else if(newEntrance.equals("右上角")){
						entrance=size;
					}else if(newEntrance.equals("左下角")){
						entrance=size*(size-1)+1;
					}else if(newEntrance.equals("右下角")){
						entrance=size*size;
					}else{
						isEntranceReasonable=false;
					}
					
					if(newExit.equals("左上角")){
						exit=1;
					}else if(newExit.equals("右上角")){
						exit=size;
					}else if(newExit.equals("左下角")){
						exit=size*(size-1)+1;
					}else if(newExit.equals("右下角")){
						exit=size*size;
					}else{
						isExitReasonable=false;
					}
					
					if(isEntranceReasonable==true&&isExitReasonable==true){
						if(entrance==exit){
							isEntranceReasonable=false;
							isExitReasonable=false;
						}
					}	
				}
				if(isSizeReasonable==true&&isEntranceReasonable==true&&isExitReasonable==true){
					dispose();
					Figure figure=new Figure(size,entrance,exit);
					figure.init();
				}else{
					SetErrorFigure setErrorFigure=new SetErrorFigure();
					setErrorFigure.init();
					dispose();
				}
			}
		}
		public void textValueChanged(TextEvent e){
			
		}
	}
	// 通过迷宫游戏界面
	class CongratulationFigure extends Frame implements ActionListener{
		public CongratulationFigure(){
			super("恭喜");
		}
		public void init(){
			this.setSize(220, 200);
			this.setBackground(Color.WHITE);
			Toolkit kit =Toolkit.getDefaultToolkit();
			Dimension screenSize=kit.getScreenSize();
			int screenWidth=screenSize.width;
			int screenHeight=screenSize.height;
			int windowWidth=this.getWidth();
			int windowHeight=this.getHeight();
			this.setLocation((screenWidth-windowWidth)/2,(screenHeight-windowHeight)/2 );
			this.setLayout(new GridLayout(2,1));
			Label text=new Label("恭喜您成功走出迷宫!");
			Button button=new Button("确认");
			button.setBackground(Color.WHITE);
			add(text);
			add(button);
			button.addActionListener(this);
			addWindowListener(new closeWin());
			this.setVisible(true);
		}
		public void actionPerformed(ActionEvent e){
			if(e.getActionCommand().equals("确认")){
				dispose();
				Figure figure=new Figure();
				figure.init();
			}
		}
	}
	// 游戏设置数据错误界面
	class SetErrorFigure extends Frame implements ActionListener{
		public SetErrorFigure(){
			super("错误");
		}
		public void init(){
			this.setSize(230, 100);
			this.setBackground(Color.WHITE);
			Toolkit kit =Toolkit.getDefaultToolkit();
			Dimension screenSize=kit.getScreenSize();
			int screenWidth=screenSize.width;
			int screenHeight=screenSize.height;
			int windowWidth=this.getWidth();
			int windowHeight=this.getHeight();
			this.setLocation((screenWidth-windowWidth)/2,(screenHeight-windowHeight)/2 );
			this.setLayout(new GridLayout(2,1));
			Label text=new Label("您输入的数据不合理,设置失败!");
			Button button=new Button("确认");
			button.setBackground(Color.WHITE);
			add(text);
			add(button);
			button.addActionListener(this);
			addWindowListener(new closeWin());
			this.setVisible(true);
		}
		public void actionPerformed(ActionEvent e){
			if(e.getActionCommand().equals("确认")){
				dispose();
				Figure figure=new Figure();
				figure.init();
			}
		}
	}
	class closeWin extends WindowAdapter{
		public void windowClosing(WindowEvent e){
			Window w=e.getWindow();
			w.dispose();
		}
	}
	
	public Figure(){
		path=new Path();
	}
	
	public Figure(int size,int entrance,int exit){
		path=new Path(size,entrance,exit);
	}
	
	public void init(){
		MazeGameFigure mazeGameFigure=new MazeGameFigure();
		mazeGameFigure.init();
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值