程序实现搜索迷宫出口完整版

import java.awt.*;

import java.awt.List;
import java.awt.event.*;
import java.util.*;
import javax.swing.JOptionPane;
//驱动类
public class tanchishe 
{
 public static void main(String[] args)
 {
  new MainFrame("迷宫破解").addWindowListener(new WindowAdapter()    //添加窗口关闭处理函数 
  { 
   public void windowClosing(WindowEvent e) 
   { 
    System.exit(0); 
   }}); 
 } 
}

//路径对象
class Rect{
 int wx;
 int wy;
 int NowValue;
 int PointerTo;
 
    public Rect(int wx,int wy){
     this.wx = wx;
     this.wy = wy;
    }
 public int GetX() {
  //获得x坐标
  return wx;
 }
 public int Gety() {
  //获得y坐标
  return wy;
 }
 public int GetNowValue() {
  //获得当前路径下的数组中的值
  return NowValue;
 }
 public void SetNowValue(int NowValue) {
  //5代表已走过的路径
  //4代表无法走通的路径
  //3代表当表终点
  this.NowValue = NowValue;
 }
 public int GetPointerTo() {
  //获得此路径的方向
  return PointerTo;
 }
 public void SetPointerTo(int PointerTo) {
  //设置当前路径的方向值
  this.PointerTo = PointerTo;
 }
 public String toString() {
  //输出路径各个属性
  return ("wx is:" + wx + "wy is:" + wy + "NowValue is:"
    + NowValue + "PointerTo is:" + PointerTo);
 }
 
}

 

//此线程负责操作栈中的数据
/*
class stack_thread implements Runnable
{  
 
 @Override
 public void run() {
  // TODO Auto-generated method stub

 }

}
***/

 

//游戏界面
class MainFrame extends Frame
{  
 private static final long serialVersionUID = 1L;
 Map map = new Map(2);      //默认进入游戏的第二关
 
 //绘制游戏界面
 //开始,暂停,选关标签,输入关卡的文本编辑框,游戏画面
 Button a = new Button("开始");
 Button b = new Button("暂停");
 Button c = new Button("退出");
 Button l = new Button("进入");
 Label ll = new Label("关卡");
 TextField t = new TextField(15);
 List lst = new List(4, false);
 List lll = new List(4);
 Rectangle r = new Rectangle(60,10);
 Init_GameArea init = new Init_GameArea(this,t,map);  //初始化游戏界面
 Paint st = new Paint() ;                             //实现了绘图的线程
 Thread Painter = new Thread(st);                     //继承了runnable接口
 boolean flag = true;
 boolean gameflag;         //判断游戏是否结束的标志
 int Nowx;                 //探索迷宫出口的起始x坐标
 int Nowy;      //探索迷宫出口的起始y坐标
 Stack<Rect> stack = new Stack<Rect>();    //保存路径对象的栈

 
 MainFrame(String s){
  
  //窗口的布局
  super(s);
  setLayout(new FlowLayout());
  Panel p = new Panel();
  p.setLayout(new FlowLayout());
  a.setBounds(r);
  b.setBounds(r);
  c.setBounds(r);
  l.setBounds(r);
  ll.setBounds(r);
  lst.setBounds(r);
  p.add(ll);
  p.add(t);
  p.add(l);
  p.add(lst);
  p.add(a);
  p.add(b);
  p.add(c);

  lst.add("第一关",1);
  lst.add("第二关",2);
  lst.add("第三关",3);
  lst.add("第四关",4);
  add(p);

  lst.addItemListener(new ItemMonitor());
  lst.addActionListener(new ItemActionMonitor());

  a.addActionListener(new Monitor());
  b.addActionListener(new Monitor());
  c.addActionListener(new Monitor());
  l.addActionListener(new Monitor());

  a.setForeground(Color.PINK);
  b.setForeground(Color.PINK);
  c.setForeground(Color.PINK);
  l.setForeground(Color.CYAN);
  ll.setBackground(Color.CYAN);

  setBounds(200,200,670,678);
  this.setBackground(Color.BLUE);
  this.setBackground(new Color(41,36,33));
  setVisible(true);
  setResizable(true);
  this.setFocusableWindowState(true);
  
 }


 //画图函数,每次数据的改变都依赖于此函数的重新绘制
 public void paint(Graphics g){
  
  Color tempColor;               //颜色对象
  tempColor = g.getColor();      //获得画笔的颜色
  g.setColor(Color.green);       //设置画笔的颜色
  g.drawRect(20, 130, 627, 533); //画游戏的边框
  tempColor = g.getColor();
  g.setColor(Color.blue);        //恢复画笔的初始颜色

  for(int i = 0  ; i < 11 ; i++)
   for(int j = 0 ; j < 13 ; j++)
   {
    //如果是墙体
    if(map.readMap(i, j) == 1)
    {
     g.setColor(Color.red);
     g.fillRect(23+j*48,133+i*48,47,47);
     
    }
    //符合条件的下一个位置作为当前路径
    if(map.readMap(i , j) == 2)
    {
     g.setColor(Color.yellow);
     g.fillRect(23+j*48,133+i*48,47,47);
     Nowx = 23+j*48;                    //修改当前路径的x值
     Nowy = 133+i*48;       //修改当前路径的y值
     stack.push(new Rect(Nowx,Nowy));   //路径入栈
    }   
    
    //若果是终点
    if(map.readMap(i , j) == 3)
    {
     g.setColor(Color.green);
     g.fillRect(23+j*48,133+i*48,47,47);
    }
    
    //如果是已经走过的路径
    if(map.readMap(i , j) == 5)
    {
     g.setColor(Color.blue);
     g.fillRect(23+j*48,133+i*48,47,47);
    }
    
    //如果是无法走通的路径
    if(map.readMap(i , j) == 4)
    {
     g.setColor(Color.MAGENTA);
     g.fillRect(23+j*48,133+i*48,47,47);
    }
   }
  
   g.setColor(tempColor);    //恢复现场操作
  
 }
 
    //内部类
 class Paint implements Runnable{
  int SleepTime = 100;

  public void  run(){
   
   //实现图案填充,标记功能
   //创建绘图线程,重写run()方法
   while(gameflag == false && stack.empty() == false)
   {
    //根据栈顶对象的坐标转换为数组下标,判断对应的数组元素值,下同
       if((map.readMap((stack.peek().Gety() - 133)/48, ((stack.peek().GetX() - 23)/48) + 1) != 1)
    && (map.readMap((stack.peek().Gety() - 133)/48, ((stack.peek().GetX() - 23)/48) + 1) != 4)
    && (map.readMap((stack.peek().Gety() - 133)/48, ((stack.peek().GetX() - 23)/48) + 1) != 5
    ))
    {  
        //如果当前栈顶元素的东面是终点,弹出胜利提示框,并跳出循环
     if(map.readMap((stack.peek().Gety() - 133)/48, ((stack.peek().GetX() - 23)/48 + 1)) == 3){
      JOptionPane.showMessageDialog(null,"Very Good! We Succeed, There is a way to the distict!");
      break;
     }
     
     //如果不是终点,下同
     if((stack.peek().GetX() + 48)/48 <= map.readXlength() &&
       stack.peek().Gety()/48 <= map.readYlength())
     {
      //将当前栈顶路径的东面设置为当前路径
      map.setMap((stack.peek().Gety() - 133)/48, ((stack.peek().GetX() - 23)/48) + 1, 2);
      //将栈顶路径设置为已走路径
      map.setMap((stack.peek().Gety() - 133)/48, ((stack.peek().GetX() - 23)/48), 5);
      stack.peek().SetPointerTo(0);
      //将当前路径入栈
      stack.push(new Rect(stack.peek().GetX() + 48,stack.peek().Gety()));
      //数组未越界,进行重绘
      repaint();
     }
     //绘图线程睡眠一段时间
     try {
      Thread.sleep(SleepTime);     
     } catch (InterruptedException e) {
      e.printStackTrace();
     };
     
    }
    //如果当前栈顶元素的南面不是墙体,不是已经走过的路径,不是无法走通的路径
    else if(map.readMap((stack.peek().Gety() - 133)/48 + 1, (stack.peek().GetX() - 23)/48) != 1
     && (map.readMap((stack.peek().Gety() - 133)/48 + 1, (stack.peek().GetX() - 23)/48)) != 4
     && (map.readMap((stack.peek().Gety() - 133)/48 + 1, (stack.peek().GetX() - 23)/48) != 5
     ))
    {
     //如果当前栈顶元素的南面是终点,弹出胜利提示框,并跳出循环
     if(map.readMap((stack.peek().Gety() - 133)/48 + 1, (stack.peek().GetX() - 23)/48) == 3){
      JOptionPane.showMessageDialog(null,"Very Good! We Succeed, There is a way to the distict!");
      break;
     }
     
     if((stack.peek().GetX())/48 <= map.readXlength() &&
       (stack.peek().Gety() + 48)/48 <= map.readYlength())
     {
      map.setMap((stack.peek().Gety() - 133)/48 + 1, (stack.peek().GetX() - 23)/48, 2);
      map.setMap((stack.peek().Gety() - 133)/48,(stack.peek().GetX() - 23)/48,5);
      //当前栈顶路径的方向设为1
      stack.peek().SetPointerTo(1);
      //新的当前路径入栈
      stack.push(new Rect(stack.peek().GetX(),stack.peek().Gety() + 48));
      repaint();
     }
     
     try {
      Thread.sleep(SleepTime);     
     } catch (InterruptedException e) {
      e.printStackTrace();
     };
     
    }
    //如果当前栈顶元素的西面不是墙体,不是已经走过的路径,不是无法走通的路径
    else if(map.readMap((stack.peek().Gety() - 133)/48, (stack.peek().GetX() - 23)/48 - 1) != 1
      && (map.readMap((stack.peek().Gety() - 133)/48, (stack.peek().GetX() - 23)/48 - 1)) != 4
      && (map.readMap((stack.peek().Gety() - 133)/48, (stack.peek().GetX() - 23)/48 -1) != 5
      ))
     {
        //如果当前栈顶元素的西面是终点,弹出胜利提示框,并跳出循环
        if(map.readMap((stack.peek().Gety() - 133)/48, (stack.peek().GetX() - 23)/48 - 1) == 3){
         JOptionPane.showMessageDialog(null,"Very Good! We Succeed, There is a way to the distict!");
         break;
         }
       
        if((stack.peek().GetX() - 48)/48 <= map.readXlength() &&
        stack.peek().Gety()/48 <= map.readYlength())
        {
         map.setMap((stack.peek().Gety() - 133)/48, (stack.peek().GetX() - 23)/48 - 1, 2);
         map.setMap((stack.peek().Gety() - 133)/48,((stack.peek().GetX() - 23)/48),5);
         stack.peek().SetPointerTo(2);
         stack.push(new Rect(stack.peek().GetX() - 48,stack.peek().Gety()));
         repaint();
        }
      
      try {
       Thread.sleep(SleepTime);     
      } catch (InterruptedException e) {
       e.printStackTrace();
      };
      
     }
    //如果当前栈顶元素的北面不是墙体,不是已经走过的路径,不是无法走通的路径
    else if(map.readMap((stack.peek().Gety() - 133)/48 - 1, (stack.peek().GetX() - 23)/48) != 1
      && (map.readMap((stack.peek().Gety() - 133)/48 - 1, (stack.peek().GetX() - 23)/48)) != 4
      && (map.readMap((stack.peek().Gety() - 133)/48 - 1, (stack.peek().GetX() - 23)/48) != 5
      ))
     {
         //如果当前栈顶元素的北面是终点,弹出胜利提示框,并跳出循环
         if(map.readMap((stack.peek().Gety() - 133)/48 - 1, ((stack.peek().GetX() - 23)/48)) == 3){
          JOptionPane.showMessageDialog(null,"Very Good! We Succeed, There is a way to the distict!");
          break;
         }
        
         if((stack.peek().GetX())/48 <= map.readXlength() &&
        (stack.peek().Gety() - 48)/48 <= map.readYlength())
         {
          map.setMap((stack.peek().Gety() - 133)/48 - 1, (stack.peek().GetX() - 23)/48, 2);
          map.setMap((stack.peek().Gety() - 133)/48,(stack.peek().GetX() - 23)/48,5);
          stack.peek().SetPointerTo(3);
          stack.push(new Rect(stack.peek().GetX(),stack.peek().Gety() - 48));
          //重绘
          repaint();
      }
      
      //画图线程睡眠一段时间
      try {
       Thread.sleep(SleepTime);     
      } catch (InterruptedException e) {
       e.printStackTrace();
      };
      
     }
      
    //四个方向均无法走通,则退栈
    else
    {
     //according the weather to pop the object
     if(stack.empty() == false)
     {
      //将当前的路径坐标下映射的数组元素值设置为4,表示不可走通,以便于重绘
      map.setMap((stack.peek().Gety() - 133)/48,(stack.peek().GetX() - 23)/48,4);
      //将当前的路径的方向设置为4,表示四个方向均无法走通,貌似没有多大用处,下一行代码有没有都行
      stack.peek().SetPointerTo(4);
      
     //System.out.println(stack.peek().GetNowValue());
     
      //将栈顶路径对象删除
      stack.pop();
      //如果栈非空并且当前栈顶路径对象还没开始向北探索,即标志值为3
      if(stack.empty() == false && (stack.peek().GetPointerTo() != 3))
      {
       //将当前栈顶对象设置为当前路径,并设置值2,便于重绘
       map.setMap((stack.peek().Gety() - 133)/48,(stack.peek().GetX() - 23)/48,2);
       
       
     //System.out.println(map.readMap((stack.peek().Gety() - 133)/48, (stack.peek().GetX() - 23)/48));
         
         
       //将当前路径的方向自增1,一直迷惑这句有什么用处?
       stack.peek().SetPointerTo(stack.peek().GetPointerTo() + 1);
       //重绘
       repaint();
      }
   
      try {
       Thread.sleep(SleepTime/5);     
      }catch (InterruptedException e){       
       e.printStackTrace();
      };
      
      
     }
 
    }
   
   }//while循环结束

   //若栈最终为空,则迷宫无路可通,弹出提示对话框
   if(stack.empty() !=  false)
    JOptionPane.showMessageDialog(null,"Oh my God, We fail, There is no way to the distict!");
   
  }//run()方法结束
  
 }//画图线程结束
  
 

 //内部类
 class Monitor implements ActionListener {
  int i = 0;
  
  public void actionPerformed(ActionEvent arg0) {
   // TODO Auto-generated method stub
   //点击了开始按钮
   if(arg0.getSource() == a){
    //所有线程均启动
    changetoTrue();
    Painter.start();
   }
   
   //点击了进入按钮
   else if(arg0.getSource() == l){
    String s = t.getText();
    int m = Integer.parseInt(s);
    map = init.InitGameArea(m);
    map = new Map(m);
    repaint();
   }
   
   //点击了暂停按钮
   else if(arg0.getSource() == b){
    //所有线程均休眠
    i++;
    if(i%2 == 0){
     resumeThread();
    }
    else if(i%2 == 1){
        changetoFalse();
    }

   }
   
   //点击了推出按钮
   else if(arg0.getSource() == c){    
    //游戏推出,窗口消失
    System.exit(0);
   }

     }
  
  public void changetoFalse(){
         flag = false;
     }
  
  public void changetoTrue(){
     flag = true;
     } 
  
  //线程挂起
  public synchronized void hangThread() throws InterruptedException
  {
       st.wait();
  }
  
  //线程恢复
  public synchronized void  resumeThread()
  {
   Thread.currentThread().notifyAll();    
  }
  
 }

 //内部类
 class ItemMonitor implements ItemListener {

  @Override
  public void itemStateChanged(ItemEvent arg0) {
   / TODO Auto-generated method stub
   int id = arg0.getID();
   System.out.println("id"+id);

  }
 }

 //内部类
 class ItemActionMonitor implements ActionListener{

  @Override
  public void actionPerformed(ActionEvent e) {
   // TODO Auto-generated method stub
   int id = e.getID();
   init.InitGameArea(++id);
  }

 }
 
}

 
 //内部类
 /***
 class TextfieldMonitor implements ActionListener{

  @Override
  public void actionPerformed(ActionEvent e) {
   // TODO Auto-generated method stub
   TextField str = (TextField)e.getSource();
   String s = str.getText();
   int m = Integer.parseInt(s);
   map = init.InitGameArea(m);
   map = new Map(m);
   repaint();
  }

 }
 ****/


//初始化迷宫
class Init_GameArea
{
 MainFrame mf = null;
 TextField tt;
 Map mmap;

 public Init_GameArea(MainFrame mf,TextField t,Map map){
  this.mf = mf;
  this.tt = t;
  this.mmap = map;
 }
 public Map InitGameArea(int m) {
  //初始化游戏界面
  switch(m){

  case 1:
   //初始化第一关
   mmap = new Map(1);
  case 2:
   //初始化第二关
   mmap = new Map(2);
  case 3:
   //初始化第三关
   mmap = new Map(3);
  }
  return mmap; //返回此引用值
 }

}

//游戏地图类
class Map
{
 private int[][] MAP ;
 Map(int i)
 {
  int[][] map1 =  {
    {1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,2,0,0,0,0,1,1,1,0,1,1,1},
    {1,1,1,0,1,0,1,1,1,0,1,1,1},
    {1,0,0,0,0,0,0,0,0,1,1,0,1},
    {1,0,1,0,1,1,0,1,0,0,0,1,1},
    {1,0,1,1,0,0,1,0,1,1,1,1,1},
    {1,0,0,0,0,0,0,0,0,0,0,1,1},
    {1,0,1,0,1,0,0,1,1,0,0,0,1},
    {1,0,0,0,1,0,0,0,0,1,1,1,1},
    {1,1,1,1,1,1,1,1,0,0,0,0,1},
    {1,1,1,1,1,1,1,1,1,1,3,1,1},
      };
  int [][]map2 = {
    {1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,2,0,0,1,0,0,0,1,0,1,1,1},
    {1,0,1,0,1,0,1,0,1,0,1,1,1},
    {1,0,0,0,1,0,0,1,0,1,1,0,1},
    {1,0,1,0,1,0,0,0,0,0,1,0,1},
    {1,0,1,0,1,0,1,1,1,0,0,0,1},
    {1,0,0,0,1,0,0,0,1,1,1,0,3},
    {1,0,1,0,0,0,0,1,1,0,0,1,1},
    {1,0,0,0,1,0,1,1,0,0,0,0,1},
    {1,1,1,0,0,0,0,0,0,0,0,1,1},
    {1,1,0,1,1,1,1,1,1,1,1,1,1},
             };
  int [][]map3 = {
    {1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,2,1,0,0,0,0,0,0,1,1,1,1},
    {1,0,1,0,1,1,0,1,0,0,1,1,1},
    {1,0,0,0,1,0,0,1,1,0,1,1,1},
    {1,0,1,1,1,1,0,1,1,0,0,0,1},
    {1,0,1,0,0,0,1,1,0,0,0,0,1},
    {1,0,0,0,1,0,1,1,1,0,1,0,1},
    {1,0,1,0,1,1,0,1,0,0,1,1,1},
    {1,0,0,0,1,0,1,1,0,1,0,1,1},
    {1,1,1,1,1,1,1,1,0,0,0,3,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1},
    };
  if(i == 1)
   MAP = map1;
  else if(i == 2)
   MAP = map2;
  else if(i == 3)
   MAP = map3;
 }
 //访问数组元素
 public int readMap(int x, int y)
 {
  if(x > MAP.length)       //如果Y大于数组的行数,返回-1
   return -1 ;   
  else if(y > MAP[0].length) //如果x大于数组的列数,返回-1
   return -1 ;
  else 
   return MAP[x][y];       //否则返回正确的数组当中的值
 }
 
 //返回数组的列数
 public int readXlength()
 {
  return MAP[0].length ;
 }
 
 //返回数组的行数
 public int readYlength()
 {
  return MAP.length ;
 }
 
 public void setMap (int x, int y, int value)
 {
  if(x > MAP.length)          //如果Y大于数组的行数,返回
   return ;
  else if(y > MAP[0].length)  //如果x大于数组的列数,返回
   return ;
  else
   MAP[x][y] = value ;      //否则设置数组当中的值
 }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值