JAVA基础课程设计 简易扫雷

以下每行代码,文字均为原创,转载请注明出处.

程序一共分为7个文件,每个文件为一个类

文件名 功能描述
Test.java 测试类,包含main()函数
Mine.java 设计主界面,
Calmine.java 随机雷的位置.计算雷区点击后应该显示的数字
My_button.java 继承自button类,添加按钮的坐标x,y.
Num_Mine.java 雷数,包括用户以标记的雷数,标记正确的雷数,以及总雷数
ClickLone.java 鼠标左击处理
ClickRone.java 鼠标右击处理


Test.java

测试类,Mine()接受的三个参数分别为雷区的长,宽,总雷数

package mine_sweep;
public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Mine(16,16,20);
	}

}

Mine.java

继承自JFame类,采用BorderLayout()布局,.NORTH区域放置显示面板JPanel,提示用户以标记的雷数,.SOUTH区域放置雷区,采用GridLayout布局

用一个双重循环向雷区minepanel添加按钮,同时在buttons[]中储存该按钮的引用.

同时添加按钮监听器..在用户点击了右键后,负责更新标记的类数


package mine_sweep;
import java.awt.*;
import java.awt.event.*;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;


@SuppressWarnings("serial")
public class Mine extends JFrame {

	Integer rn;				//用户已标记的雷数
	Integer sn;				//标记对的雷数
	public Mine(int rows,int cols,int n)		//雷区的行数,列数,雷数
	{
		My_button buttons[]=new My_button[rows*cols];	//记录每个按钮的引用
		Integer mine[]= new Integer[rows*cols];			//每个位置的数字
		Boolean ismine[]=new Boolean[rows*cols];		//是否有雷的标志
		new Calmine(mine,ismine,rows,cols,n);
		this.setSize(500, 450);
		this.setTitle("mine_sweep");
		this.setLayout(new BorderLayout());		

		rn=new Integer(0);				//用户标记的雷数
		sn=new Integer(0);				//标记对的雷数
		JPanel showpanel=new JPanel();			//设置控制面板
		showpanel.setLayout(new FlowLayout(FlowLayout.LEFT));
		JTextArea showArea=new JTextArea("sum of mine: "+n);
		JTextArea showrmArea=new JTextArea("num of marked  mine: "+rn.intValue());
		showArea.setEditable(false);
		showrmArea.setEditable(false);
		showpanel.add(showrmArea );
		showpanel.add(showArea);
		this.add(showpanel,BorderLayout.NORTH);  	
		
		JPanel minepanel=new JPanel();			//设置雷区
		minepanel.setLayout(new GridLayout(rows,cols));
		minepanel.setSize(500, 450);
		Mine t=this;
		for(int i=0;i

Calmine.java

随机雷的位置.储存在ismine[]中. 并通过dx[].dy[]遍历一个按钮周围的8个位置.计算出每个按钮点击后应该显示的值,计算出的结果存储在mine[]中

注意:随机数可能产生重复的,导致雷数不够.所以,要加一个while循环放置产生重复的位置

package mine_sweep;

import java.util.Random;

public class Calmine {
	Integer mine[];
	Boolean ismine[];
	int rows,cols;
	int dx[]={-1,1,0};
	int dy[]={-1,1,0};
	int num;
	Random rd;
	Calmine(Integer m[],Boolean ism[],int r,int l,int n)
	{
		rows=r;
		cols=l;
		num=n;
		mine=m;
		ismine=ism;
		rd=new Random();
		for(int i=0;i=0&&ny>=0&&nx

My_button.java

继承自Button类,添加x,y.标记该按钮是处以雷区的的第几行第几列

package mine_sweep;

import java.awt.Button;

 @SuppressWarnings("serial")
public class My_button extends Button {
	 int x;
	 int y;
	 My_button()
	 {
		 super();
	 }
	 My_button(int a,int b)
	 {
		 super();
		 x=a;
		 y=b;
	 }
}

Num_Mine.java

存储用户以标记的雷数,标记正确的雷数,以及雷区的总雷数

package mine_sweep;

public class Num_Mine {
	Integer mark_mine;
	Integer mark_correct_mine;
	Integer sum_mine;
	Num_Mine(Integer rn,Integer sn,Integer n)
	{
		mark_mine=new Integer(rn);
		mark_correct_mine=new Integer(sn);
		sum_mine=new Integer(n);

	}

}

ClickLone.java

左击事件的处理. 分两种情况:

     1,点击的位置是雷,这时,弹出一个模态对话框显示GAME OVER,结束游戏

     2.点击的地方不是雷,这时,需要把该按钮设置为setEnabled(false).并通过mine[]数组中预先计算出应该显示的数字设置按钮标签,如果为零,这设置为空格..然后,如果点击的位置对应的mine[]的值为0,则调用BFS,不断向周围扩散,直到遇见数字或雷为止(广度优先搜索,队列)

package mine_sweep;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.LinkedList;
import java.util.Queue;

import javax.swing.JButton;
import javax.swing.JDialog;

public class ClickLone {
	My_button buttons[]; 		//按钮的引用
	int i,j;
	int rows,cols;
	Integer  mine[];
	Boolean ismine[];
	boolean used[];
	Integer rn;				//已经标记的雷数
	Mine sjm;
	int dx[]={1,-1,0};
	int dy[]={1,-1,0};
	ClickLone(My_button[] tem,int a,int b,int r,int l,Integer mines[],Boolean ismines[],Mine Jm,Integer n)
	{
		buttons=tem;
		rn=n;
		mine=mines;
		ismine=ismines;
		rows=r;
		cols=l;
		i=a;
		j=b;
		sjm=Jm;
		used=new boolean[rows*cols];
		for(int i=0;i que=new LinkedList();
		que.offer(new Integer(i*cols+j));
		while(!que.isEmpty())
		{
			int t=que.poll().intValue();
			if(new String("#").equals(buttons[t].getLabel()))		//如果该位置标记为雷,说明用户标记错误
				rn=new Integer(rn.intValue()-1);			//用户标记的雷数-1
			if(new String("0").equals(mine[t].toString()) )
				buttons[t].setLabel(" ");
			else
			{
				buttons[t].setLabel(mine[t].toString());
			}

			buttons[t].setEnabled(false);
			buttons[t].setBackground(Color.gray);
			if(mine[t].intValue()!=0)
				continue;
			i=t/cols;
			j=t%cols;
			for(int x=0;x<3;x++)
				for(int y=0;y<3;y++)
				{
					int nx=i+dx[x],ny=j+dy[y];
					if(nx>=0&&ny>=0&&nx

ClickRone.java

处理右键事件,如果该位置还没有被标记,点击后将按钮的标签设置为"#" ,如果已经被标记为"#" ,则将标记清除.

如果标记的雷数==标记对的雷数==总雷数,接结束游戏,弹出YOU WIN 对话框

package mine_sweep;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JDialog;

public class ClickRone {
	My_button buttons[];
	int x,y;
	int rows,cols;
	Mine sjm;
	Boolean ismine[];
	Num_Mine num_mine;
	ClickRone(My_button button[],int a,int b,int r,int l,Num_Mine num,Mine jm,Boolean ism[])
	{
		ismine=ism;
		buttons=button;
		num_mine=num;
		sjm=jm;
		x=a;
		y=b;
		rows=r;
		cols=l;
		if(buttons[x*cols+y].getLabel()=="#")			//该位置以被标记为雷,取消标记
		{
			num_mine.mark_mine=new Integer(num_mine.mark_mine.intValue()-1);
			buttons[x*cols+y].setBackground(Color.blue);
			buttons[x*cols+y].setLabel(" ");
			if(ismine[x*cols+y].booleanValue())			//如果该位置是雷
				num_mine.mark_correct_mine=new Integer(num_mine.mark_correct_mine.intValue()-1);
		}
		else						//加上雷的标记	
		{
			num_mine.mark_mine=new Integer(num_mine.mark_mine.intValue()+1);
			buttons[x*cols+y].setBackground(Color.yellow);
			buttons[x*cols+y].setLabel("#");
			if(ismine[x*cols+y].booleanValue())		//如果标记正确
				num_mine.mark_correct_mine=new Integer(num_mine.mark_correct_mine.intValue()+1);
		}
		if(num_mine.mark_correct_mine.intValue()==num_mine.mark_mine.intValue()
				&&num_mine.mark_mine.intValue()==num_mine.sum_mine.intValue())
		{
			JButton btc=new JButton("YOU WIN");
			JDialog dialog=new JDialog(sjm,"you_win");
			dialog.setLayout(new FlowLayout());
			dialog.addWindowListener(new WindowAdapter()		//对话框监听器
			{

				@Override
				public void windowClosing(
						WindowEvent e) {
					// TODO Auto-generated method stub
					super.windowClosing(e);
					dialog.dispose();
					sjm.dispose();
				}
				
				
			});
			btc.addActionListener(new ActionListener(){			

				@Override
				public void actionPerformed(
						ActionEvent e) {
					// TODO Auto-generated method stub
					dialog.dispose();
					sjm.dispose();
				}
				
			});
			dialog.add(btc);
			dialog.setModal(true);				//弹出you_win窗口
			dialog.setSize(220,150 );
			dialog.setLocation(350, 250);
			dialog.setVisible(true);
		}
	}
	Num_Mine repnum()
	{
		return num_mine;
	}

}

下面是运行截图: JAVA基础课程设计 简易扫雷_第1张图片

从拿到题目,到基本完成,一共用了整整一天的时间(早上八点~第二天凌晨1点).

后来用了3天改了十数个bug.终于做成了现在比较完善的程序.


你可能感兴趣的:(JAVA基础课程设计 简易扫雷)