当前位置 : 主页 > 编程语言 > java >

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

来源:互联网 收集:自由互联 发布时间:2022-07-14
9.8.2 扫雷图像设置 我们注意到,点到有雷区域时,不会显示当前的雷,我们尝试用图像表达点到雷的效果: 扫到雷: b.setIcon(new ImageIcon("src/resource/p1.png")); 输了之后的重置: B.setIcon(


《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个。

无雷区域扩展意味着:

  • 要记录哪些区域是已经点击过,并将它们进行扩展(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);
    }
    }
  • 记录索引->按钮的映射关系,以便可以找到周围位置的按钮,设置已点击效果
  • int[] xy = sweeperPos.get(button);
    posSweeper.putIfAbsent(xy[0],new HashMap<>());
    posSweeper.get(xy[0]).put(xy[1],button);

    《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(2) 扫雷图像+无雷区域扩展+数字提示_开发语言_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) 扫雷图像+无雷区域扩展+数字提示_ico_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》查找相关笔记

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

    网友评论