HeyWeGo小组《Java程序设计》

2015—2016年学期团队项目总结

题目简介

一个简单的扫雷小游戏,在12*12的方格盘上,首先可以设定雷的个数,然后点击开始程序就会随机布雷,开始游戏后如果点到雷就会显示游戏结束,如果没有,会出现数字表示周围一圈雷的个数,以此推理当扫出所有雷将显示游戏胜利。

游戏项目规划:

  1. 确定游戏中方块格子的个数
  2. 确定游戏中地雷的个数(初始10个),完成布雷
  3. 计算每个方块周围的雷数,在方块周围本身没有地雷的情况下,统计周围地雷的个数
  4. 若周围没有地雷则翻开周围的空白方格,直到周围有附近地雷的格子
  5. 设计一个检测是否挖完所有的雷的方法
  6. 设定左键点击为翻开
  7. 设定右键点开为标记

团队分工

  • 20145336 张子扬(对代码的进度进行策划,实现代码的运行,对主程序和模块进行划分及分析)
  • 20145321 曾子誉(收集资料,实现程序界面,对一些分支进行细节处理)
  • 20145235 方浩南(进行代码的编写)
  • 20145225 唐振远(实验代码检查错误,并对代码进行下一步的完善)
  • 20145331魏澍琛(发现不足,查找资料,改善体验)

代码实现及注释:

 import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Frame
extends JFrame {
JTextField text;
JLabel nowBomb, setBomb;
int BombNum, BlockNum; //当前雷数,当前方块数
int rightBomb, restBomb, restBlock; //找到的地雷数,剩余雷数,剩余方块数 JButton start = new JButton(" 开始 ");//初始化一个开始的按钮
JPanel MenuPanel = new JPanel();//新建一个区域,作为菜单
JPanel bombPanel = new JPanel();//新建一个区域,作为雷区
Bomb[][] bombButton;//2维数组,防地雷 JPanel c;
BorderLayout borderLayout1 = new BorderLayout();//布局管理器边界布局
GridLayout gridLayout1 = new GridLayout();//布局一个网格布局
public Frame() {
try {
setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭操作并结束进程
jbInit();//一般用于对程序进行初始化
}
catch (Exception exception) {//异常处理
exception.printStackTrace();
}
} private void jbInit() throws Exception {
c = (JPanel) getContentPane();//设定一个空间
setTitle("扫雷");//标题为扫雷
c.setBackground(Color.WHITE);//背景颜色为白色
MenuPanel.setBackground(Color.GRAY);//菜单颜色为灰色
c.setLayout(borderLayout1);
setSize(new Dimension(700, 700));//界面大小700*700
setResizable(false); BlockNum = 144;//设定方块数144个
BombNum = 10;//设定初始地雷数10个
text = new JTextField("10 ", 3);//设定一个字符框长度为3
nowBomb = new JLabel("当前雷数" + ":" + BombNum);
setBomb = new JLabel("设置地雷数");//标明解释
start.addActionListener(new Frame1_start_actionAdapter(this)); MenuPanel.add(setBomb);
MenuPanel.add(text);
MenuPanel.add(start);
MenuPanel.add(nowBomb);//添加菜单元素
c.add(MenuPanel, java.awt.BorderLayout.SOUTH);//给界面下方的界面设定布局 bombPanel.setLayout(gridLayout1);
gridLayout1.setColumns( (int) Math.sqrt(BlockNum));//纵列设定
gridLayout1.setRows( (int) Math.sqrt(BlockNum));//横排设定
bombButton = new Bomb[ (int) Math.sqrt(BlockNum)][ (int) Math.sqrt(BlockNum)];
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {//嵌套for循环表示所有的格子
bombButton[i][j] = new Bomb(i, j); bombButton[i][j].setFont(new Font("", Font.PLAIN, 14));//设计字体显示效果 bombButton[i][j].setForeground(Color.white);//背景颜色为白色
bombButton[i][j].addMouseListener(new Bomb_mouseAdapter(this));
bombButton[i][j].addActionListener(new Bomb_actionAdapter(this));
bombPanel.add(bombButton[i][j]);
}
}
c.add(bombPanel, java.awt.BorderLayout.CENTER);//给界面中间的界面设定布局 startBomb();
} /* 开始按钮 */ public void start_actionPerformed(ActionEvent e) {
int num=Integer.parseInt(text.getText().trim());//调用Integer.parseInt()把一个String转换成一个Double基本类型的值并赋值给了num
if (num >= 5 && num < 50) {
BombNum = num;//如果当前雷数在5-50之间
startBomb();//可以开始布雷。
}
else if (num < 5) {//如果当前雷数在5以下
JOptionPane.showMessageDialog(null, "您设置的地雷数太少了,请重设!", "错误",
JOptionPane.ERROR_MESSAGE);//消息提示框显示错误。
num=10;
BombNum = num;//自动将雷数改为10.
}
else {
JOptionPane.showMessageDialog(null, "您设置的地雷数太多了,请重设!", "错误",
JOptionPane.ERROR_MESSAGE);//同上,消息提示框提醒输入有误。
num=10;
BombNum = num;
}
}
/* 开始,布雷 */ public void startBomb() {
nowBomb.setText("当前雷数" + ":" + BombNum);//利用setText设置现在的雷数。
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {//由按钮组成的二维数组,i表示行,j表示列,构成了一个方形网格
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {//循环条件判断isRight的值,如果为false循环否则退出
bombButton[i][j].isBomb = false;//当前按钮是否为雷
bombButton[i][j].isClicked = false;//是否已被点击
bombButton[i][j].isRight = false;//是否被(标注)正确
bombButton[i][j].BombFlag = 0;//是否被标注为雷
bombButton[i][j].BombRoundCount = 9;//周围
bombButton[i][j].setEnabled(true);
bombButton[i][j].setText("");
bombButton[i][j].setFont(new Font("", Font.PLAIN, 14));//设置字体大小
bombButton[i][j].setForeground(Color.BLUE);//设置颜色为蓝色
rightBomb = 0;//正确标出的雷数为0
restBomb = BombNum;
restBlock = BlockNum - BombNum;
}
} for (int i = 0; i < BombNum; ) {
int x = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1));
int y = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1)); if (bombButton[x][y].isBomb != true) {
bombButton[x][y].isBomb = true;
i++;
}
}
CountRoundBomb();
} /* 计算方块周围雷数 */ public void CountRoundBomb() {
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {//开方 障碍数
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {
int count = 0;//当需要检测的单元格本身无雷的情况下,统计周围的地雷个数 if (bombButton[i][j].isBomb != true) {//如果不是雷
for (int x = i - 1; x < i + 2; x++) {//从左边到右,一个三个
for (int y = j - 1; y < j + 2; y++) {
if ( (x >= 0) && (y >= 0)
&& (x < ( (int) Math.sqrt(BlockNum)))
&& (y < ( (int) Math.sqrt(BlockNum)))) {//因前面x=i-1,所以排除超出边界的情况
if (bombButton[x][y].isBomb == true) {//如果是雷
count++;//加一
}
}
}
}
bombButton[i][j].BombRoundCount = count;//设置该Bomb环绕数的值
}
}
}
} /* 是否挖完了所有的雷 */ public void isWin() {
restBlock = BlockNum - BombNum;
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {
if (bombButton[i][j].isClicked == true) {
restBlock--;
}
}
} if (rightBomb == BombNum || restBlock == 0) {
JOptionPane.showMessageDialog(this, "您挖完了所有的雷,您胜利了!", "胜利",
JOptionPane.INFORMATION_MESSAGE);
startBomb();
}
} /** 当选中的位置为空,则翻开周围的地图* */ public void isNull(Bomb ClickedButton) {
int i, j;
i = ClickedButton.num_x; //点击的方块,周围地图
j = ClickedButton.num_y; for (int x = i - 1; x < i + 2; x++) { //从左边到右边,一至三个
for (int y = j - 1; y < j + 2; y++) {
if ( ( (x != i) || (y != j)) && (x >= 0) && (y >= 0)
&& (x < ( (int) Math.sqrt(BlockNum))) //因为设定x=i-1,所以排除超出边界的情况
&& (y < ( (int) Math.sqrt(BlockNum)))) {
if (bombButton[x][y].isBomb == false //如果方块中不是雷
&& bombButton[x][y].isClicked == false //如果方块未被点击
&& bombButton[x][y].isRight == false) { //如果方块未被标记
turn(bombButton[x][y]);
} //当前位置为空,周围地图被翻开
}
}
}
} /* 翻开 */ public void turn(Bomb ClickedButton) {
ClickedButton.setEnabled(false);
ClickedButton.isClicked = true; //点击方块为空,不是地雷
if (ClickedButton.BombRoundCount > 0) { //如果方块地雷环绕数>0
ClickedButton.setText(ClickedButton.BombRoundCount + ""); //标记数目
}
else {
isNull(ClickedButton); //否则,代替Null
}
} /* 左键点击 */
public void actionPerformed(ActionEvent e) {
if ( ( (Bomb) e.getSource()).isClicked == false //如果方块未被点击
&& ( (Bomb) e.getSource()).isRight == false) { //如果方块标未被记
if ( ( (Bomb) e.getSource()).isBomb == false) { //如果方块不是地雷
turn( ( (Bomb) e.getSource()));
isWin(); //当挖完雷,胜利
} else {
for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {
if (bombButton[i][j].isBomb == true) { //如果踩到雷
bombButton[i][j].setText("b"); //地雷方块上显示“b”
}
}
}
( (Bomb) e.getSource()).setForeground(Color.RED); //显示红色
( (Bomb) e.getSource()).setFont(new Font("", Font.BOLD, 20));
( (Bomb) e.getSource()).setText("X"); //显示符号“X”
JOptionPane.showMessageDialog(this, "你踩到地雷了,按确定重来", "踩到地雷", 2);
startBomb();
}
}
} /* 右键点击 */
public void mouseClicked(MouseEvent e) {
Bomb bombSource = (Bomb) e.getSource();
boolean right = SwingUtilities.isRightMouseButton(e); if ( (right == true) && (bombSource.isClicked == false)) {
bombSource.BombFlag = (bombSource.BombFlag + 1) % 3; //计算右键标记数及对应得出符号
if (bombSource.BombFlag == 1) { //如果计算得1,标记显示F
if (restBomb > 0) {
bombSource.setForeground(Color.RED); //标记显示红色
bombSource.setText("F"); //标记符号“F”
bombSource.isRight = true; //如果方块被标记
restBomb--; //那么当前地雷数减1
}
else {
bombSource.BombFlag = 0;
}
}
else if (bombSource.BombFlag == 2) { //如果计算得2,标记显示Q
restBomb++; //在F减1的基础上地雷数加1
bombSource.setText("Q"); //标记符号“Q”
bombSource.isRight = false; //方块未被标记地雷
}
else {
bombSource.setText("");
} if (bombSource.isBomb == true) { //如果方块是雷
if (bombSource.BombFlag == 1) { //如果所在方块计算得1,即标记F
rightBomb++;
}
else if (bombSource.BombFlag == 2) { //如果所在方块计算得2,即标记Q
rightBomb--;
}
}
nowBomb.setText("当前雷数" + ":" + restBomb);
isWin();
}
} public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
}
} class Frame1_start_actionAdapter
implements ActionListener {
private Frame adaptee;
Frame1_start_actionAdapter(Frame adaptee) {
this.adaptee = adaptee;
} public void actionPerformed(ActionEvent e) {
adaptee.start_actionPerformed(e);
}
} ////////////////////////////
class Bomb
extends JButton {
int num_x, num_y; //第几号方块
int BombRoundCount; //周围雷数
boolean isBomb; //是否为雷
boolean isClicked; //是否被点击
int BombFlag; //测试雷标记
boolean isRight; //是否点击右键 public Bomb(int x, int y) {
num_x = x;
num_y = y;//累的位置,获得是参数值,嵌套了两个for循环
BombFlag = 0;//是否已经插旗了
BombRoundCount = 9;//环绕数
isBomb = false;//是雷
isClicked = false;//被点击
isRight = false;//是真的
}
} class Bomb_actionAdapter
implements ActionListener {
private Frame adaptee;
Bomb_actionAdapter(Frame adaptee) {
this.adaptee = adaptee;
} public void actionPerformed(ActionEvent e) {
adaptee.actionPerformed(e);
}
} class Bomb_mouseAdapter
extends MouseAdapter {
private Frame adaptee;
Bomb_mouseAdapter(Frame adaptee) {
this.adaptee = adaptee;
} public void mouseClicked(MouseEvent e) {
adaptee.mouseClicked(e);
}
}

运行结果截图:

初始界面:

设置雷数为10,开始游戏,会显示数字:

踩到雷,游戏结束:

两种标记:

扫完雷,游戏胜利:

分数的分配

张子扬   30分

方浩南  27分

唐振远  23分

曾子誉  20分

团队贡献

张子扬:小组组长,负责给组员分配任务,掌握代码进度。对代码的架构进行划分,并协助方浩南完成部分代码。并完成图形界面和雷数的布控。

方浩南:负责编写部分前期代码,完成对周围雷数的计算、剩余雷数的计算和翻开的操作。

唐振远:负责编写后期代码,完成左右键的点击操作,并完成代码的检查,更正。

曾子誉:查阅相关资料,协助唐振远同学完成相关代码。并对代码进行后期完善,改善用户体验。

代码托管链接

http://git.oschina.net/Zziyang/Frame/tree/master

总结

通过团队项目,我们认识到了合作的重要性,紧密的合作能够提高我们的能力。代码测试过程中出现很多错误,但经过互相的合作和探讨,加以改进,便可以成功运行。 小组各组员的课程总结已发到个人博客。

HeyWeGo小组《Java程序设计》 2015—2016年学期团队项目总结的更多相关文章

  1. 20145225《Java程序设计》 2015—2016年学期课程总结

    20145225<Java程序设计> 2015—2016年学期课程总结 读书笔记链接汇总 1.2016年2月25日 <Java程序设计>课程准备之问卷调查 摘要: 一.你对自己 ...

  2. java程序设计 彩票购买抽奖程序 团队博客

    一.项目介绍 题目要求 功能要求: 模拟福利彩票36选7,实现彩票的抽奖与中奖通知功能. 1.允许注册用户,用户信息包括用户id,用户名,密码,账户金额,电话号码等属性. 2.允许注册用户购买彩票:手 ...

  3. 201521123071 《JAVA程序设计》第二周学习总结

    1. 本周学习总结 在本周的学习中,主要学习了书上的String类以及Math类等知识,但是书上学到的东西只是理论,实际打起代码来的时候会学习到更多,比如在PTA上就有学习到StringBuilder ...

  4. 2015-2016-2 《Java程序设计》项目小组博客

    2015-2016-2 <Java程序设计>项目小组博客 1451 完+美 java项目 守望先疯 JavaGroup 07_10_20_22 FromBottomToTop L.G.Su ...

  5. 《Java程序设计》学期总结

    <Java程序设计> 学期总结 课程设计小组 -迦瓦栈队 团队博客 读书笔记汇总 第一周 第二周 第三周 第四周 第五周 第六周 第七周 第八周 第九周 第十周 实验报告汇总 实验一 实验 ...

  6. 2016年1月编程语言排行榜:Java荣获2015年度冠军

    Java因于2015年人气增幅最大(+ 5.94%),故获得2015年的TIOBE指数的编程语言奖,同时成为15年年度冠军, Visual Basic.NET(+ 1.51%)和Python(+ 1. ...

  7. 2017-2018-2学期 20172324《Java程序设计》第六周学习总结

    20172324<Java程序设计>第六周学习总结 教材学习内容总结 如何创建数组以及int[] X与int X[]的区别(编译时是没有差别的,只是前者与其他类型的声明方式有一致性) 每一 ...

  8. 2016-2017 2 20155335《java程序设计》第四周总结

    #  20155335    <Java程序设计>第四周学习总结 ##  教材学习内容总结 继承,在本职上是特殊到一般的关系,即is—a关系,子类继承父类,表明子类是一种特殊的父类,并且具 ...

  9. 2015-2016-2 《Java程序设计》教学进程

    2015-2016-2 <Java程序设计>教学进程 目录 考核方式 寒假准备 教学进程 第00周学习任务和要求 第01周学习任务和要求 第02周学习任务和要求 第03周学习任务和要求 第 ...

随机推荐

  1. PHP之语句

    前面的话 任何 PHP 脚本都是由一系列语句构成的.一条语句可以是一个赋值语句,一个函数调用,一个循环,一个条件语句或者甚至是一个什么也不做的语句(空语句).语句通常以分号结束.此外,还可以用花括号将 ...

  2. 【PHP】算法: 获取满足给定值的最优组合

    PHP 获取给定值的最优组合 方法 -   (蓝洛提供,博客地址: www.zhaorui.info) <?php ini_set('error_reporting','E_ALL^E_NOTI ...

  3. Computer Science Theory for the Information Age-5: 学习理论——VC维的定义以及一些例子

    学习理论——VC维的定义以及一些例子 本文主要介绍一些学习理论上的东西.首先,我们得明确,从训练集上学习出来的分类器的最终目标是用于预测未知的样本,那么我们在训练的时候该用多少的样本才能使产生的分类器 ...

  4. Spring集成Struts、Hibernate----三大框架SSH(Spring、Struts和hibernate)

    Spring 框架可以完成业务层的设计任务,Struts框架可以将表示层和业务层分离,而Hibernate框架可以提供灵活的持久层支持.下面介绍三大框架的集成环境: 1.配置Struts2. I.导入 ...

  5. 记录用户操作历史命令history

    我们知道可以使用history命令,查看自己的操作记录,但如果你是root用户,如何查看其它用户的操作记录呢?   其实history命令只是把当前用户目录下的~/.bash_History文件内容列 ...

  6. 模反元素 RSA Euler's totient function

    https://baike.baidu.com/item/模反元素/20417595 如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除,或者说ab被n除的余数是1.这时,b就 ...

  7. s3对象存储

    bkstorages 模块帮助你在蓝鲸应用中使用多种文件存储服务作为后端,用于加速静态资源,管理用户上传文件. 自定静态文件 storage 如果通过修改配置文件满足不了你的需求,你随时可以通过继承 ...

  8. 【Javascript】Windows下Node.js与npm的安装与配置

      1:先下载Node.js,网站https://nodejs.org/en/,左侧为稳定版,右侧为最新版,推荐稳定版 2:Node.js安装,运行下载后的.msi文件,一路下一步就可以了,我选择的安 ...

  9. wget全站抓取命令

    wget -r -p -np -k http://www.freebuf.com/ 忽视,避开robots.txt,加一个-e robots=off 用wget避开robots.txt的下载限制 wg ...

  10. jquery序列化表单以及回调函数的使用

    在开发项目中.将前台的值传给后台,有时的JSP表单中的值有一两个,也有所有的值,假设这时一个个传,必然不是非常好的办法,所以使用jQuery提供的表单序列化方法,能够非常好的解决问题.同一时候能够封装 ...