java的扫雷游戏-带算法解析---【课程设计】

关于毕业设计这个总目录
一定要看,因为JAVA工具,tomcat,MAVEN , idea 下载都在这篇文件当中
JAVA项目环境必知必会–【大作业及毕设项目】

本系列校训

互相伤害互相卷,玩命学习要你管,天生我才必有用,我命由我不由天!

在这里插入图片描述

环境及工具:

本系列环境

环境win11
工具idea 2020.1/idea 2018.3(为什么不使用更高的版本,一个是破解的BUG问题,一个是我用高的你用低的那就不兼容了)
jdk1.8(不管是学校还是企业里最主流的)
数据库
maven3.6.0
项目导入方式打开目录
数据库前端工具

项目说明

这个游戏工作量比较小,也比较粗糙。当做学习还是相当的不错的。当毕业设计就有点拿不出手了。但是还是相当的值得学习

总体功能

‌扫雷的规则与技巧‌
扫雷是一款考验逻辑推理和策略规划的经典游戏,其核心在于通过数字提示快速定位所有非雷区域并避免触发地雷。以下是游戏的基本规则与进阶技巧:

核心规则‌

‌目标与判定标准‌

玩家需在限定时间内通过点击格子揭示数字或空白区域,目标是在所有剩余格子中排除地雷,同时避免触发任何地雷格(标记为“地雷”)。若误触地雷格或无法通过逻辑推理完成游戏,则判定失败。‌‌

游戏胜利条件:当场上仅剩地雷格未被开启时,若所有非地雷格均被正确识别,则游戏胜利;否则失败。‌‌

‌数字含义‌

每个数字表示以该格为中心的3×3区域(角落或边线为8邻近格)内地雷的数量。例如:
数字“1”表示周围有1个地雷;
数字“3”表示周围有3个地雷。‌‌

‌操作方式‌

使用鼠标左键点击格子以开启区域;
右键标记疑似地雷的格子(插旗)或不确定的区域(问号),标记后该格不可再次开启。‌‌

‌关键技巧‌

‌基础策略‌

‌从边缘入手‌:优先从边缘区域展开推理,逐步向中心推进,减少误判风险。‌‌

‌稳定点击节奏‌:避免连续快速点击同一区域,以防触发地雷。‌‌

‌合理利用标记‌:标记已知地雷和疑问区域,减少试错成本。‌‌

‌逻辑推理技巧‌

‌阵型分析‌:识别特定数字组合的排列规律(如“123”阵型),推断安全区域(例如:若数字“2”下方为雷,则相邻的“1”下方也必有雷,形成矛盾)。‌‌

‌数字守恒原则‌:高级关卡中剩余雷数固定(如99颗),若某区域出现大片空白,则剩余区域雷密度可能更高。‌‌

‌试错与收尾‌:在确定剩余雷数后,通过试错法验证小范围区域的地雷位置。‌‌

‌进阶战术‌

‌平行边处理‌:若数字两侧均为空白区域且无其他线索,可推断该行或列无雷。‌‌

‌时间管理‌:高级模式需注意时间限制,优先处理高密度数字区域以压缩剩余搜索范围。‌‌

‌全局视角‌:整合所有已知信息(数字、标记),通过交叉验证排除错误假设。‌‌

‌实战建议‌

‌练习与经验积累‌:扫雷是策略性游戏,需通过反复练习熟悉常见阵型和逻辑漏洞。‌‌

‌心态调整‌:避免因失误导致情绪化操作,保持冷静分析每一步决策的合理性。‌‌

代码部分

文件编码问题。不太熟悉JAVA的同学请不要随意怀疑本程序运行出错,或不能运行,盲目修改文件

在这里插入图片描述

import javax.swing.*;
import java.awt.event.*;
import javax.swing.border.*;
import java.awt.*;
import java.util.*;
import java.applet.*;
import java.net.*;
import java.io.*;
public class saolei extends JFrame implements ActionListener,MouseListener,Runnable{
	JFrame frame = new JFrame("扫雷游戏");
	int x=1;  //是否启动线程
	int flagcount=0;//标记数量
	int wanchenglei=0;//成功标记雷数
	String dengji;//等级
	JButton start;
	int width=50;
	int height=50;
	int flag=0;//完成雷数
	int N=5;//雷数
	Graphics g;
	Boolean Gaming=false; //游戏是否开始
	int weibu=0;  //布雷变量
	int totalscore;//得分
	int totaltime=200;//时间
	Thread t=new Thread(this);//第二线程
	int A[][]=new int[10][10];//雷的标记
	int B[][]=new int[10][10];//标记该格子是否已经点过
	int C[][]=new int[10][10];
	JLabel score=new JLabel("总分:0");
	JLabel time=new JLabel("时间:0");
	JLabel leishu=new JLabel("雷数:");
	Image im,qi; //两个图片
	JMenuBar jb=new JMenuBar();  //菜单条
	JMenu jm=new JMenu("选择难度");
	JMenuItem cainiao,zhongdeng,gaoshou,paihang;
	AudioClip au,aau,aaau;  //声音变量
	URL backurl,xiaziurl,baozhaurl;//声音路径
	saolei(){
		ImageIcon i=new ImageIcon("start.gif");

		try{
			xiaziurl=getClass().getResource("ding.wav");
			baozhaurl=getClass().getResource("bob.wav");	//加载声音
			backurl=getClass().getResource("music.mid");

			au=JApplet.newAudioClip(backurl);
			aau=JApplet.newAudioClip(xiaziurl);
			aaau=JApplet.newAudioClip(baozhaurl);
			au.loop();
		}
		catch(Exception e){
			System.err.println("e.getMessage()");}




		dengji="菜鸟";

		Border border=BorderFactory.createTitledBorder("游戏状态");
		JPanel p=new JPanel();
		start=new JButton(i);
		p.setBorder(border);
		p.setLayout(null);
		p.add(score);
		p.add(time);
		p.add(leishu);
		p.add(start);
		frame.setLayout(null);
		score.setBounds(0,10,80,40);
		time.setBounds(100,10,80,40);
		leishu.setBounds(200,10,40,40);
		start.setBounds(300,10,40,40);             //游戏界面代码
		start.addActionListener(this);
		frame.addMouseListener(this);
		frame.add(p);

		p.setBounds(100,10,400,40);
		cainiao=new JMenuItem("菜鸟级别");
		zhongdeng=new JMenuItem("中等级别");
		gaoshou=new JMenuItem("高手级别");
		paihang=new JMenuItem("排行榜");
		cainiao.addActionListener(this);
		zhongdeng.addActionListener(this);
		gaoshou.addActionListener(this);
		paihang.addActionListener(this);

		jm.add(cainiao);
		jm.addSeparator();
		jm.add(zhongdeng);
		jm.addSeparator();
		jm.add(gaoshou);
		jm.addSeparator();
		jb.add(jm);
		jb.add(paihang);


		frame.setJMenuBar(jb);
		frame.setLocation(200,10);
		frame.setSize(540,650);
		frame.setVisible(true);

		frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
		Image back=getToolkit().getImage("lei.gif");
		frame.setIconImage(back);
		g=frame.getGraphics();
		im=getToolkit().getImage("lei.gif");    // 获取图片
		qi=getToolkit().getImage("qi.gif");
		leishu.setForeground(Color.red);
		time.setForeground(Color.red);          //设置标签背景色
		score.setForeground(Color.red);

	}
	public void start(){
		t.start();


	}
	public void run(){
		x=0;

		for(;;){
			if(Gaming){          //无限循环

				try{
					t.sleep(1000);

					totaltime-=1;
					time.setText("时间:"+totaltime);  //倒记时
					if(flag==100 && wanchenglei<N)      //判断格子用完 且 完成雷数小于N  就结束游戏
					{ Gaming=false;
						lei();
						end("你输了!!!");
						defen();

					}
				}
				catch(Exception e){}
			}

			if(totaltime<=0)
			{Gaming=false;

				lei();

				end("时间到!");   //时间为零  结束游戏
				qingkong();}


		}

	}







	void draw(){                //绘制窗格



		g.setColor(frame.getBackground());
		g.fillRect(0,100,600,540);
		g.setColor(Color.red);
		int i,j;

		for(i=0;i<10;i++)
		{

			for(j=0;j<10;j++)

			{


				g.draw3DRect(i*50+10,j*50+130,width,height,true);



			}


		}





	}




	void randbulei(int n)     //随即布雷
	{

		Random r=new Random();

		for(int i=0;i<n;i++)

		{
			int t=Math.abs(r.nextInt()%10);
			int f=Math.abs(r.nextInt()%10);

			A[t][f]=1;



		}

		if(isfull())
			Gaming=true;
		else
			randbulei(weibu);


	}


	Boolean isfull(){             //判断布雷数量是否已经达到N

		int t=0;


		for(int i=0;i<10;i++)
		{

			for(int j=0;j<10;j++)
			{
				if(A[i][j]==1)
					t+=1;


			}





		}

		if(t<N)
		{weibu=N-t;


			return false;
		}

		else
			return true;



	}

	void playback(){                //背景音乐播放

		au.play();



	}






	int leicount(int i,int j){

		if(i>=0 && j>=0 && i<=9 && j<=9){     //判断鼠标点中的格子是否有雷  如果雷数为 0  就染色并标记b  数组 ...  如果为1 或2...  就显示数字


			if(B[i][j]!=1 && A[i][j]!=1){

				if(shuzi(i,j)==0 ){

					g.setColor(new Color(248,226,100));
					g.fillRect(i*50+10,j*50+130,width,height);
					g.setColor(Color.black);
					g.drawRect(i*50+10,j*50+130,width,height);
					B[i][j]=1;
					flag+=1;
					return 0;

				}


				else{

					g.setFont(new Font("宋体",Font.BOLD,28));
					g.setColor(new Color(240,150,150));

					g.fillRect(i*50+10,j*50+130,width,height);
					g.setColor(Color.red);
					g.drawString(String.valueOf(shuzi(i,j)),i*50+30,j*50+160);
					g.setColor(Color.red);
					g.drawRect(i*50+10,j*50+130,width,height);
					B[i][j]=1;

					flag+=1;

					return  shuzi(i,j);
				}


			}


		}



		return -1;


	}

	int shuzi(int i,int j){    //雷数

		int shu=0;
		if(i>0 && i<9 && j>0 && j<9)

			shu=count(i-1,j-1)+count(i-1,j)+count(i-1,j+1)+count(i,j-1)+count(i,j+1)+count(i+1,j-1)+count(i+1,j)+count(i+1,j+1);

		if(i==0 && j==0)

			shu=count(i,j+1)+count(i+1,j+1)+count(i+1,j);

		if(i==0 && j==9)
			shu=count(i,j-1)+count(i+1,j-1)+count(i+1,j);

		if(i==9 && j==0)
			shu=count(i-1,j)+count(i-1,j+1)+count(i,j+1);

		if(i==9 && j==9)
			shu=count(i-1,j)+count(i-1,j-1)+count(i,j-1);

		return shu;

	}

	int count(int i,int j){



		if(A[i][j]==1)
			return 1;
		else

			return 0;

	}

	void qingkong(){

		for(int i=0;i<10;i++)   //数组清空
		{

			for(int j=0;j<10;j++)
			{	A[i][j]=0;
				B[i][j]=0;
				C[i][j]=0;
			}

		}


	}

	void end(String s){              //游戏结束




		g.setFont(new Font("宋体",Font.BOLD,72));
		g.setColor(Color.green);

		g.drawString(s,100,330);


	}


	void play(){

		aau.play();    //鼠标单机声音


	}


	public void mouseClicked(MouseEvent e){

		int x1=0,y1=0;                //判断鼠标单机范围 确定数组下标


		if(e.getX()>60){

			x1=(e.getX()-10)/50;

		}
		else
		{x1=0;}
		if(e.getY()>180)
		{y1=(e.getY()-130)/50;	}
		else
		{
			if(e.getY()>150)
				y1=0;}
		if(e.getButton()==3)
			youji(x1,y1);
		else

		{  if(Gaming)
		{
			if(A[x1][y1]==1)                  //该格子有雷  炸死

			{      g.setColor(Color.red);
				g.fillRect(x1*50+10,y1*50+130,width,height);



				Gaming=false;
				aaau.play();
				lei();

				end("你被炸死了!!!");
				defen();
				qingkong();

			}
			else
			{
				int i=leicount(x1,y1);


				if(i==0)
				{
					jiance(x1,y1);
				}


			}


		}
		}
		play();
	}


	void jiance(int x1,int y1){
		//该格子无雷 递归调用



		if(leicount(x1-1,y1)==0 )

			jiance(x1-1,y1);

		if(leicount(x1-1,y1-1)==0 )
			jiance(x1-1,y1-1);

		if(leicount(x1-1,y1+1)==0)
			jiance(x1-1,y1+1);

		if(leicount(x1,y1-1)==0)
			jiance(x1,y1-1);

		if(leicount(x1,y1+1)==0)
			jiance(x1,y1+1);

		if(leicount(x1+1,y1-1)==0)
			jiance(x1+1,y1-1);

		if(leicount(x1+1,y1)==0)
			jiance(x1+1,y1);

		if(leicount(x1+1,y1+1)==0)
			jiance(x1+1,y1+1);

	}


	void lei(){



		//雷暴炸后显示所有雷



		for(int i=0;i<10;i++)
		{

			for(int j=0;j<10;j++)
			{	if(A[i][j]==1)
				g.drawImage(im,i*50+20,j*50+140,this);

			}

		}



	}
	void defen(){


		for(int i=0;i<10;i++){

			for(int j=0;j<10;j++){



				if((C[i][j]==1 ) && ( A[i][j]==1))    //计算得分
				{	totalscore+=1000/(200-totaltime);

					score.setText("总分:"+totalscore);



				}
			}

		}

		write();












	}
	public void mousePressed(MouseEvent e){}
	public void mouseExited(MouseEvent e){}
	public void mouseEntered(MouseEvent e){}
	public void mouseReleased(MouseEvent e){}


	void youji(int i,int j){            //鼠标右机判断

		if(B[i][j]!=1){

			g.drawImage(qi,i*50+20,j*50+140,this);
			if(A[i][j]==1)
				wanchenglei+=1;


			flagcount+=1;

			B[i][j]=1;	C[i][j]=1;
			flag+=1;
		}
		if(flagcount==N && wanchenglei<N)
		{lei();
			end("Game Over");
			defen();

			Gaming=false;
		}


		if(wanchenglei==N)
		{lei();
			end("You Win");
			defen();
			Gaming=false;

		}















	}

	public void actionPerformed(ActionEvent e){     //菜单和按纽事件

		if(e.getSource()==cainiao)
		{totaltime=200;	N=5;leishu.setText("雷数"+N);dengji="菜鸟";}
		if(e.getSource()==zhongdeng)
		{totaltime=150;	N=15;leishu.setText("雷数"+N);dengji="中等";  }
		if(e.getSource()==gaoshou)
		{totaltime=100;	N=25;leishu.setText("雷数"+N);dengji="高手";}

		if(e.getSource()==paihang)
			read();


		if(e.getSource()==start)
		{	draw();
			flag=0;
			qingkong();
			randbulei(N);
			totalscore=0;
			wanchenglei=0;
			flagcount=0;
			score.setText("总分:"+totalscore);
			if(dengji=="菜鸟")
				totaltime=200;
			if(dengji=="中等")
				totaltime=150;
			if(dengji=="高手")
				totaltime=100;

			if(x==1)
				start();


		}
	}

	void write(){    //记录保存




		try{
			InputStream fo1=new FileInputStream("record.txt");
			DataInputStream  fi1=new DataInputStream(fo1);

			if(fi1.readInt()<totalscore)

			{fo1.close();

				String s=JOptionPane.showInputDialog(frame,"纪录","请输入您的姓名");
				OutputStream fi=new FileOutputStream("record.txt");
				DataOutputStream fo=new DataOutputStream(fi);

				fo.writeInt(totalscore);
				fo.writeUTF(s);
				fi.close();
				JOptionPane.showMessageDialog(frame,"记录保存成功");

			}
			fo1.close();

		}catch(Exception e){}







	}

	void read(){
		int fen=0;                          //读取记录
		String s="";




		try{
			InputStream fo=new FileInputStream("record.txt");
			DataInputStream  fi=new DataInputStream(fo);

			fen=fi.readInt();
			s=fi.readUTF();

			fo.close();
		}catch(Exception e){}
		JOptionPane.showMessageDialog(frame,"目前记录保持着是:"+s+"\n"+"总分是:"+fen);







	}


	public static void main(String args[]){

		new saolei();


	}





}

找到关键核心代码的方法:
应用软件的核心代码是指这个程序最关键部分的代码。例如WinRAR,它的核心代码就是压缩算法部分,而诸如用户界面、操作系统移植等部分就无足轻重了。
商城类的核心代码是指业务层的代码,比如你商城的核心代码就是:商品、购物车、创建订单、支付这些代码就是核心代码。

作为程序员,我们经常需要看懂别人的代码。特别是在开源社区中,我们需要理解许多优秀的开源项目的代码。而在Gitee这样的代码托管平台上,我们如何快速有效地看懂别人的代码呢?本文将为大家介绍一些方法。

1.阅读README和项目介绍

在Gitee上,许多开源项目都会有自己的README文件或项目介绍。这些文件一般会介绍项目的背景、功能、使用方法等内容,可以帮助我们快速了解这个开源项目的基本情况。如果我们能够从这些文件中找到与自己相关的内容,就可以快速入手这个开源项目的代码。

2.了解项目结构和代码组织

在阅读代码之前,我们需要先了解这个开源项目的代码结构和代码组织方式。通常,开源项目会将不同的功能模块封装到不同的代码文件中,并按照一定的目录结构组织起来。如果我们能够了解这个开源项目的代码组织方式,就能更加快速地找到所需的代码。

3.利用IDE和工具

IDE和一些代码阅读工具可以帮助我们更快速、更高效地阅读代码。例如,Java开发者可以使用Eclipse或IntelliJ IDEA这样的IDE,可以快速打开代码文件、查看类、方法和变量等信息。另外,一些代码阅读工具,如Source Insight、CodeCompare等,可以帮助我们更方便地查看代码的结构和关系,以及快速跳转到相关代码。

4.关注代码注释和文档

良好的代码注释和文档可以帮助我们更快速地理解代码。因此,在阅读别人的代码时,我们可以将注意力放在代码注释和文档上。有些开源项目会提供详细的文档,有些则注重代码注释。如果我们能够针对代码注释和文档有一个系统的阅读和理解,就能更快速地掌握别人的代码。

5.跑通测试和运行项目

如果我们想更深入地了解别人的代码,可以试着跑通相关的测试,或者直接运行这个开源项目。通过跑测试和运行项目,我们可以更加直观地了解代码的实现细节和具体的业务逻辑。

总结:

以上就是在Gitee上快速理解他人代码的一些方法,希望对大家有所帮助。当然,阅读代码是一件需要耐心和细心的事情,需要我们多花一点时间和心思。只有沉下心来,慢慢阅读每一行代码,才能真正理解它们的含义和作用。

运行的界面

当然了,这里为了调试的方便,事实上,这个代码起初有不少BUG,主要就是因为点位取的时候,碰到了windows 的字体变大,
需要重置一次级别。

在这里插入图片描述

总结

就一句,真的很实用,真的太实用了了。

以前的学习的人,没有那么正规,但是潜下心写代码。现在的人呢?除了各种网络的BBLL,真心写代码的还能找不到工作?每个人都是springBoot ,甚至springcloud 起步,但是实际的分析能力真的是…

配套资源

JAVA版本扫雷最初级版本–【课程设计】

https://download.csdn.net/download/dearmite/90199877

JAVA设计扫雷(程序) 游戏的源代码-课程设计(本文章截图都来自这个代码)
https://download.csdn.net/download/dearmite/88224292

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

项目张雪峰之巅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值