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

《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(4) 扩展方向调整+菜

来源:互联网 收集:自由互联 发布时间:2022-07-14
9.8.7 扩展方向调整 我们注意到,四个方向对于推断结果不太友好,展开形状是锯齿形,可玩性有限 因此我们把四个方向的改成八个方向: private final int [][] direction = new int [][]{{ - 1 , -


《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(4) 扩展方向调整+菜单栏_intellij-idea

 

9.8.7 扩展方向调整

我们注意到,四个方向对于推断结果不太友好,展开形状是锯齿形,可玩性有限

《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(4) 扩展方向调整+菜单栏_i++_02

因此我们把四个方向的改成八个方向:

private final int[][] direction = new int[][]{{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
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 < 8; x++){
int l = i+direction[x][0];
int c = j+direction[x][1];
dfs(l,c);
}
}

效果:

《Java 核心技术 卷1》 笔记 第九章扩展 总结扫雷小项目(4) 扩展方向调整+菜单栏_i++_03

边角锯齿消失

9.8.8 菜单栏

有时候玩到一半太难了,想重来,需要退出键

JMenuBar menuBar = new JMenuBar();
JMenu operator = new JMenu("操作");
restartMenu = new JMenuItem("重新开始");
exitMenu = new JMenuItem("退出");
operator.add(restartMenu);
operator.add(exitMenu);
menuBar.add(operator);
setJMenuBar(menuBar);
restartMenu.addActionListener(this);
exitMenu.addActionListener(this);

当前类实现ActionListener接口,同时重写抽象方法:

@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == restartMenu){
init();
}else if(e.getSource() == exitMenu){
System.exit(0);
}
}

全部代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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 implements ActionListener {
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 = 10;
int row = 10;
int col = 10;
int last = row*col;
private final int[][] direction = new int[][]{{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
List<int[]> allSweeps = new ArrayList<>();

private JMenuItem restartMenu;
private JMenuItem exitMenu;
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();

JMenuBar menuBar = new JMenuBar();
JMenu operator = new JMenu("操作");
restartMenu = new JMenuItem("重新开始");
exitMenu = new JMenuItem("退出");
operator.add(restartMenu);
operator.add(exitMenu);
menuBar.add(operator);
setJMenuBar(menuBar);
restartMenu.addActionListener(this);
exitMenu.addActionListener(this);
}

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]));
}
}

@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == restartMenu){
init();
}else if(e.getSource() == exitMenu){
System.exit(0);
}
}

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 < 8; x++){
int l = i+direction[x][0];
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》 笔记 第九章扩展 总结扫雷小项目(4) 扩展方向调整+菜单栏_ico_04

至此,整个扫雷小项目就写完了,感兴趣的同学可以继续写,如添加计时器,增加表情,设置不同难度

相关内容:选择 《Java核心技术 卷1》查找相关笔记

评论

网友评论