乞丐版JAVA扫雷
事先声明:本人是一位刚接触Java不久的菜鸟,所以代码写的略显臃肿,敬请谅解!这个扫雷是我在暑假时做的,灵感来源于csdn上某位大神的博客,不过我个人实在不喜欢他的代码实现,于是我自己写了一个实现上不同的扫雷。
这是那位大牛那篇扫雷的博客链接:http://blog.csdn.net/su20145104009/article/details/52152514,有兴趣的可以去浏览下。
程序:主界面上和Windows经典的那款扫雷很像,正上方有一个笑脸按钮,用于游戏重启,下面是雷区,用一个继承于JButton组件的类型实现。笑脸按钮两侧,一侧用JLabel显示剩余雷数,一侧用JLabel显示使用的时间。菜单栏上有难度设置,也是仿制windows经典扫雷的难度设置,即9*9,16*16,30*16三种级别。之所以叫乞丐版主要是左右同时敲击鼠标不能敲开周围的块而且没有排名并且记录的那个功能。
P.S.:用的好端端的edge浏览器TMD崩了,我真他们是CTM,我本来写的一大堆程序解释瞬间消失,算了我还是直接讲最主要算法吧。(这一下弄得我实在是没有热情再写那么详细了,我明明已经快写完了。第一次草稿保存的是如上内容,晚上修改的后面的所有全没了。网页崩了而我的系统屁事儿没有依旧飞快运转。。。。我可是在熬夜写这个啊)
主要难点在于如何判断点击后如何判断九宫格的位置,要引入两个值,edgeU和edgeD(不偏不倚这两个值我还真的给他们起名为edge,看着就来气),在雷区内总有些位置很尴尬它们周围并没有形成完全的九宫格,不过没有关系。因为在整个区域内只用两条竖边很特殊,它们的前一个或者后一个不一定在它们的左边或者右边,这个时候利用上面那两个值就很管用了,具体怎么用的我不想讲了,请自己去看代码吧(热情实在是被浇灭了。。。)在判断完九宫格内雷数后,你还要展开周围没有雷的地方(被展开的周围如有空位置也要一起展开),具体实现也请看代码。


import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random; public class Main extends JFrame implements MouseListener{
private int screenwide;
private int screenhigh;
private int colNum;
private int rowNum;
private int mineNum;
private int restNum;
private int min = 0;//分钟
private int sec = 0;//秒钟
private JLabel label1;//显示时间用
private JLabel label2;//显示剩余雷数
private JButton button;//笑脸按钮,用于重新开始
private String gameState = "run";//游戏运行状态
private boolean isfirst = true;//判断是否是第一次按下
//难度选择菜单
private JMenuBar menuBar;
private JMenu menu;
private JMenuItem low;
private JMenuItem mid;
private JMenuItem high;
//核心模块
private ArrayList<Bub>list = new ArrayList<Bub>(0);
public boolean isFirst() {
return isfirst;
}
public void initMenu() {
menuBar = new JMenuBar();
menu = new JMenu("难度设置");
low = new JMenuItem("初级(10)");
mid = new JMenuItem("中级(40)");
high = new JMenuItem("高级(99)");
low.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
new Main(10);
}
});
mid.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
new Main(40);
}
});
high.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
new Main(99);
}
});
menu.add(low);
menu.add(mid);
menu.add(high);
menuBar.add(menu);
setJMenuBar(menuBar);
}
class stopwatch extends Thread{
public void run() {
while(gameState.equals("run")) {
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
sec++;
if(sec==60) {
sec=0;
min++;
}
if(min==0&&sec<10)label1.setText("00:0"+new Integer(sec).toString());
if(min==0&&sec>=10)label1.setText("00:"+new Integer(sec).toString());
if(min>0&&sec<10)label1.setText(new Integer(min).toString()+":0"+new Integer(sec).toString());
if(min>0&&sec>=10)label1.setText(new Integer(min).toString()+":"+new Integer(sec).toString());
}
}
}
public Main(int num) {
super("扫雷");
mineNum = num;
restNum = mineNum;
if(mineNum == 10) {
screenwide = 200;
screenhigh = 290;
colNum = 9;
rowNum = 9;
}
if(mineNum == 40) {
screenwide = 340;
screenhigh = 430;
colNum = 16;
rowNum = 16;
}
if(mineNum == 99) {
screenwide = 620;
screenhigh = 430;
colNum = 30;
rowNum = 16;
}
initMenu();
setSize(screenwide,screenhigh);
setLayout(null);
setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); button = new JButton(new ImageIcon("D:\\学习文档\\smile1.jpg"));
button.setBounds(screenwide/2-20, 5, 20, 20);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
new Main(mineNum);
}
});
add(button);
label1 = new JLabel("剩余时间");
label1.setBounds(10,5,60,20);
add(label1); label2 = new JLabel("剩余:"+restNum);
label2.setBounds(screenwide-70,5,60,20);
add(label2);
JPanel p = new JPanel();
p.setLayout(new GridLayout(rowNum,colNum,0,0));
for(int i = 0;i<rowNum*colNum;++i) {
Bub bub = new Bub();
bub.showImg(13);
bub.addMouseListener(this);
list.add(bub);
p.add(bub);
}
p.setBounds(0,40,colNum*20,rowNum*20);
add(p);
this.setVisible(true);
}
public static void main(String[]args) {
new Main(10);
}
class Result extends JFrame {
/**
*
*/
private static final long serialVersionUID = 7899366376251467187L; public Result(String con) {
super("游戏结果");
setSize(250,150);
setLocationRelativeTo(null);
JButton button = new JButton("确定");
setLayout(null);
JLabel label3 = new JLabel();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
label3.setFont(new Font("微软雅黑",Font.BOLD,15));
if(con.equals("win")) label3.setText("用时"+min+"分"+sec+"秒");
if(con.equals("lose"))label3.setText("继续努力!");
label3.setBounds(70, 5, 100, 40);
add(label3);
button.setBounds(80, 50, 70, 40);
add(button);
setVisible(true);
}
}
@Override
public void mouseClicked(MouseEvent arg0) {
// TODO 自动生成的方法存根 } @Override
public void mouseEntered(MouseEvent arg0) {
// TODO 自动生成的方法存根 } @Override
public void mouseExited(MouseEvent arg0) {
// TODO 自动生成的方法存根 } @Override
public void mousePressed(MouseEvent arg0) {
// TODO 自动生成的方法存根 }
public boolean judge(int index) {
if(index>=0&&index<list.size()) {
if(list.get(index).getreal()==1)return true;
}
return false;
}
public boolean judgeLimit(int index) {
if(index>=0&&index<list.size()) return true;
return false;
}
public void show(int index) {
Bub tmp1 = list.get(index);//当前点击位置的在链表中的索引
int cnt = 0; //四周雷数的记录值
boolean edgeU = (index%colNum!= 0); //判断是否在右边界
boolean edgeD = ((index+1)%colNum!= 0); //判断是否在左边界
if(judge(index-colNum))tmp1.setface(++cnt);
if(judge(index+colNum))tmp1.setface(++cnt);
if(judge(index-1)&&edgeU)tmp1.setface(++cnt);
if(judge(index+1)&&edgeD)tmp1.setface(++cnt);
if(judge(index-colNum+1)&&edgeD)tmp1.setface(++cnt);
if(judge(index+colNum+1)&&edgeD)tmp1.setface(++cnt);
if(judge(index-colNum-1)&&edgeU)tmp1.setface(++cnt);
if(judge(index+colNum-1)&&edgeU)tmp1.setface(++cnt);
if(cnt==0) {
tmp1.setface(0);
tmp1.showImg(0);
if(!judge(index-colNum)&&judgeLimit(index-colNum)&&!list.get(index-colNum).getOpen())show(index-colNum);//为了避免这里的递归陷入了死循环,要对相邻的按钮进行判断,如果已经处于翻开状态,就不用在进一步操作
if(!judge(index+colNum)&&judgeLimit(index+colNum)&&!list.get(index+colNum).getOpen())show(index+colNum);
if(!judge(index-1)&&edgeU&&judgeLimit(index-1)&&!list.get(index-1).getOpen())show(index-1);
if(!judge(index+1)&&edgeD&&judgeLimit(index+1)&&!list.get(index+1).getOpen())show(index+1);
if(!judge(index-colNum+1)&&edgeD&&judgeLimit(index-colNum+1)&&!list.get(index-colNum+1).getOpen())show(index-colNum+1);
if(!judge(index+colNum+1)&&edgeD&&judgeLimit(index+colNum+1)&&!list.get(index+colNum+1).getOpen())show(index+colNum+1);
if(!judge(index-colNum-1)&&edgeU&&judgeLimit(index-colNum-1)&&!list.get(index-colNum-1).getOpen())show(index-colNum-1);
if(!judge(index+colNum-1)&&edgeU&&judgeLimit(index+colNum-1)&&!list.get(index+colNum-1).getOpen())show(index+colNum-1);
}
else tmp1.showImg(cnt);
}
@Override
public void mouseReleased(MouseEvent e) {
Bub tmp = (Bub)e.getSource();
int index = list.indexOf(tmp);
if(this.gameState.equals("over"))return;
else {
if(e.getButton()==MouseEvent.BUTTON1) {
if(tmp.getface()!=11&&tmp.getface()!=12) {
if(isfirst) {
tmp.setreal(1);
Random r = new Random();
int len = list.size();
for(int i = 1;i<=mineNum;++i) {
while(true) {
int des = r.nextInt(len);
if(list.get(des).getreal()!=1) {
list.get(des).setreal(1);
list.get(des).showImg(13);
break;
}
}
}
tmp.setreal(0);
isfirst = false;
show(index);
new stopwatch().start();
}
else if(tmp.getreal()!=1){
show(index);
}
else if(tmp.getreal()==1) {
for(Bub bub:list) {
if(bub.getreal()==1)bub.showImg(9);
if(bub.getreal()==0&&bub.getface()==11) {
bub.setface(10);bub.showImg(10);
}
}
gameState = "over";
button.setIcon(new ImageIcon("D:\\学习文档\\smile3.jpg"));
new Result("lose"); }
}
}
if(e.getButton()==MouseEvent.BUTTON3) {
if(tmp.getface()==13) {
tmp.setface(11);
tmp.showImg(11);
restNum--;
}
else if(tmp.getface()==11) {
tmp.setface(12);
tmp.showImg(12);
restNum++;
}
else if(tmp.getface()==12) {
tmp.setface(13);
tmp.showImg(13);
}
}
if(restNum==0) {
int total = 0;
for(Bub bub1:list) {
if(bub1.getface()==11&&bub1.getreal()==1)total++;
}
if(total==mineNum) {
gameState = "over";
button.setIcon(new ImageIcon("D:\\学习文档\\smile2.jpg"));
new Result("win");
}
}
label2.setText("剩余:"+restNum);
}
}
}
import javax.swing.ImageIcon;
import javax.swing.JButton; public class Bub extends JButton{ private int face=13; //表面上的图形显示
private int real=0; //有无雷,有雷为1,无雷为0
private boolean isOpen = false;//表明当前按钮的状态,true表示已经翻开,false表示还未翻开
private ImageIcon[]img = new ImageIcon[14];
public Bub() {
super();
img[0] = new ImageIcon("D:\\学习文档\\0mine.jpg");
img[1] = new ImageIcon("D:\\学习文档\\1mine.jpg");
img[2] = new ImageIcon("D:\\学习文档\\2mine.jpg");
img[3] = new ImageIcon("D:\\学习文档\\3mine.jpg");
img[4] = new ImageIcon("D:\\学习文档\\4mine.jpg");
img[5] = new ImageIcon("D:\\学习文档\\5mine.jpg");
img[6] = new ImageIcon("D:\\学习文档\\6mine.jpg");
img[7] = new ImageIcon("D:\\学习文档\\7mine.jpg");
img[8] = new ImageIcon("D:\\学习文档\\8mine.jpg");
img[9] = new ImageIcon("D:\\学习文档\\mine.jpg");
img[10] = new ImageIcon("D:\\学习文档\\mineerr.jpg");
img[11] = new ImageIcon("D:\\学习文档\\flag.jpg");
img[12] = new ImageIcon("D:\\学习文档\\flag2.jpg");
img[13] = new ImageIcon("D:\\学习文档\\bg.jpg");
}
public int getface() {
return face;
}
public int getreal() {
return real;
}
public void setface(int c) {
face = c;
}
public void setreal(int c) {
real = c;
}
public void setOpen(boolean swit) {
isOpen = swit;
}
public boolean getOpen() {
return isOpen;
}
public void showImg(int c) {
this.setIcon(img[c]);
if(c!=13)isOpen = true;
}
}
水品有限,代码写得很臃肿,仅限个人娱乐
乞丐版JAVA扫雷的更多相关文章
- eoLinker-AMS开源版JAVA版本正式发布
eoLinker-AMS开源版JAVA版本正式发布! eoLinker深感广大开发者的支持与厚爱,我们一直在努力为大家提供更多更好的接口服务.截止至2018年4月3日,eoLinker-AMS 开源版 ...
- 解析一下阿里出品的泰山版 Java 开发手册
说起华山,我就想起岳不群,不,令狐冲:说起泰山,我就想起司马迁,他的那句名言"人总有一死,或重于泰山,或轻于鸿毛",真的发人深省啊.这就意味着,阿里出品的泰山版 Java 开发手册 ...
- 2020阿里最新出品的泰山版Java开发手册,告别垃圾代码
说起华山,我就想起岳不群,不,令狐冲:说起泰山,我就想起司马迁,他的那句名言"人总有一死,或重于泰山,或轻于鸿毛",真的发人深省啊.这就意味着,阿里出品的泰山版 Java 开发手册 ...
- 从零打造“乞丐版” React(一)——从命令式编程到声明式编程
这个系列的目的是通过使用 JS 实现"乞丐版"的 React,让读者了解 React 的基本工作原理,体会 React 带来的构建应用的优势 1 HTML 构建静态页面 使用 HT ...
- Java版的扫雷游戏源码
package com.xz.sl; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; i ...
- Java实现QQ微信轰炸机1.2(斗图乞丐版)
之前有小可爱评论可以实现斗图的功能,原理上是行的通的,所以我就稍微改了一下,能够实现单个图片循环轰炸,如果大家感兴趣也可以自己探究实现多张图片循环轰炸,不废话了,直接上源码package QQWcha ...
- JAVA 扫雷 程序
文件列表 2.主程序入口 3.1部分源代码 package MineSweeper; import java.awt.BorderLayout; import java.awt.Font; impor ...
- Java 基础入门随笔(1) JavaSE版——java语言三种技术架构
1.java语言的三种技术架构: J2SE(java 2 Platform Standard Edition):标准版,是为开发普通桌面和商务应用程序提供的解决方案.该技术体系是其他两者的基础,可以完 ...
- “石家庄铁道大学软件工程系学生学籍管理系统2019版”java小程序制作分享
首先附上完整代码: import java.util.Scanner; public class SocreInformation { public SocreInformation(){}; pub ...
随机推荐
- H5_0005:JS判断域名和时间有效期的方法
(function () { var n = { c: function (t, e) { //console.log("c"); //把i(15)的d数组转换成字串 for (v ...
- 【转载】汇编调试程序Debug使用
https://blog.csdn.net/Notzuonotdied/article/details/70888205
- 通过<meta>标签指定IE的文档模式实现CSS3兼容
今天发现之前做好的一个页面在IE中打开显示的效果不正常,本地和服务器上显示的是两种不同的样式. 经过确认文档内容和CSS都是一样的. 通过IE F12(开发人员工具)发现不正常的样式 浏览器文档模式自 ...
- 面试经验合集-Web前端<一>
面试一:MF时间:2019-1-2 试题一 // [mf: stringify-query-string] // 类型: x z // 时长: 15 分钟 // 姓名: // 日期: // 实现下面的 ...
- Lucene的中文分词器
1 什么是中文分词器 学过英文的都知道,英文是以单词为单位的,单词与单词之间以空格或者逗号句号隔开. 而中文的语义比较特殊,很难像英文那样,一个汉字一个汉字来划分. 所以需要一个能自动识别中文语义的分 ...
- Collections -- OrderedDict类
普通dict(字典)在插入的时候并不记住元素的顺序,迭代器会根据散列表(哈希表)中存储的顺序来生成的.而OrderedDict则会记录元素的顺序,并且在迭代器输出时,会按现在记录的顺序进行遍历. 例: ...
- idea如何快速查看接口的实现类
查找接口的实现类: IDEA 风格 ctrl + alt +B 在按F2查看详细文档注解 查看类或接口的继承关系: ctrl + h
- mint-ui Picker设置指定初始值
最近做的项目公司需求是信息输入页设置地址跳转下一页后,再返回信息输入页查看信息时,地址要默认显示前面选择的地址,以此记录下,需要小伙伴可以看看 data{return{}}中设置 :slots 在 ...
- dotnet core使用开源组件FastHttpApi进行web应用开发(转)
FastHttpApi相对于asp.net mvc来说有着更轻量和性能上的优势,性能上面就不在这里介绍了(具体可查看 https://github.com/IKende/FastHttpApi). ...
- Apollo与ROS
Apollo项目基于ROS,但是对其进行了改造,主要包括下面三个方面: 通信性能优化 去中心化网络拓扑 数据兼容性扩展 通信性能优化 自动驾驶车辆中包含了大量的传感器,这些传感器可能以非常高频的速度产 ...