0
点赞
收藏
分享

微信扫一扫

《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(2) 扫雷图像+无雷区域扩展+数字提示


《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(2) 扫雷图像+无雷区域扩展+数字提示_ico

9.8.2 扫雷图像设置

我们注意到,点到有雷区域时,不会显示当前的雷,我们尝试用图像表达点到雷的效果:

扫到雷:

b.setIcon(new ImageIcon("src/resource/p1.png"));

输了之后的重置:

B.setIcon(null);

效果:

《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(2) 扫雷图像+无雷区域扩展+数字提示_ico_02

图片来源:https://www.iconfont.cn/collections/detail?spm=a313x.7781069.1998910419.dc64b3430&cid=29753

9.8.3 数字提示

如果点到无雷区域,应该有无雷区域扩展。为了方便看效果,把雷的个数扩展为20个。

无雷区域扩展意味着:

  1. 要记录哪些区域是已经点击过,并将它们进行扩展(BFS+visited数组)

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;

for(int x = 0; x < 4; x++){
int l = i+direction[x];
int c = j+direction[x+1];
dfs(l,c);
}

int sweepCnt = getSweepCnt(i,j);
if(sweepCnt>0){
b.setText(""+sweepCnt);
}
}

  1. 记录索引->按钮的映射关系,以便可以找到周围位置的按钮,设置已点击效果

int[] xy = sweeperPos.get(button);
posSweeper.putIfAbsent(xy[0],new HashMap<>());
posSweeper.get(xy[0]).put(xy[1],button);

《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(2) 扫雷图像+无雷区域扩展+数字提示_ico_03

9.8.4 设置数字提示

当扩展到有雷区域附近时,应该有数字提示周围剩余雷个数,为了方便看效果,宽高各设置为500:

周围8格雷个数检查:

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》 笔记 第九章扩展 总结扫雷小项目(2) 扫雷图像+无雷区域扩展+数字提示_java_04

完整代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;

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<JButton,int[]> sweeperPos = new HashMap<>();
Map<Integer,Map<Integer,JButton>> 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};
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.addActionListener(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];
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;
}

//输出,检查效果用
for(int i = 0; i < row; i++){
System.out.println(Arrays.toString(hasSweeper[i]));
}
}

class Sweeper implements ActionListener{

@Override
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
int[] pos = sweeperPos.get(b);
int i = pos[0];
int j = pos[1];

if(hasSweeper[i][j]){
b.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();

}
}
}
}

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;

for(int x = 0; x < 4; x++){
int l = i+direction[x];
int c = j+direction[x+1];
dfs(l,c);
}

int sweepCnt = getSweepCnt(i,j);
if(sweepCnt>0){
b.setText(""+sweepCnt);
}
}

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》查找相关笔记

喜欢的话,点个赞吧~!平时做题,以及笔记内容将更新到公众号。

举报

相关推荐

0 条评论