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 ; //否则设置数组当中的值
}
}