JAVA实现经典扫雷游戏的示例代码

作者:小虚竹and掘金 时间:2022-01-26 04:20:18 

前言

windows自带的游戏《扫雷》是陪伴了无数人的经典游戏,本程序参考《扫雷》的规则进行了简化,用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。

主要需求

1、要有难度等级,初级,中级,高级

2、由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束

3、游戏主区域由很多个方格组成。使用鼠标左键随机点击一个方格,方格即被打开并显示出方格中的数字;方格中数字则表示其周围的8个方格隐藏了几颗雷。

4、用户右键可标记雷的位置

5、雷都被标记出来则胜利

主要设计

1、格子格数固定为10*10格

2、难度等级,初级:12,中级:24,高级:36

3、点击格子时,产生没有引爆的地图效果;

4、点击格子时,此格子是雷,则显示所有雷的位置,并递归清空非雷格子,结束游戏

5、实现检查所有的雷是否都被标记出来了,如果是,则胜利算法。

6、实现计时器算法,用来计时显示游戏开始多少秒

7、实现难度等级,雷数的显示

8、实现鼠标左键的实现逻辑

9、实现鼠标右键的标记逻辑

功能截图

开始界面

JAVA实现经典扫雷游戏的示例代码

左键选中格子效果

JAVA实现经典扫雷游戏的示例代码

左键选中雷效果

JAVA实现经典扫雷游戏的示例代码

右键标记雷效果

JAVA实现经典扫雷游戏的示例代码

胜利效果

JAVA实现经典扫雷游戏的示例代码

代码实现

程序启动类


   public class JMine extends JFrame implements MouseListener, ActionListener {
   private JMineArth mine;

private JMineButton[][] mineButton;

private GridBagConstraints constraints;

private JPanel pane;

private GridBagLayout gridbag;

private boolean gameStarted;

private static JCounter mineCounter;

private static JCounter timeCounter;

private Timer timer;

private Timer winTimer = new Timer();

public int numMine;

public int numFlaged;

private JMenuBar mb;

private JMenu mGame;

private JMenuItem miEasy;

private JMenuItem miMiddle;

private JMenuItem miHard;

private JMenuItem miExit;

private JMenu mHelp;

private JMenuItem miAbout;

private JPanel controlPane;

private JButton bTest;

private AboutFrame about;

private WinFrame winFrame;

private ImageIcon[] mineNumIcon = { new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("1.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("2.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("3.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("4.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("5.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("6.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("7.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("8.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("0.gif"))};

private ImageIcon[] mineStatus = { new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("flag.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("question.gif")) };

private ImageIcon[] mineBombStatus = { new ImageIcon(JMine.class.getClassLoader().getResource("0.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("mine.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("wrongmine.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("bomb.gif")) };

private ImageIcon[] faceIcon = { new ImageIcon(JMine.class.getClassLoader().getResource("smile.gif")),
   new ImageIcon(JMine.class.getClassLoader().getResource("Ooo.gif")) };

// You lose
   private void bomb(int row, int col){
   try{
   //System.out.println("Bomb!");

for (int i = 0; i < 10; i++) {
   for (int j = 0; j < 10; j++) {
   mineButton[i][j].setIcon(mineBombStatus[0]);
   int toShow;
   toShow = mine.mine[i][j] != 9 ? 0 : 1;
   mineButton[i][j].setClickFlag(true);
   if (toShow == 1 && (i != row || j != col)) {
   mineButton[i][j].setIcon(mineBombStatus[toShow]);
   mineButton[i][j].setClickFlag(true);
   } else if (toShow == 1 && (i == row && j == col)) {
   mineButton[i][j].setIcon(mineBombStatus[3]);
   mineButton[i][j].setClickFlag(true);
   } else if (toShow == 0 && mineButton[i][j].getFlag() != 1) {
   mineButton[i][j].setEnabled(false);
   } else if (toShow == 0 && mineButton[i][j].getFlag() == 1) {
   mineButton[i][j].setIcon(mineBombStatus[2]);
   mineButton[i][j].setClickFlag(true);
   }
   }
   }

timer.cancel();

}catch (Exception e){

}
   }

// check if you win() {
   private boolean isWin() {
   for (int i = 0; i < 10; i++) {
   for (int j = 0; j < 10; j++) {
   if (mine.mine[i][j] == 9 && mineButton[i][j].getFlag() != 1) {
   return (false);
   }
   if (mine.mine[i][j] != 9 && mineButton[i][j].getFlag() == 1) {
   return (false);
   }
   if (mine.mine[i][j] != 9
   && mineButton[i][j].getClickFlag() == false) {
   return (false);
   }
   }
   }
   return (true);
   }

// You Win
   private void win(){
   timer.cancel();
   winFrame.setVisible(true);

winTimer.schedule(new TimerTask(){
   public void run() {
   while(!winFrame.getWinOk()){
   }
   numMine = winFrame.getMineNum();
   winFrame.setVisible(false);
   setNewGame(numMine);
   //System.out.println("Jerry Debug:"+numMine);
   this.cancel();
   winFrame.setWinOk(false);
   }
   },0L);

}

// Constructor of the game
   public JMine() {
   super("JMine Game");
   setSize(250, 350);
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Insets space = new Insets(0, 0, 0, 0);

// Game vars
   gameStarted = false;
   numMine = 12;
   numFlaged = 0;

ImageIcon myIcon = new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif"));
   gridbag = new GridBagLayout();
   constraints = new GridBagConstraints();
   pane = new JPanel();
   pane.setLayout(gridbag);
   constraints.fill = GridBagConstraints.BOTH;
   constraints.anchor = GridBagConstraints.CENTER;

// Begin Menu Set
   mb = new JMenuBar();
   mGame = new JMenu("Game");
   miEasy = new JMenuItem("Easy");
   miEasy.addActionListener(this);
   miMiddle = new JMenuItem("Middle");
   miMiddle.addActionListener(this);
   miHard = new JMenuItem("Hard");
   miHard.addActionListener(this);
   miExit = new JMenuItem("Exit");
   miExit.addActionListener(this);
   mGame.add(miEasy);
   mGame.add(miMiddle);
   mGame.add(miHard);
   mGame.addSeparator();
   mGame.add(miExit);
   mb.add(mGame);

mHelp = new JMenu("Help");
   miAbout = new JMenuItem("About...");
   mHelp.add(miAbout);
   miAbout.addActionListener(this);
   mb.add(mHelp);
   this.setJMenuBar(mb);
   // end of Menu Set

// Control Panel
   controlPane = new JPanel();
   bTest = new JButton(faceIcon[0]);
   bTest.setSize(26, 27);
   bTest.setMargin(space);
   bTest.addMouseListener(this);
   bTest.setPressedIcon(faceIcon[1]);

mineCounter = new JCounter(numMine);
   timeCounter = new JCounter();
   controlPane.add(mineCounter);
   controlPane.add(bTest);
   controlPane.add(timeCounter);
   buildConstraints(constraints, 0, 0, 10, 2, 100, 100);
   gridbag.setConstraints(controlPane, constraints);
   pane.add(controlPane);

// Bottons
   mineButton = new JMineButton[10][10];
   for (int i = 0; i < 10; i++) {
   for (int j = 0; j < 10; j++) {
   mineButton[i][j] = new JMineButton(i, j, myIcon);
   mineButton[i][j].addMouseListener(this);
   mineButton[i][j].setMargin(space);
   buildConstraints(constraints, j, i + 3, 1, 1, 100, 100);
   gridbag.setConstraints(mineButton[i][j], constraints);
   pane.add(mineButton[i][j]);
   }
   }

// Content Pane
   setContentPane(pane);
   setLocation(200, 150);
   setVisible(true);

// About Frame
   about = new AboutFrame("JMine About");
   winFrame = new WinFrame("You win!");
   }

// Set the GUI objects positions
   void buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw,
   int gh, int wx, int wy) {
   gbc.gridx = gx;
   gbc.gridy = gy;
   gbc.gridwidth = gw;
   gbc.gridheight = gh;
   gbc.weightx = wx;
   gbc.weighty = wy;
   }

// the methods to check if there were mines, to be nested
   void checkMine(int row, int col){
   int i, j;
   i = row < 0 ? 0 : row;
   i = i > 9 ? 9 : i;
   j = col < 0 ? 0 : col;
   j = j > 9 ? 9 : j;
   //System.out.println("Check Mine row:"+i + ",col:" +j);
   if (mine.mine[i][j] == 9) {
   bomb(i, j);
   } else if (mine.mine[i][j] == 0
   && mineButton[i][j].getClickFlag() == false) {
   mineButton[i][j].setClickFlag(true);
   showLabel(i, j);
   for (int ii = i - 1; ii <= i + 1; ii++)
   for (int jj = j - 1; jj <= j + 1; jj++)
   checkMine(ii, jj);

} else {
   showLabel(i, j);
   mineButton[i][j].setClickFlag(true);
   }
   if (isWin()) {
   win();
   }
   }

private void clearAll(int row, int col){
   int top, bottom, left, right;
   top = row - 1 > 0 ? row - 1 : 0;
   bottom = row + 1 < 10 ? row + 1 : 9;
   left = col - 1 > 0 ? col - 1 : 0;
   right = col + 1 < 10 ? col + 1 : 9;
   for (int i = top; i <= bottom; i++) {
   for (int j = left; j <= right; j++) {
   if (mineButton[i][j].getFlag() != 1)
   checkMine(i, j);
   }
   }

}

private void resetAll() {
   for (int i = 0; i < 10; i++) {
   for (int j = 0; j < 10; j++) {
   mineButton[i][j].setFlag(0);
   mineButton[i][j].setClickFlag(false);
   mineButton[i][j].setIcon(mineStatus[0]);
   mineButton[i][j].setEnabled(true);
   mineButton[i][j].setVisible(true);
   }
   }
   }

// to flag the mine you want to flag out
   void flagMine(int row, int col) {
   //System.out.println("Jerry Arrives here!");
   int i, j;
   i = row < 0 ? 0 : row;
   i = i > 9 ? 9 : i;
   j = col < 0 ? 0 : col;
   j = j > 9 ? 9 : j;
   if (mineButton[i][j].getFlag() == 0) {
   numFlaged++;
   } else if (mineButton[i][j].getFlag() == 1) {
   numFlaged--;
   }
   mineCounter.resetCounter(numMine - numFlaged >= 0 ? numMine - numFlaged
   : 0);
   mineButton[i][j].setFlag((mineButton[i][j].getFlag() + 1) % 3);
   showFlag(i, j);
   if (isWin()) {
   win();
   }
   }

// show the numbers of the nearby mines
   void showLabel(int row, int col) {
   //System.out.println("ShowLabel row:" + row + ",col:" + col);
   int toShow;
   toShow = mine.mine[row][col];
   if (toShow != 0) {
   mineButton[row][col].setIcon(mineNumIcon[toShow]);
   mineButton[row][col].setClickFlag(true);
   //mineButton[row][col].setEnabled(false);
   } else {
   //mineButton[row][col].setIcon(mineNumIcon[0]);
   //mineButton[row][col].setClickFlag(true);
   mineButton[row][col].setEnabled(false);
   }
   }

// circle the flag with blank, flaged, questioned
   void showFlag(int row, int col) {
   mineButton[row][col]
   .setIcon(mineStatus[mineButton[row][col].getFlag()]);
   }

// the mouse events listener methods
   public void mouseEntered(MouseEvent e) {
   //System.out.println("Jerry Test");

}

// method to start the new game
   private void startNewGame(int num, int row, int col){
   mine = new JMineArth(num, row, col);
   //mine.printMine();
   gameStarted = true;
   timer = new Timer();
   timer.scheduleAtFixedRate(new TimerTask(){
   public void run() {
   timeCounter.counterAdd();
   //System.out.println(timeCounter.getCounterNum());
   }
   },1000,1000);
   }

public void setNewGame(int num) {
   resetAll();
   numMine = num;
   numFlaged = 0;
   gameStarted = false;
   mineCounter.resetCounter(numMine);
   timeCounter.resetCounter(0);
   }

// the event handle to deal with the mouse click
   public void mouseClicked(MouseEvent e) {
   if (e.getSource() == bTest) {
   setNewGame(numMine);
   return;
   }
   int row, col;
   row = ((JMineButton) e.getSource()).getRow();
   col = ((JMineButton) e.getSource()).getCol();
   if (!gameStarted) {
   startNewGame(numMine, row, col);
   }

if (e.getModifiers() == (InputEvent.BUTTON1_MASK + InputEvent.BUTTON3_MASK)) {
   //System.out.println("HA");
   clearAll(row, col);
   }
   if (!mineButton[row][col].getClickFlag()) {

if (e.getModifiers() == InputEvent.BUTTON1_MASK) {
   //System.out.println("LeftButton");
   if (mineButton[row][col].getFlag() == 1) {
   return;
   } else {
   checkMine(row, col);
   }
   } else if (e.getModifiers() == InputEvent.BUTTON3_MASK) {
   //System.out.println("RightButton");
   flagMine(row, col);
   } else {
   //System.out.println("MiddleButton");
   }
   }
   }

public void mousePressed(MouseEvent e) {
   //System.out.println("Jerry Press");

}

public void mouseReleased(MouseEvent e) {
   //System.out.println("Jerry Release");
   }

public void mouseExited(MouseEvent e) {
   //System.out.println("Jerry Exited");

}

public void actionPerformed(ActionEvent e) {
   try {
   if (e.getSource() == miEasy) {
   setNewGame(12);
   return;
   }
   if (e.getSource() == miMiddle) {
   setNewGame(24);
   return;
   }
   if (e.getSource() == miHard) {
   setNewGame(36);
   return;
   }
   if (e.getSource() == miExit) {
   System.exit(0);
   }
   if (e.getSource() == miAbout) {
   about.setVisible(true);
   }
   } catch (Exception ie) {
   }
   }

public static void main(String [] args) {
   JMine jmine = new JMine();
   jmine.setVisible(true);
   }
   }

地雷分布图算法类


public class JMineArth {
public int [][] mine;
private boolean fMineSet;

JMineArth(int mineNum, int row, int col) {
mine = new int[10][10];
setMine(mineNum, row, col);
setMineNum();
}

private void setMine(int mineNum, int Outrow, int Outcol) {
int col=0, row = 0, i=0;
//Math.srand(now);
while (i < mineNum) {
col = (int)(Math.random()*100)%10;
row = (int)(Math.random()*100)%10;
if (mine[col][row]==0 && (row!=Outrow || col!=Outcol || Outrow==10 )) {
mine[row][col]=9;
i++;
}
}
}

private void setMineNum() {
for ( int i=0 ; i <10; i++) {
for (int j=0; j < 10; j++) {
mine[i][j]=mine[i][j]==9?9:checkMineNum(i,j);
}
}
fMineSet = true;
}

private int checkMineNum(int ii,int jj) {
int top,bottom, left, right, count=0;
top=ii-1>0?ii-1:0;
bottom=ii+1<10?ii+1:9;
left=jj-1>0?jj-1:0;
right=jj+1<10?jj+1:9;
for (int i=top; i<=bottom; i++) {
for(int j=left; j<= right; j++) {
if (mine[i][j]==9) count++;
}
}
return(count);
}

public void printMine() {
for (int i = 0; i < 10; i++) {
for (int j=0; j < 10; j++) {
System.out.print(this.mine[i][j] + " ");
}
System.out.println();
}
}

public static void main(String[] args) {
JMineArth mine = new JMineArth(Integer.parseInt(args[0]),Integer.parseInt(args[1]),Integer.parseInt(args[2]));
mine.printMine();
}
}

来源:https://juejin.cn/post/7056745934566195230

标签:Java,扫雷
0
投稿

猜你喜欢

  • jdbc与druid连接池的使用详解

    2023-09-18 17:50:11
  • 使用newInstance()来实例化fragment并传递数据操作

    2022-07-11 15:41:57
  • Java实现驼峰和下划线互相转换的示例代码

    2023-12-16 15:23:48
  • Android性能优化及性能优化工具

    2023-11-12 09:24:00
  • JAVA中实现链式操作(方法链)的简单例子

    2022-12-16 00:54:50
  • Android自定义双向滑动控件

    2022-04-30 04:11:18
  • Eclipse+Java+Swing+Mysql实现工资管理系统

    2023-07-26 08:51:05
  • http协议进阶之Transfer-Encoding和HttpCore实现详解

    2023-11-03 14:22:05
  • Android提高之ListView实现自适应表格的方法

    2023-04-05 17:25:09
  • C# 使用Dictionary复制克隆副本及比较是否相等

    2021-05-29 21:33:06
  • Android使用SoundPool播放短音效

    2022-03-02 12:33:00
  • .Net WInform开发笔记(五)关于事件Event

    2023-11-22 01:00:18
  • SSM框架搭建图文教程(推荐)

    2023-11-10 20:39:07
  • Java的关键字与保留字小结

    2021-05-30 10:20:50
  • FragmentStatePagerAdapter保存恢复下拉刷新Fragment内存数据

    2023-07-17 20:36:40
  • java安全编码指南之:表达式规则说明

    2021-06-01 17:48:44
  • Retrofit 创建网络请求接口实例过程

    2023-11-23 22:26:43
  • Android自定义Chronometer实现短信验证码秒表倒计时功能

    2022-02-22 10:52:47
  • C#中的Socket编程详解

    2021-10-24 01:25:00
  • Quartz.Net调度框架配置解析

    2021-10-13 01:35:02
  • asp之家 软件编程 m.aspxhome.com