编程之美里的挖雷游戏:

本文介绍了编程实现扫雷游戏的思路和过程。首先,通过计算每个数字周围方块的雷概率来确定界面展示。接着,详细阐述了命令行扫雷游戏的界面设计,包括数字和符号的含义。接着,描述了游戏流程,从随机生成雷的位置到计算数字,再到用户交互。最后,提到了游戏的代码实现和胜利时的界面截图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

缘由

今天的新书:编程之美 到手了,随便读了翻了一下。就翻到一个有趣的问题,计算扫雷游戏中未知方块是雷的概率。

看看图,就是那些还可以点的方块是雷的概率是多少。相信大家都玩过,我就不介绍游戏规则了。

思路

简单的思考之后,我有了一个思路:
  1. 对每一个出现的数字作如下计算
  2. 针对一个数字,统计数字周边可点击的方块的个数
  3. 数字的数值除以方块的个数,就是周边方块是雷的概率
  4. 如果多个数字计算了同一个方块的是雷的概率,则记录概率的高的那一个。
本来想看看参考答案的,翻过书的一页过去居然是空白,然后就是下一页,书上对这道题没有解答。

命令行的扫雷游戏

界面

为了验证我的想法是正确的,我决定自己先写一个命令行版扫雷游戏。
我打算用一个二维数组来来表示扫雷的界面:就16x16(书上的图的大小,但是为了和储存雷的数组统一,还是使用17x17)吧,再用一个17x17的数组存储雷的位置和各个方块的周边的雷的数量,第一列和第一行用于标识行列号。
用一些特别的符号来表示,
  1. 数字1-8已经被占了,用于表示周边方块的雷数
  2. +来表示可以点击的地方,空白的地方
  3. 空白 用来表示上图中空白的部分

流程

先对存储雷的位置和各个方块的周边的雷的数量的17x17(除去行列号应该是16x16)的数组赋值,如下
  1. 先随机生成雷的位置,雷就用99来代替吧,选用数字是为了打印方便
  2. 然后在雷的周边方块生成数字,就一个雷一个雷的计算吧,计算一个雷周边方便未变1,第二个雷计算的周边方块在原有的基础上增加1
  3. 没有雷也没有数字的地方就以0来表示。这是因为方便在第二步的时候直接加起来
  4. 界面就按上面所说的字符代表,通过输入行和列来表示点击了哪个雷
  5. 每输入一对数相当于点击了一下方块,只有+号才可以被点击
  6. 直到界面中只剩下雷没有被点的时候,游戏结束。

代码


#include <stdlib.h>
#include <stdio.h>
#include "time.h"


#define HEXAS
文件共包含有14个文件,部分代码如下: package 挖雷游戏; /** * * @author Administrator */ import java.awt.event.*; import java.awt.*; import javax.swing.*; import javax.swing.border.*; import java.util.*; import java.io.*; public class Game extends JFrame implements ActionListener { JMenuBar bar; JMenu fileMenu; JMenuItem 初级,中级,高级,扫雷英雄榜; int grade=2; MineSquare 雷阵; JButton buttonPerson; Container con; JPanel box; File 英雄榜=new File("英雄榜.txt"); Hashtable hashtable=null; Record 记录对话框=null; ShowRecord 显示英雄榜对话框=null; Game() { buttonPerson=new JButton(new ImageIcon("微笑脸.gif")); 雷阵=new MineSquare("中级",40,16,16,buttonPerson,记录对话框); buttonPerson.addActionListener(this); con=getContentPane(); con.add(雷阵,BorderLayout.CENTER); box=new JPanel(); box.setLayout(new GridLayout(1,3)); box.add(雷阵.count.textShowMine); box.add(buttonPerson); box.add(雷阵.time.textShowTime); con.add(box,BorderLayout.NORTH); setVisible(true); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); setBounds(100,50,360,380); bar=new JMenuBar(); fileMenu=new JMenu("游戏"); 初级=new JMenuItem("初级"); 中级=new JMenuItem("中级"); 高级=new JMenuItem("高级"); fileMenu.setMnemonic('G'); 初级.setMnemonic('B'); 中级.setMnemonic('I'); 高级.setMnemonic('E'); 扫雷英雄榜=new JMenuItem("扫雷英雄榜"); 初级.setMnemonic('T'); fileMenu.add(初级); fileMenu.add(中级); fileMenu.add(高级); fileMenu.add(扫雷英雄榜); bar.add(fileMenu); setJMenuBar(bar); 初级.addActionListener(this); 中级.addActionListener(this); 高级.addActionListener(this); 扫雷英雄榜.addActionListener(this); hashtable=new Hashtable(); hashtable.put("初级","初级#"+999+"#匿名"); hashtable.put("中级","中级#"+999+"#匿名"); hashtable.put("高级","高级#"+999+"#匿名"); 记录对话框=new Record(this,hashtable); 记录对话框.setGrade("高级"); if(!英雄榜.exists()) { try{ FileOutputStream out=new FileOutputStream(英雄榜); ObjectOutputStream object_out=new ObjectOutputStream(out); object_out.writeObject(hashtable); object_out.close(); out.close(); } catch(IOException e) { } } 显示英雄榜对话框=new ShowRecord(this,hashtable); validate(); } public void newGame(String grade,int number,int rows,int cols,int w,int h) { buttonPerson.setIcon(new ImageIcon("微笑脸.gif")); 记录对话框.setGrade(grade); 雷阵=new MineSquare(grade,number,rows,cols,buttonPerson,记录对话框); con.removeAll(); box.removeAll(); box.add(雷阵.count.textShowMine); box.add(buttonPerson); box.add(雷阵.time.textShowTime); con.add(box,BorderLayout.NORTH); con.add(雷阵,BorderLayout.CENTER); setBounds(10,10,w,h); validate(); } public void actionPerformed(ActionEvent e) { if(e.getSource()==初级) { grade=1; newGame("初级",10,8,8,180,220); } if(e.getSource()==中级) { grade=2; newGame("中级",40,16,16,360,380); } if(e.getSource()==高级) { grade=3; newGame("高级",99,22,22,500,520); } if(e.getSource()==扫雷英雄榜) { 显示英雄榜对话框.显示记录(); 显示英雄榜对话框.setVisible(true); } if(e.getSource()==buttonPerson) { if(grade==1) { newGame("初级",10,8,8,180,220); } if(grade==2) { newGame("中级",40,16,16,360,380); } if(grade==3) { newGame("高级",99,22,22,500,520); } } } public static void main(String args[]) { new Game(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值