9.8.5 效果调整
数字都冒出来,事实上显示内容太多了。如果出现数字,我们希望不继续扫描,增加可玩性:
private void dfs(int i, int j){
if(i<0 || i >= row || j < 0 || j >= col || visited[i][j] || hasSweeper[i][j])
return;
visited[i][j] = true;
JButton b = posSweeper.get(i).get(j);
b.setEnabled(false);
--last;
int sweepCnt = getSweepCnt(i,j);
if(sweepCnt>0){
b.setText(""+sweepCnt);
return;
}
for(int x = 0; x < 4; x++){
int l = i+direction[x];
int c = j+direction[x+1];
dfs(l,c);
}
}
然后是雷的问题,点到雷应该显示所有雷的位置,那我们记录一下所有雷的位置
ListallSweeps = new ArrayList<>(); allSweeps.add(new int[]{x,y}); for(int [] sweepPos:allSweeps){ posSweeper.get(sweepPos[0]).get(sweepPos[1]).setIcon(new ImageIcon("src/resource/p1.png")); }
9.8.6 立 flag
玩的时候希望能打标记标记推出的非雷区,方便识别。
ActionListener 就不太好用了,我们用 MouseListener 的 mouseClicked, 其中 MouseEvent.BUTTON1 代表左键,MouseEvent.BUTTON3 代表右键
图片来源:https://www.iconfont.cn/search/index?searchType=icon&q=旗子
我们把之前的部分拷贝到左键,右键部分直接返回,右键一次立下旗子,两次取消
class Sweeper extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
int c = e.getButton();
JButton b = (JButton) e.getSource();
if (c == MouseEvent.BUTTON1){ //左键
int[] pos = sweeperPos.get(b);
int i = pos[0];
int j = pos[1];
if(hasSweeper[i][j]){
for(int [] sweepPos:allSweeps){
posSweeper.get(sweepPos[0]).get(sweepPos[1]).setIcon(new ImageIcon("src/resource/p1.png"));
}
int selection = JOptionPane.showConfirmDialog(MineSweeperframe.this,"你输了!","结果",
JOptionPane.DEFAULT_OPTION);
init();
}else {
dfs(i,j);
if(last == sweepCnt){
int selection = JOptionPane.showConfirmDialog(MineSweeperframe.this,"你赢了!太棒了!","结果",
JOptionPane.DEFAULT_OPTION);
init();
}
}
}else if(c==MouseEvent.BUTTON3){//右键
if(b.getIcon()==null)
b.setIcon(new ImageIcon("src/resource/flag.png"));
else
b.setIcon(null);
}
}
}
完整代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
public class Main {
public static void main(String[] args) {
Main solution = new Main();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MineSweeperframe MineSweeperframe = new MineSweeperframe();
MineSweeperframe.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);
MineSweeperframe.setVisible(true);
}
});
}
}
class MineSweeperframe extends Jframe {
public static final int W = 500;
public static final int H = 500;
Map sweeperPos = new HashMap<>();
Map> posSweeper = new HashMap<>();
boolean[][] hasSweeper;
boolean[][] visited;
int sweepCnt = 30;
int row = 10;
int col = 10;
int last = row*col;
private final int[] direction = new int[]{-1,0,1,0,-1};
List allSweeps = new ArrayList<>();
Random r = new Random();
public MineSweeperframe(){
setTitle("扫雷游戏");
setSize(W,H);
setLayout(new GridLayout(row,col));
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
JButton button = new JButton();
add(button);
sweeperPos.put(button,new int[]{i,j});
button.addMouseListener(new Sweeper());
int[] xy = sweeperPos.get(button);
posSweeper.putIfAbsent(xy[0],new HashMap<>());
posSweeper.get(xy[0]).put(xy[1],button);
}
}
init();
}
private void init(){
last = 100;
for(JButton button:sweeperPos.keySet()){
button.setEnabled(true);
button.setIcon(null);
button.setText("");
}
hasSweeper = new boolean[row][col];
visited = new boolean[row][col];
allSweeps.clear();
setSweeps();
}
private void setSweeps(){
int x = 0;
int y = 0;
int total = row*col;
for(int i = 0; i < sweepCnt; i++){
do{
int pos = r.nextInt(total);
x = pos/col;
y = pos%col;
}while (hasSweeper[x][y]);
hasSweeper[x][y] = true;
allSweeps.add(new int[]{x,y});
}
//输出,检查效果用
for(int i = 0; i < row; i++){
System.out.println(Arrays.toString(hasSweeper[i]));
}
}
class Sweeper extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
int c = e.getButton();
JButton b = (JButton) e.getSource();
if (c == MouseEvent.BUTTON1){ //左键
int[] pos = sweeperPos.get(b);
int i = pos[0];
int j = pos[1];
if(hasSweeper[i][j]){
for(int [] sweepPos:allSweeps){
posSweeper.get(sweepPos[0]).get(sweepPos[1]).setIcon(new ImageIcon("src/resource/p1.png"));
}
int selection = JOptionPane.showConfirmDialog(MineSweeperframe.this,"你输了!","结果",
JOptionPane.DEFAULT_OPTION);
init();
}else {
dfs(i,j);
if(last == sweepCnt){
int selection = JOptionPane.showConfirmDialog(MineSweeperframe.this,"你赢了!太棒了!","结果",
JOptionPane.DEFAULT_OPTION);
init();
}
}
}else if(c==MouseEvent.BUTTON3){//右键
if(b.getIcon()==null)
b.setIcon(new ImageIcon("src/resource/flag.png"));
else
b.setIcon(null);
}
}
}
private void dfs(int i, int j){
if(i<0 || i >= row || j < 0 || j >= col || visited[i][j] || hasSweeper[i][j])
return;
visited[i][j] = true;
JButton b = posSweeper.get(i).get(j);
b.setEnabled(false);
--last;
int sweepCnt = getSweepCnt(i,j);
if(sweepCnt>0){
b.setText(""+sweepCnt);
return;
}
for(int x = 0; x < 4; x++){
int l = i+direction[x];
int c = j+direction[x+1];
dfs(l,c);
}
}
private int getSweepCnt(int x, int y){
int cnt = 0;
for(int i = x-1; i <= x+1; i++){
for(int j = y-1; j <= y+1; j++){
if(i==x&&y==j) continue;
if(i<0 || i >= row || j < 0 || j >= col) continue;
if(hasSweeper[i][j]){
++cnt;
}
}
}
return cnt;
}
}
相关内容:选择 《Java核心技术 卷1》查找相关笔记
喜欢的话,点个赞吧~!平时做题,以及笔记内容将更新到公众号。



