`
MoonMonster
  • 浏览: 37036 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

简单扫雷--完结

    博客分类:
  • Java
阅读更多

不再做了,最后一个版本,虽然还是很多问题,代码也很难看。

1.增加刷新按钮。

2.可选难度。

3.修复一些小bug。

4.增加界面友好性。

 


 


 直接贴代码,代码中都有注释,而且扫雷都会玩,规则很简单。

 

 

 

Card.java

package version_6;
/** 
 * @author Chalmers
 *	2015年12月26日 上午10:12:46  
 */
public class Card {

	//该方块附近雷的数目
	public int count;
	//该方块是否已经被翻开
	public boolean flag;
}

 

 

 

 

MainFrame.java

package version_6;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
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.JOptionPane;
import javax.swing.JPanel;

/**
 * @author Chalmers
 * @version 创建时间:2015年12月24日 下午10:25:44
 */
/**
 * 增加刷新按钮
 * 
 */
public class MainFrame extends JFrame {

	JMenuBar menuBar = new JMenuBar();
	JMenu level = new JMenu("难度选择");
	JMenuItem easy = new JMenuItem("简单");
	JMenuItem middle = new JMenuItem("中等");
	JMenuItem harder = new JMenuItem("困难");

	// 行
	private int rowNum = 0;
	// 列
	private int colNum = 0;

	// 面板宽度
	public int width = 0;
	// 面板高度
	public int height = 0;

	// 剩余的方块数目
	private int remainCount = 0;
	// 雷的数目
	private int bomb = 10;

	// 用来存放方块的信息
	private Card[][] card = null;

	// 因为方块附近最大雷的数目为8,所以设置雷为9
	public static final int BOOM = 9;
	// 附近没有雷
	public static final int NONE = 0;

	// 考虑最极端的情况,某个位置附近有8个雷
	private String[] img = new String[] { "0.jpg", "1.jpg", "2.jpg", "3.jpg",
			"4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "boom.jpg", "flag.png" };

	private JPanel panel = null;
	// 方块
	private JLabel[][] label = null;
	// 刷新按钮
	private JButton refreshBt = null;
	// 存放按钮的面板
	private JPanel panelUp = null;

	public MainFrame(int row, int col, int count) {

		this.rowNum = row;
		this.colNum = col;
		this.bomb = count;

		width = 42 * colNum;
		height = 50 * rowNum;
		remainCount = rowNum * colNum;

		card = new Card[rowNum][colNum];
		label = new JLabel[rowNum][colNum];

		panel = new JPanel();

		panelUp = new JPanel();
		panelUp.setSize(340, 20);
		panelUp.setBorder(BorderFactory.createLineBorder(Color.BLACK));

		setJMenuBar(menuBar);
		menuBar.add(level);
		// add(level);
		level.add(easy);
		level.add(middle);
		level.add(harder);
		
		refreshBt = new JButton("刷新");
		
		ClickListener cl = new ClickListener();
		refreshBt.addActionListener(cl);
		easy.addActionListener(cl);
		middle.addActionListener(cl);
		harder.addActionListener(cl);
		
		initJLabel();

		Toolkit tool = getToolkit();
		Dimension dim = tool.getScreenSize();

		// 横竖间隔为1,1
		panel.setLayout(new GridLayout(rowNum, colNum, 1, 1));

		panelUp.setLayout(new FlowLayout());
		panelUp.add(refreshBt);

		setLayout(new BorderLayout());
		add(panel, BorderLayout.CENTER);
		add(panelUp, BorderLayout.NORTH);
		panel.setVisible(true);
		setVisible(true);
		
		// 设置在屏幕的位置和面板大小
		setBounds((int) (dim.getWidth() - width) / 2,
				(int) (dim.getHeight() - height) / 2, width, height);
		setIconImage(new ImageIcon("img\\扫雷.jpg").getImage());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 设置为不可调整大小
		setResizable(false);
		setVisible(true);
	}

	private void initJLabel() {

		initBoom();

		for (int i = 0; i < rowNum; i++) {
			for (int j = 0; j < colNum; j++) {
				label[i][j] = new JLabel();
				label[i][j].setBorder(BorderFactory
						.createLineBorder(Color.BLACK));
				// 点击事件
				label[i][j].addMouseListener(new JLabelListener(i, j));
				panel.add(label[i][j]);
			}
		}
	}

	// 初始化雷位置
	private void initBoom() {
		// 记录当前已随机生成雷的数目
		int count = 0;
		int row = 0;
		int col = 0;

		for (int i = 0; i < rowNum; i++) {
			for (int j = 0; j < colNum; j++) {
				card[i][j] = new Card();
				card[i][j].count = 0;
				card[i][j].flag = false;
			}
		}

		while (count < bomb) {

			do {
				// 随机产生雷位置
				row = (int) (Math.random() * rowNum);
				col = (int) (Math.random() * colNum);

			} while (card[row][col].count == BOOM); // 直到该位置没有雷位置
			// 在该位置设置雷
			card[row][col].count = BOOM;
			count++;
		}

		// 初始化数值
		for (int i = 0; i < rowNum; i++) {
			for (int j = 0; j < colNum; j++) {
				// 如果该处不是雷,则计算该处周围的雷的数目
				if (!(card[i][j].count == BOOM)) {
					count(i, j);
				}
			}
		}
	}

	// 将每个位置的周围的雷的数据计算出来
	private void count(int row, int col) {
		int count = 0;

		// 左上
		if (row - 1 >= 0 && col - 1 >= 0) {
			if (card[row - 1][col - 1].count == BOOM) {
				count++;
			}
		}
		// 上方
		if (row - 1 >= 0) {
			if (card[row - 1][col].count == BOOM) {
				count++;
			}
		}
		// 右上
		if (row - 1 >= 0 && col + 1 < colNum) {
			if (card[row - 1][col + 1].count == BOOM) {
				count++;
			}
		}
		// 左边
		if (col - 1 >= 0) {
			if (card[row][col - 1].count == BOOM) {
				count++;
			}
		}
		// 右边
		if (col + 1 < colNum) {
			if (card[row][col + 1].count == BOOM) {
				count++;
			}
		}
		// 左下
		if (row + 1 < rowNum && col - 1 >= 0) {
			if (card[row + 1][col - 1].count == BOOM) {
				count++;
			}
		}
		// 下边
		if (row + 1 < rowNum) {
			if (card[row + 1][col].count == BOOM) {
				count++;
			}
		}
		// 右下
		if (row + 1 < rowNum && col + 1 < colNum) {
			if (card[row + 1][col + 1].count == BOOM) {
				count++;
			}
		}

		// 将对应方块设置为计算后的数值
		card[row][col].count = count;
	}

	private class JLabelListener extends MouseAdapter {

		private int row = 0;
		private int col = 0;

		public JLabelListener(int row, int col) {
			this.row = row;
			this.col = col;
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			/*
			 * 右键点击
			 */
			if (e.getButton() == 3 && card[row][col].flag == false) {
				label[row][col].setIcon(new ImageIcon("img\\"
						+ img[img.length - 1]));

				return;
			}

			/*
			 * 左键点击
			 */
			// 如果不是雷,并且没有被点击过
			if (!(card[row][col].count == BOOM) && card[row][col].flag == false) {
				// 如果该位置附近雷数为0
				if (card[row][col].count == NONE) {
					// 进入递归
					open(row, col);
				} else {
					// 否则打开
					label[row][col].setIcon(new ImageIcon("img\\"
							+ img[card[row][col].count]));
					// 改变该位置方块状态
					card[row][col].flag = true;

					// 剩余方块-1
					remainCount--;

					// 如果剩余的方块和雷的数目一样,那么表示过关
					if (remainCount == bomb) {
						JOptionPane.showMessageDialog(null, "恭喜过关!");

						return;
					}
				}
				// 如果是雷
			} else if (card[row][col].count == BOOM
					&& card[row][col].flag == false) {
				label[row][col].setIcon(new ImageIcon("img\\" + "over.jpg"));
				card[row][col].flag = true;
				// 提醒
				JOptionPane.showMessageDialog(null, "游戏失败!!");
				// 将所有的方块翻开
				openAll();
			}
		}

		// 递归翻牌
		private void open(int row, int col) {

			if (card[row][col].count == NONE && card[row][col].flag == false) {
				label[row][col].setIcon(new ImageIcon("img\\"
						+ img[card[row][col].count]));
				// 改变方块状态,表示该方块已经被翻开
				card[row][col].flag = true;

				remainCount--;
				// 左上
				if (row - 1 >= 0 && col - 1 >= 0) {
					open(row - 1, col - 1);
				}
				// 上方
				if (row - 1 >= 0) {
					open(row - 1, col);
				}
				// 右上
				if (row - 1 >= 0 && col + 1 < colNum) {
					open(row - 1, col + 1);
				}
				// 左边
				if (col - 1 >= 0) {
					open(row, col - 1);
				}
				// 右边
				if (col + 1 < colNum) {
					open(row, col + 1);
				}
				// 左下
				if (row + 1 < rowNum && col - 1 >= 0) {
					open(row + 1, col - 1);
				}
				// 下边
				if (row + 1 < colNum) {
					open(row + 1, col);
				}
				// 右下
				if (row + 1 < rowNum && col + 1 < colNum) {
					open(row + 1, col + 1);
				}
			} else {
				if (card[row][col].flag == false) {
					label[row][col].setIcon(new ImageIcon("img\\"
							+ img[card[row][col].count]));
					card[row][col].flag = true;

					remainCount--;
				}
				return;
			}
		}

		// 翻开所有的方块
		private void openAll() {

			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					// 翻开雷牌
					if (card[i][j].flag == false && card[i][j].count == 9) {
						label[i][j].setIcon(new ImageIcon("img\\"
								+ img[card[i][j].count]));
					}
					card[i][j].flag = true;
				}
			}
		}
	}

	class ClickListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == easy) {
				setVisible(false);
				new MainFrame(9, 9, 9);
			} else if (e.getSource() == middle) {
				setVisible(false);
				new MainFrame(16, 16, 40);
			} else if (e.getSource() == harder) {
				setVisible(false);
				new MainFrame(16, 30, 99);
			} else if (e.getSource() == refreshBt) {
				// 将panel上的控件全部移除
				panel.removeAll();
				// 初始化
				initJLabel();
				// 刷新
				repaint();
				// 设置可见
				setVisible(true);
			}
		}
	}

	public static void main(String[] args) {
		new MainFrame(9, 9, 10);
	}
}

 

  • 大小: 62.5 KB
1
1
分享到:
评论

相关推荐

    kernel-devel-4.18.0-553.45.1.el8-10.x86-64.rpm

    Rocky Linux 8.10内核包

    Simulink中三阶单环多位量化Σ-Δ调制器的设计与实现-音频带ADC的应用(复现论文或解答问题,含详细可运行代码及解释)

    内容概要:本文档详细介绍了如何在Simulink中设计一个满足特定规格的音频带ADC(模数转换器)。首先选择了三阶单环多位量化Σ-Δ调制器作为设计方案,因为这种结构能在音频带宽内提供高噪声整形效果,并且多位量化可以降低量化噪声。接着,文档展示了具体的Simulink建模步骤,包括创建模型、添加各个组件如积分器、量化器、DAC反馈以及连接它们。此外,还进行了参数设计与计算,特别是过采样率和信噪比的估算,并引入了动态元件匹配技术来减少DAC的非线性误差。性能验证部分则通过理想和非理想的仿真实验评估了系统的稳定性和各项指标,最终证明所设计的ADC能够达到预期的技术标准。 适用人群:电子工程专业学生、从事数据转换器研究或开发的技术人员。 使用场景及目标:适用于希望深入了解Σ-Δ调制器的工作原理及其在音频带ADC应用中的具体实现方法的人群。目标是掌握如何利用MATLAB/Simulink工具进行复杂电路的设计与仿真。 其他说明:文中提供了详细的Matlab代码片段用于指导读者完成整个设计流程,同时附带了一些辅助函数帮助分析仿真结果。

    计算机课后习题.docx### 【计算机科学】研究生入学考试计算机组成原理专项题库设计:考研复习资源集成与优化

    内容概要:该题库专为研究生入学考试计算机组成原理科目设计,涵盖名校考研真题、经典教材课后习题、章节题库和模拟试题四大核心模块。名校考研真题精选多所知名高校的计算机组成原理科目及计算机联考真题,并提供详尽解析,帮助考生把握考研命题趋势与难度。经典教材课后习题包括白中英《计算机组成原理》(第5版)和唐朔飞《计算机组成原理》(第2版)的全部课后习题解答,这两部教材被众多名校列为考研指定参考书目。章节题库精选代表性考题,注重基础知识与重难点内容,帮助考生全面掌握考试大纲要求的知识点。模拟试题依据历年考研真题命题规律和热门考点,精心编制两套全真模拟试题,并附标准答案,帮助考生检验学习成果,评估应试能力。 适用人群:计划参加研究生入学考试并报考计算机组成原理科目的考生,尤其是需要系统复习和强化训练的学生。 使用场景及目标:①通过研读名校考研真题,考生可以准确把握考研命题趋势与难度,有效评估复习成效;②通过经典教材课后习题的练习,考生可以巩固基础知识,掌握解题技巧;③通过章节题库的系统练习,考生可以全面掌握考试大纲要求的各个知识点,为备考打下坚实基础;④通过模拟试题的测试,考生可以检验学习成果,评估应试能力,为正式考试做好充分准备。 其他说明:该题库不仅提供详细的题目解析,还涵盖了计算机组成原理的各个方面,包括计算机系统概述、数据表示与运算、存储器分层、指令系统、中央处理器、总线系统和输入输出系统等。考生在使用过程中应结合理论学习与实践操作,注重理解与应用,以提高应试能力和专业知识水平。

    __UNI__DB9970A__20250328141034.apk.1

    __UNI__DB9970A__20250328141034.apk.1

    minio-rsc-Rust资源

    rust for minio

    4-4-台区智能融合终端功能模块型式规范(试行).pdf

    国网台区终端最新规范

    《基于YOLOv8的化工管道焊缝缺陷检测系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    python源码-1个机器学习相关资源

    一个简单的机器学习代码示例,使用的是经典的鸢尾花(Iris)数据集,通过 Scikit-learn 库实现了一个简单的分类模型。这个代码可以帮助你入门机器学习中的分类任务。

    pyqt离线包,pyqt-tools离线包

    pyqt离线包,pyqt-tools离线包

    《基于YOLOv8的船舶机舱灭火系统状态监测系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    SQL常用日期和时间函数整理及使用示例

    SQL常用日期和时间函数整理及在sqlserver测试示例 主要包括 1.查询当前日期GETDATE 2.日期时间加减函数DATEADD 3 返回两个日期中指定的日期部分之间的差值DATEDIFF 4.日期格式转换CONVERT(VARCHAR(10),GETDATE(),120) 5.返回指定日期的年份数值 6.返回指定日期的月份数值 7.返回指定日期的天数数值

    GSDML-V2.3-Turck-BL20-E-GW-EN-20160524-010300.xml

    GSDML-V2.3-Turck-BL20_E_GW_EN-20160524-010300.xml

    T_CPCIF 0225-2022 多聚甲醛.docx

    T_CPCIF 0225-2022 多聚甲醛.docx

    《基于YOLOv8的智能仓储货物堆码倾斜预警系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    《基于YOLOv8的智能仓储货物堆码倾斜预警系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计

    蚕豆脱壳机设计.zip

    蚕豆脱壳机设计.zip

    附件2-2:台区智能融合终端入网专业检测单位授权委托书.docx

    台区终端电科院送检文档

    Y6一39一No23.6D离心通风机 CAD().zip

    Y6一39一No23.6D离心通风机 CAD().zip

    django自建博客app

    django自建博客app

    附件3-4:台区智能融合终端全性能试验增值税发票开具确认单.docx

    台区终端电科院送检文档

    非开挖水平定向钻机动力头装置设计.zip

    非开挖水平定向钻机动力头装置设计.zip

Global site tag (gtag.js) - Google Analytics