zoukankan      html  css  js  c++  java
  • java课程设计——扫雷

    一、团队课程设计博客链接:

    https://www.cnblogs.com/luomeili/p/10280310.html

     

    二、个人负责模块或任务说明:

    模块:文件操作  Minefield类实现

    三、自己的代码提交记录截图

    四、自己负责模块或任务详细说明

    1.Minefield类实现

    Minefield是我们主要的算法实现模块。在正式开始扫雷游戏时,看见的是如下界面:一格一格的蓝色格子表示可点击区域。

    点击后,分三个情况:1)标记该区域为雷(右击)2)该区域是点击到雷,游戏结束 3)该区域无雷,显示区域九宫格范围内的雷的个数。(此处有9种情况)4)游戏提前结束,显示所有未被点击的雷。下图囊括四种情况:

    选项区域:

    这里涉及到的保存进度,下条中讲解。

    对于以上游戏功能,我们是这样实现的。

    先根据所选等级,初始化一个map数组,数组的行数和列数取决于等级。然后用Math.random()数结合循环语句和判断语句生成,将类的区域置9。其余位置元素值属于0~8,分别表示以当前位置为中心的九宫格中雷的数目。至此,map数组生成完毕。由于游戏界面中,真正显示出来的状态有13种(0~8九个数字九种,标记该位置为雷、该位置是被点击的雷、游戏成功后未被点击的雷、当前可点击区域各一种),用map数组来控制游戏界面的显示会有冲突,所以此处引入hiddenmap数组,元素数值范围为0~12,分别表示上述13种情况。对于游戏界面,其实是一个JButton数组,由于界面的美观性,用hiddenmap数组值为每个按钮分配图片,根据hiddenmap数组值分配对应的功能图片。

     生成雷:

    生成map数组其他位置的数字:

    for (int i = 0; i < getWidth(); i++)
                for (int j = 0; j < getLength(); j++) {
                    if (map[i][j] != 9) // 只对不为雷的区域进行雷数判断
                    {
                        int number = 0;
                        if (i == 0) {
                            if (j == 0) {
                                if (map[i][j + 1] == 9)
                                    number++;
                                if (map[i + 1][j] == 9)
                                    number++;
                                if (map[i + 1][j + 1] == 9)
                                    number++;
                            } else if (j == getLength() - 1) {
                                if (map[i][j - 1] == 9)
                                    number++;
                                if (map[i + 1][j] == 9)
                                    number++;
                                if (map[i + 1][j - 1] == 9)
                                    number++;
                            } else {
                                if (map[i][j - 1] == 9)
                                    number++;
                                if (map[i][j + 1] == 9)
                                    number++;
                                if (map[i + 1][j - 1] == 9)
                                    number++;
                                if (map[i + 1][j] == 9)
                                    number++;
                                if (map[i + 1][j + 1] == 9)
                                    number++;
                            }
    
                        }
                        if (i == getWidth() - 1) {
                            if (j == 0) {
                                if (map[i][j + 1] == 9)
                                    number++;
                                if (map[i - 1][j] == 9)
                                    number++;
                                if (map[i - 1][j + 1] == 9)
                                    number++;
                            } else if (j == getLength() - 1) {
                                if (map[i][j - 1] == 9)
                                    number++;
                                if (map[i - 1][j] == 9)
                                    number++;
                                if (map[i - 1][j - 1] == 9)
                                    number++;
                            } else {
                                if (map[i][j - 1] == 9)
                                    number++;
                                if (map[i][j + 1] == 9)
                                    number++;
                                if (map[i - 1][j - 1] == 9)
                                    number++;
                                if (map[i - 1][j] == 9)
                                    number++;
                                if (map[i - 1][j + 1] == 9)
                                    number++;
                            }
                        }
                        if (i != 0 && i != (getWidth() - 1)) {
                            if (j == 0) {
                                if (map[i - 1][j + 1] == 9)
                                    number++;
                                if (map[i][j + 1] == 9)
                                    number++;
                                if (map[i + 1][j + 1] == 9)
                                    number++;
                                if (map[i - 1][j] == 9)
                                    number++;
                                if (map[i + 1][j] == 9)
                                    number++;
                            }
    
                            if (j == getLength() - 1) {
                                if (map[i - 1][j - 1] == 9)
                                    number++;
                                if (map[i][j - 1] == 9)
                                    number++;
                                if (map[i + 1][j - 1] == 9)
                                    number++;
                                if (map[i - 1][j] == 9)
                                    number++;
                                if (map[i + 1][j] == 9)
                                    number++;
                            }
    
                        }
    
                        if ((i != 0) && (j != 0) && (i != getWidth() - 1) && (j != getLength() - 1)) { // 不在边缘的情况
                            // 单位九宫格内的雷数
                            for (int n = i - 1; n <= i + 1; n++)
                                for (int m = j - 1; m <= j + 1; m++)
                                    if (map[n][m] == 9)
                                        number++;
    
                        }
                        map[i][j] = number;
                    }
    
                }
        }

    所有过程中我们的操作都是对我们的hiddenmap做修改,我们的map是我们的真实雷区不做改动,接下来讲讲核心的具体实现。
    所以我们的hiddenmap刚开始都是初始化为10,当进行第一次点击的时候,如果hiddenmap下面对应的map对应的数字是0,则需要展开所有为0的区域,所以我们这里对hiddenmap进行了递归搜索为0的区域并为hiddenmap标注上去,以显示空白区域,我们的做法是对当前为0的方块检查它的上下左右不为9的方块,给它标注出来,然后对上下左右递归,直到遍历整个区域,因为我们直对当前为0的方块进行递归,所以不会使我们的递归遍历整个图,只会遍历当前区域。这个是findzero方法的具体思想。

    public void findZero(int i, int j) {
            if (hiddenmap[i][j] != 0) {
                if (map[i][j] == 0) {
                    hiddenmap[i][j] = 0;
    
                    if (i == 0) {
                        if (j == 0) {
                            if (map[i][j + 1] != 0 && map[i][j + 1] != 9)
                                hiddenmap[i][j + 1] = map[i][j + 1];
                            if (map[i + 1][j] != 0 && map[i + 1][j] != 9)
                                hiddenmap[i + 1][j] = map[i + 1][j];
                        } 
                        else if (j == length - 1) {
                            if (map[i][j - 1] != 0 && map[i][j - 1] != 9)
                                hiddenmap[i][j - 1] = map[i][j - 1];
                            if (map[i + 1][j] != 0 && map[i + 1][j] != 9)
                                hiddenmap[i + 1][j] = map[i + 1][j];
                        } 
                        else {
                            if (map[i][j - 1] != 0 && map[i][j - 1] != 9)
                                hiddenmap[i][j - 1] = map[i][j - 1];
                            if (map[i + 1][j] != 0 && map[i + 1][j] != 9)
                                hiddenmap[i + 1][j] = map[i + 1][j];
                            if (map[i][j + 1] != 0 && map[i][j + 1] != 9)
                                hiddenmap[i][j + 1] = map[i][j + 1];
                        }
                    }
    
                    if (i == width - 1) {
                        if (j == 0) {
                            if (map[i][j + 1] != 0 && map[i][j + 1] != 9)
                                hiddenmap[i][j + 1] = map[i][j + 1];
                            if (map[i - 1][j] != 0 && map[i - 1][j] != 9)
                                hiddenmap[i - 1][j] = map[i - 1][j];
                        } else if (j == length - 1) {
                            if (map[i - 1][j] != 0 && map[i - 1][j] != 9)
                                hiddenmap[i - 1][j] = map[i - 1][j];
                            if (map[i][j - 1] != 0 && map[i][j - 1] != 9)
                                hiddenmap[i][j - 1] = map[i][j - 1];
                        } else {
                            if (map[i][j + 1] != 0 && map[i][j + 1] != 9)
                                hiddenmap[i][j + 1] = map[i][j + 1];
                            if (map[i - 1][j] != 0 && map[i - 1][j] != 9)
                                hiddenmap[i - 1][j] = map[i - 1][j];
                            if (map[i][j - 1] != 0 && map[i][j - 1] != 9)
                                hiddenmap[i][j - 1] = map[i][j - 1];
                        }
                    }
    
                    if (j == 0) {
                        if (i != 0 && i != width - 1) {
                            if (map[i - 1][j] != 0 && map[i - 1][j] != 9)
                                hiddenmap[i - 1][j] = map[i - 1][j];
                            if (map[i + 1][j] != 0 && map[i + 1][j] != 9)
                                hiddenmap[i + 1][j] = map[i + 1][j];
                            if (map[i][j + 1] != 0 && map[i][j + 1] != 9)
                                hiddenmap[i][j + 1] = map[i][j + 1];
                        }
                    }
                    if (j == length - 1) {
                        if (i != 0 && i != width - 1) {
                            if (map[i - 1][j] != 0 && map[i - 1][j] != 9)
                                hiddenmap[i - 1][j] = map[i - 1][j];
                            if (map[i + 1][j] != 0 && map[i + 1][j] != 9)
                                hiddenmap[i + 1][j] = map[i + 1][j];
                            if (map[i][j - 1] != 0 && map[i][j - 1] != 9)
                                hiddenmap[i][j - 1] = map[i][j - 1];
                        }
                    }
                    if (i != 0 && i != width - 1 && j != 0 && j != length - 1) {
                        if (map[i][j + 1] != 0 && map[i][j + 1] != 9)
                            hiddenmap[i][j + 1] = map[i][j + 1];
                        if (map[i + 1][j] != 0 && map[i + 1][j] != 9)
                            hiddenmap[i + 1][j] = map[i + 1][j];
                        if (map[i][j - 1] != 0 && map[i][j - 1] != 9)
                            hiddenmap[i][j - 1] = map[i][j - 1];
                        if (map[i - 1][j] != 0 && map[i - 1][j] != 9)
                            hiddenmap[i - 1][j] = map[i - 1][j];
                    }
    
                    if (j >= 1)
                        findZero(i, j - 1);
                    if (i >= 1)
                        findZero(i - 1, j);
                    if (j <= getLength() - 2)
                        findZero(i, j + 1);
                    if (i <= getWidth() - 2)
                        findZero(i + 1, j);
                }
            }
        }

    setButton函数为JButton[][]数组每个位置放置图片:

    public void setButton(JButton button, int i, int j) {
            if (minefield.getHiddenMap()[i][j] == 0)
                button.setIcon(new ImageIcon("whilt.png"));
            if (minefield.getHiddenMap()[i][j] == 1)
                button.setIcon(new ImageIcon("whilt-1.png"));
            if (minefield.getHiddenMap()[i][j] == 2)
                button.setIcon(new ImageIcon("whilt-2.png"));
            if (minefield.getHiddenMap()[i][j] == 3)
                button.setIcon(new ImageIcon("whilt-3.png"));
            if (minefield.getHiddenMap()[i][j] == 4)
                button.setIcon(new ImageIcon("whilt-4.png"));
            if (minefield.getHiddenMap()[i][j] == 5)
                button.setIcon(new ImageIcon("whilt-5.png"));
            if (minefield.getHiddenMap()[i][j] == 6)
                button.setIcon(new ImageIcon("whilt-6.png"));
            if (minefield.getHiddenMap()[i][j] == 7)
                button.setIcon(new ImageIcon("whilt-7.png"));
            if (minefield.getHiddenMap()[i][j] == 8)
                button.setIcon(new ImageIcon("whilt-8.png"));
            if (minefield.getHiddenMap()[i][j] == 9)
                button.setIcon(new ImageIcon("boom.png"));
            if (minefield.getHiddenMap()[i][j] == 10)
                button.setIcon(new ImageIcon("blue.png"));
            if (minefield.getHiddenMap()[i][j] == 11)
                button.setIcon(new ImageIcon("red.png"));
            if (minefield.getHiddenMap()[i][j] == 12)
                button.setIcon(new ImageIcon("redboom.png"));
        }

    2..文件操作

    我们引入了文件保存的机制,为了不用保存过多的参数,而且不希望一个一个量地保存,我们把所有的操作需要用到的数据都保存到了minefield类里面,包含我们整个扫雷模块的数据,因为学习过文件处理,我们以object的形式可以把所有类都保存起来,再以同样的方式读取,并强制转换类型为minefield子类,就可以恢复我们之前保存的数据,所以我们就引入了文件保存机制,能使用户保存他的上一局未完成的游戏,我们会以用户名的形式创建一个同名的file来保存,文件保存在当前目录下。当然,如果没有上一局记录的话,就找不到我们的记录文件,我们会默认打开一个初始化的界面。

    读取上局文件:

    if (file.isNewOne() == false) {
                    try {
                        readFile = new ObjectInputStream(new FileInputStream(file.getFileName()));
                        this.minefield = (Minefield) readFile.readObject();
                        readFile.close();
                        if (minefield.isBoom() == true) {
                            boom.play();
                            upset.play();
                        } else {
                            playGame.play();
                        }
                    } catch (FileNotFoundException e) {   //不存在上局时,自动生成一局
                        this.minefield = new Minefield(file.getWidth(), file.getLength(), file.getLambnumber());
                        playGame.play();
    //                        JOptionPane.showMessageDialog(null, "您还未开始游戏,不存在上局哦,即将为您自动生成上局!");
    //                        e.printStackTrace();
                    } catch (IOException e) {
    //                        e.printStackTrace();
                    }
                    
                }

     保存进度:

    item3.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    try {
                        ObjectOutputStream dateSave = new ObjectOutputStream(new FileOutputStream(getFileName()));
                        dateSave.writeObject(minefield);
                        dateSave.close();
                    } catch (FileNotFoundException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
            });

    五、课程设计感想

    通过这次课程设计,我大大提高了自己的自主学习能力,俗话说“师傅领进门,修行在个人”,要完成如此复杂的课程设计,仅靠老师上课教授的知识是远远不够的,需要我们自己去多加学习。在学习中,还应学会提问的方法,遇文图时不要慌张,要仔细往根源去找问题,不要一有问题就寻求老师同学帮忙,要有自主解决问题的能力。

  • 相关阅读:
    jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
    jQuery 源码解析(二十三) DOM操作模块 替换元素 详解
    jQuery 源码解析(二十二) DOM操作模块 复制元素 详解
    jQuery 源码分析(二十一) DOM操作模块 删除元素 详解
    jQuery 源码分析(二十) DOM操作模块 插入元素 详解
    jQuery 源码分析(十九) DOM遍历模块详解
    python 简单工厂模式
    python 爬虫-协程 采集博客园
    vue 自定义image组件
    微信小程序 image组件坑
  • 原文地址:https://www.cnblogs.com/chenyutin/p/10279348.html
Copyright © 2011-2022 走看看