迷宫游戏
说明:
-
用非递归的栈来解决
-
用类来解决迷宫路径的查找问题,寻找一条从左上角迷官入口到右下角迷官出口的一条有效路径, 0 代表可以行走,1代表不能行走。找到,请输入最终的迷言和路径信息,找不到,请输出不存在有效径。
例:请输入迷宫的行列数(m *n) : 5 5 请输入迷宫的路径: 0 1 1 1 0 0 0 1 1 1 1 0 0 0 1 0 1 1 0 1 1 1 1 0 0 正在寻找迷宫路径..... 路径已找到,输出如下:(2代表行走的路径) 2 1 1 1 0 2 2 1 1 1 1 2 2 2 1 0 1 1 2 1 1 1 1 2 2
1.首先我们需要用一个类来存储这个迷宫:
class Maze {
private int arr[][];
private int a;
private int b;
}
在这里我们用到了一个二维数组arr[][]来存放它每一个点,0代表可以走,1代表不可以走。a和b代表迷宫的长和宽,通过用户输入给值。
2.迷宫存好了,接下来我们需要定义一个类来存放它的行走路径,这里用栈来实现。
class SeqStqck{//******一个栈,存放路径
Point way[];
int top;//栈顶指针
int maxsize;//栈最大容量
public void getSeqStqck(int x){
maxsize=x;
way=new Point[maxsize];
top=-1;
}
}
因为java没有指针,这里我实现栈时是用数组做的,再加一个栈顶指针top,栈顶指针初始值为-1。way[]数组用来存放路径中每一个点的坐标,也就是说它每一个元素代表一个坐标,有横坐标和竖坐标,所以这里我们就需要再定义一个坐标类。
class Point{//******存放坐标
private int x;
private int y;
public void getPoint(int x,int y){
this.x=x;
this.y=y;
}
}
这样,存放路径的类就完成了。
3.接下来就是解决怎么找有效路径的问题了。
0 1 1 1
0 0 1 1
1 0 0 0
对坐标(2,2)的0节点,它有上下左右四个节点可以走,我是按照下、右、上、左的顺序走的。在这里需注意出了1节点不可走外,他的来源节点也不可走。所以坐标(2,2)的0节点只能向下走。
下面是寻找路径的代码:
System.out.println("正在寻找路径:");
int i=0,j=0;
int temp_x=0,temp_y=0;//******上一个节点的坐标,节点在寻找下一个可走节点时,不能寻找来源节点
if(arr[i][i]==1)
return false;
else{
super.push_SeqStqck(i,j);
arr[i][j]=2;
while(true){
if(i==a-1&&j==b-1&&arr[i][j]==2){//循环出口:判断是否走到右下脚出口
return true;
}
int flag=0;//*****判断本次是否进行了向下、向右....等的操作
if((i+1)<arr.length&&arr[i+1][j]==0){ //***向下
super.push_SeqStqck(i+1,j);//节点存入路径
arr[i+1][j]=2;
i++;
flag=1;
continue;
}
if((j+1)<arr[i].length&&arr[i][j+1]==0){ //***向右
super.push_SeqStqck(i,j+1);
arr[i][j+1]=2;
j++;
flag=1;
continue;
}
if((i-1)>=0&&arr[i-1][j]==0&&i-1!=temp_x&&j!=temp_y){ //***向上
super.push_SeqStqck(i-1,j);
arr[i-1][j]=2;
i--;
flag=1;
continue;
}
if((j-1)>=0&&arr[i][j-1]==0&&i!=temp_x&&j-1!=temp_y){ //***向左
super.push_SeqStqck(i,j-1);
arr[i][j-1]=2;
j--;
flag=1;
continue;
}
if(flag==0){//******flag=0时,此节点为死节点,找不到下一个有效节点。这时从路径中删除此节点,回到上一个节点
if(i==0&&j==0)
return false;//如果此节点是入口节点,结束,无有效路径
else{
arr[i][j]=-1;//****给此节点赋值-1,终结这条路径
this.pop_SeqStqckk(); // 路径中删除此节点
i=way[top].getX();// 回到上一个节点
j=way[top].getY();
}
}
}
}
好了,这样就完成了。下面是完整代码
package com.tulun.src1;
import java.util.Scanner;
class Point{//******存放坐标
private int x;
private int y;
public void getPoint(int x,int y){
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
class SeqStqck{//******一个栈,存放路径
Point way[];
int top;//栈顶指针
int maxsize;//栈最大容量
public void getSeqStqck(int x){
maxsize=x;
way=new Point[maxsize];
top=-1;
}
public void push_SeqStqck(int x,int y){//*****入栈
way[++top]=new Point();
way[top].getPoint(x,y);
}
public void pop_SeqStqckk(){//********出栈
top--;
}
}
class Maze extends SeqStqck{
private int arr[][];
private int a;
private int b;
public Maze(){//*****初始化迷宫
System.out.println("请输入迷宫的行数和列数:");
Scanner scanner=new Scanner(System.in);
a=scanner.nextInt();
b=scanner.nextInt();
super.getSeqStqck(a*b);//******因为用super调用父类的构造方法,必须放在第一条语句,所以另写了一个方法
System.out.println("请输入迷宫的(0代表可以走,1代表不可以走):");
arr=new int[a][];
for(int i=0;i<arr.length;i++){
arr[i]=new int[b];
for(int j=0;j<arr[0].length;j++){
arr[i][j]=scanner.nextInt();
}
}
}
public boolean searchWay(){
System.out.println("正在寻找路径:");
int i=0,j=0;
int temp_x=0,temp_y=0;//******上一个节点的坐标,节点再寻找下一个可走节点时,不能寻找来源节点
if(arr[i][i]==1)
return false;
else{
super.push_SeqStqck(i,j);
arr[i][j]=2;
while(true){
if(i==a-1&&j==b-1&&arr[i][j]==2){//循环出口:判断是否走到右下脚出口
return true;
}
int flag=0;//*****判断本次是否进行了向下、向右....等的操作
if((i+1)<arr.length&&arr[i+1][j]==0){ //***向下
super.push_SeqStqck(i+1,j);//节点存入路径
arr[i+1][j]=2;
i++;
flag=1;
continue;
}
if((j+1)<arr[i].length&&arr[i][j+1]==0){ //***向右
super.push_SeqStqck(i,j+1);
arr[i][j+1]=2;
j++;
flag=1;
continue;
}
if((i-1)>=0&&arr[i-1][j]==0&&i-1!=temp_x&&j!=temp_y){ //***向上
super.push_SeqStqck(i-1,j);
arr[i-1][j]=2;
i--;
flag=1;
continue;
}
if((j-1)>=0&&arr[i][j-1]==0&&i!=temp_x&&j-1!=temp_y){ //***向左
super.push_SeqStqck(i,j-1);
arr[i][j-1]=2;
j--;
flag=1;
continue;
}
if(flag==0){//******flag=0时,此节点为死节点,找不到下一个有效节点。这时从路径中删除此节点,回到上一个节点
if(i==0&&j==0)
return false;//如果此节点是入口节点,结束,无有效路径
else{
arr[i][j]=-1;//****给此节点赋值-1,终结这条路径
this.pop_SeqStqckk(); // 路径中删除此节点
i=way[top].getX();// 回到上一个节点
j=way[top].getY();
}
}
}
}
}
public void put(){
for(int i=0;i<arr.length;i++)
{
for(int j=0;j<arr[i].length;j++){
if(arr[i][j]==-1)
arr[i][j]=0;
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
public class TestworkMaze {
public static void main(String[] args){
Maze maze=new Maze();
boolean flag=maze.searchWay();
if(flag)
{
System.out.println("路径已找到,输出如下");
maze.put();
// maze.printlf();
}
else
System.out.println("无有效路径");
}
}