JAVA_Practice_2扫雷

用swing写了一个扫雷,代码量没有想象中那么大。
注意:代码中用url获取了一个本地图片(地雷贴图),在其他电脑上运行此程序需要自行寻找贴图,保存在与类文件同一个文件夹并改名为image。原图片格式为png,若下载图片格式不同,请自行修改private static final String url = "\\image.png";中的后缀名。
以本人使用的eclipse为例,项目名为MySwing,package名为SwingTest,图片应放在MySwing\bin\SwingTest中
在这里插入图片描述
游戏效果图:
在这里插入图片描述
在这里插入图片描述

package SwingTest;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

class Coord
{
	public int row;
	public int col;
	Coord(int r,int c)
	{
		row = r;
		col = c;
	}
}

class Mine extends JButton
{
	private boolean isMine;
	private boolean visit;
	private	int mineAround;
	private int row;
	private int col;
	Mine(int num,boolean boom,int r,int c)
	{
		super();
		isMine = boom;
		visit = true;
		mineAround = num;
		row = r;
		col = c;
		super.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) {
				visit = false;
				if(flip())
				{
					Game.die();
				}
				else
				{
					Queue<Coord> queue = new LinkedList<Coord>();
					queue.add(new Coord(row,col));
					while(!queue.isEmpty())
					{
						Coord now = queue.peek();
						queue.poll();
						if(now.row!=0 && !Game.gameMap[now.row-1][now.col].isMine &&Game.gameMap[now.row-1][now.col].visit)
						{
							Game.gameMap[now.row-1][now.col].flip();
							Game.gameMap[now.row-1][now.col].visit = false;
							if(Game.gameMap[now.row-1][now.col].mineAround == 0)
								queue.add(new Coord(now.row - 1,now.col));
						}
						if(now.row!=Game.size-1 && !Game.gameMap[now.row+1][now.col].isMine && Game.gameMap[now.row+1][now.col].visit)
						{
							Game.gameMap[now.row+1][now.col].flip();
							Game.gameMap[now.row+1][now.col].visit = false;
							if(Game.gameMap[now.row+1][now.col].mineAround == 0)
								queue.add(new Coord(now.row+1,now.col));
						}	
						if(now.col!=0 && !Game.gameMap[now.row][now.col-1].isMine && Game.gameMap[now.row][now.col-1].visit)
						{
							Game.gameMap[now.row][now.col-1].flip();
							Game.gameMap[now.row][now.col-1].visit = false;
							if(Game.gameMap[now.row][now.col-1].mineAround == 0)
								queue.add(new Coord(now.row,now.col-1));
						}	
						if(now.col!=Game.size-1 && !Game.gameMap[now.row][now.col+1].isMine && Game.gameMap[now.row][now.col+1].visit)
						{
							Game.gameMap[now.row][now.col+1].flip();
							Game.gameMap[now.row][now.col+1].visit = false;
							if(Game.gameMap[now.row][now.col+1].mineAround == 0)
								queue.add(new Coord(now.row,now.col+1));
						}	
					}
				}
			}
		});
	}
	
	void setMine()
	{
		isMine = true;
	}
	
	boolean flip()
	{
		super.setEnabled(false);
		if(isMine)
		{
			super.setEnabled(true);
			Game.setButtonImage(this);
		}
		else
		{
			if(mineAround!=0)
				super.setText(""+mineAround);
			Game.flipNum++;
			if(Game.flipNum == Game.size*Game.size-Game.mineNum)
				Game.win();	
		}
		return isMine;
	}
	void add()
	{
		mineAround++;
	}
};
public class Game{
	private static final int easyModeSize = 10;
	private static final int easyModeMine = 10;
	private static final int normalModeSize = 10;
	private static final int normalModeMine = 40;
	private static final int hardModeSize = 20;
	private static final int hardModeMine = 80;
	private static Calendar initialTime;
	private static final String url = "\\image.png";
	
	static int flipNum;
	static int size;
	static int mineNum;
	static int minePos[][];
	static Mine gameMap[][];
	static JFrame mainInterface;
	static JFrame gameInterface;
	
	static void win(){
		for(int[] x:minePos)
			Game.gameMap[x[0]][x[1]].flip();
		Calendar endTime = Calendar.getInstance();
		JDialog success = new JDialog();
		success.setTitle("你赢了 用时:"+
				((endTime.get(Calendar.MINUTE)-initialTime.get(Calendar.MINUTE))*60
				+endTime.get(Calendar.SECOND)-initialTime.get(Calendar.SECOND))+"s");
		Game.setDialogImage(success);
		success.setLayout(null);
		Game.setPos(success, 40, 80);
		
		JButton restart = new JButton();
		restart.setText("重新开始");
		restart.setBounds(30, 10, 90, 30);
		
		restart.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0) {
				gameInterface.setVisible(false);
					mainInterface.setVisible(true);
					success.setVisible(false);
				}
			}
		);
		
		success.add(restart);
		success.setVisible(true);
	}
	static void die(){
		for(int[] x:minePos)
			Game.gameMap[x[0]][x[1]].flip();
		JDialog dead = new JDialog();
		dead.setTitle("你输了");
		Game.setDialogImage(dead);
		dead.setLayout(null);
		Game.setPos(dead, 40, 80);
		
		JButton restart = new JButton();
		restart.setText("重新开始");
		restart.setBounds(30, 10, 90, 30);
		
		restart.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0) {
				gameInterface.setVisible(false);
					mainInterface.setVisible(true);
					dead.setVisible(false);
				}
			}
		);
		dead.add(restart);
		dead.setVisible(true);
	}
	
	static void setMine(){
		minePos = new int[mineNum][2];
		Random rand = new Random();
		for(int i = 0;i<mineNum;i++)
		{
			minePos[i][0] = rand.nextInt(size);
			minePos[i][1] = rand.nextInt(size);
			for(int j = 0;j<i;j++)
				if(minePos[i][0]==minePos[j][0] && minePos[i][1]==minePos[j][1])
				{
					i--;
					break;
				}
		}
	}
	
	static void setGame(String difficulty){
		flipNum = 0;
		gameInterface = new JFrame();
		setFrameImage(gameInterface);
		gameInterface.setVisible(true);
		gameInterface.setTitle("扫雷"+'('+difficulty+')');
		if(difficulty.equals("easy")) {
			size = easyModeSize;
			mineNum = easyModeMine;
		}
		else if(difficulty.equals("normal")){
			size = normalModeSize;
			mineNum = normalModeMine;
		}
		else
		{
			size = hardModeSize;
			mineNum = hardModeMine;
		}
		
		setPos(gameInterface, 44*size, 44*size);
		gameInterface.setLayout(new GridLayout(size,size,0,0));
		setMine();
		
		gameMap = new Mine[size][size];
		for(int i = 0;i <size;i++)
			for(int j = 0;j<size;j++)
				{
					gameMap[i][j] = new Mine(0,false,i,j);
					gameMap[i][j].setFont((new Font("宋体",1,12)));
					gameInterface.add(gameMap[i][j]);
				}
		
		for(int[] x:minePos)
		{
			gameMap[x[0]][x[1]].setMine();
			if(x[0]!=0)
				gameMap[x[0]-1][x[1]].add();
			if(x[0]!=size-1)
				gameMap[x[0]+1][x[1]].add();
			if(x[1]!=0)
				gameMap[x[0]][x[1]-1].add();
			if(x[1]!=size-1)
				gameMap[x[0]][x[1]+1].add();
			
			if(x[0]!=0 && x[1]!=0)
				gameMap[x[0]-1][x[1]-1].add();
			if(x[0]!=0 && x[1]!=size-1)
				gameMap[x[0]-1][x[1]+1].add();
			if(x[0]!=size-1 && x[1]!=0)
				gameMap[x[0]+1][x[1]-1].add();
			if(x[0]!=size-1 && x[1]!=size-1)
				gameMap[x[0]+1][x[1]+1].add();
		}
	}
	
	static void setActionListener(JButton button,String difficulty,JFrame jf){
		button.addActionListener(
				new ActionListener()
				{
					public void actionPerformed(ActionEvent e) {
						setGame(difficulty);
						jf.setVisible(false);
						initialTime = Calendar.getInstance();
					}
				}
				);
	}
	
	static void setPos(JFrame frame,int x,int y)
	{
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setBounds((screenSize.width-x)/2, (screenSize.height-y)/2, x, y);
	}
	static void setPos(JDialog dialog,int x,int y)
	{
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		dialog.setBounds((screenSize.width-x)/2, (screenSize.height-y)/2, x, y);
	}
	
	static JFrame initial(){
		mainInterface = new JFrame();
		mainInterface.setTitle("扫雷");
		setFrameImage(mainInterface);
		mainInterface.setVisible(true);
		mainInterface.setLayout(new GridLayout(4,1,0,0));
		setPos(mainInterface,250,200);
		
		Container container = mainInterface.getContentPane();
		
		JLabel label = new JLabel("选择难度");
		label.setFont(new Font("宋体",1,20));
		label.setHorizontalAlignment(SwingConstants.CENTER);
		label.setSize(20,10);
		container.add(label);
		
		JButton easy = new JButton("简单");
		setActionListener(easy,"easy",mainInterface);
		mainInterface.add(easy);
		
		JButton normal = new JButton("一般");
		setActionListener(normal,"normal",mainInterface);
		mainInterface.add(normal);
		
		JButton hard = new JButton("困难");
		setActionListener(hard,"hard",mainInterface);
		mainInterface.add(hard);
		return mainInterface;
	}
	
	public static void setButtonImage(JButton button){
		ImageIcon myicon = new ImageIcon(Game.class.getResource(url));
		Image image = myicon.getImage().getScaledInstance(20, 20, 20);
		myicon.setImage(image);
		button.setIcon(myicon);
	}
	public static void setFrameImage(JFrame frame) {
		ImageIcon myicon = new ImageIcon(Game.class.getResource(url));
		Image image = myicon.getImage().getScaledInstance(20, 20, 20);
		frame.setIconImage(image);
	}
	public static void setDialogImage(JDialog dialog) {
		ImageIcon myicon = new ImageIcon(Game.class.getResource(url));
		Image image = myicon.getImage().getScaledInstance(20, 20, 20);
		dialog.setIconImage(image);
	}
	
	public static void main(String[] args) {
		initial();
	}

}

Version1.1
优化了一些边界条件,减少了如图的情况发生(在少数情况下依旧会发生)
在这里插入图片描述
代码更改部分:

	Mine(int num,boolean boom,int r,int c)
	{
		super();
		isMine = boom;
		visit = true;
		mineAround = num;
		row = r;
		col = c;
		super.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) {
				visit = false;
				if(flip())
				{
					Game.die();
				}
				else
				{
					Queue<Coord> queue = new LinkedList<Coord>();
					queue.add(new Coord(row,col));
					while(!queue.isEmpty())
					{
						boolean north = false,south = false,east = false,west = false;
						Coord now = queue.peek();
						queue.poll();
						if(now.row!=0 && !Game.gameMap[now.row-1][now.col].isMine &&Game.gameMap[now.row-1][now.col].visit)
						{
							Game.gameMap[now.row-1][now.col].flip();
							Game.gameMap[now.row-1][now.col].visit = false;
							if(Game.gameMap[now.row-1][now.col].mineAround == 0)
								queue.add(new Coord(now.row - 1,now.col));
							else 
								north = true;
						}
						if(now.row!=Game.size-1 && !Game.gameMap[now.row+1][now.col].isMine && Game.gameMap[now.row+1][now.col].visit)
						{
							Game.gameMap[now.row+1][now.col].flip();
							Game.gameMap[now.row+1][now.col].visit = false;
							if(Game.gameMap[now.row+1][now.col].mineAround == 0)
								queue.add(new Coord(now.row+1,now.col));
							else
								south = true;
						}
						if(now.col!=0 && !Game.gameMap[now.row][now.col-1].isMine && Game.gameMap[now.row][now.col-1].visit)
						{
							Game.gameMap[now.row][now.col-1].flip();
							Game.gameMap[now.row][now.col-1].visit = false;
							if(Game.gameMap[now.row][now.col-1].mineAround == 0)
								queue.add(new Coord(now.row,now.col-1));
							else 
								west = true;
						}	
						if(now.col!=Game.size-1 && !Game.gameMap[now.row][now.col+1].isMine && Game.gameMap[now.row][now.col+1].visit)
						{
							Game.gameMap[now.row][now.col+1].flip();
							Game.gameMap[now.row][now.col+1].visit = false;
							if(Game.gameMap[now.row][now.col+1].mineAround == 0)
								queue.add(new Coord(now.row,now.col+1));
							else
								east = true;
						}	
						if(north && west)
						{
							if(!Game.gameMap[now.row-1][now.col-1].isMine && Game.gameMap[now.row-1][now.col-1].visit)
								{
									Game.gameMap[now.row-1][now.col-1].flip();
								}
						}
						if(north && east)
						{
							if(!Game.gameMap[now.row-1][now.col+1].isMine && Game.gameMap[now.row-1][now.col+1].visit)
								{
									Game.gameMap[now.row-1][now.col+1].flip();
								}
						}
						if(south && west)
						{
							if(!Game.gameMap[now.row+1][now.col-1].isMine && Game.gameMap[now.row+1][now.col-1].visit)
								{
									Game.gameMap[now.row+1][now.col-1].flip();
								}						
						}
						if(south && east)
						{
							if(!Game.gameMap[now.row+1][now.col+1].isMine && Game.gameMap[now.row+1][now.col+1].visit)
								{
									Game.gameMap[now.row+1][now.col+1].flip();
								}
						}
					}
				}
			}
		});
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值