迷宫游戏
深度优先遍历(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*算法的具体步骤
- 把起点加入openlist
- 遍历openlist,找到F值最小的节点,把它作为当前处理的节点,并把该节点加入closelist中
- 对该节点的8个相邻格子进行判断, 如果格子是不可抵达的或者在closelist中,则忽略它,否则如下操作:
a. 如果相邻格子不在openlist中,把它加入,并将parent设置为该节点和计算f,g,h值
b.如果相邻格子已在openlist中,并且新的G值比旧的G值小,则把相邻格子的parent设置为该节点,并且重新计算f值。 - 重复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();
}
}