【问题标题】:what is wrong with my MineSweeper dot java我的 MineSweeper dot java 出了什么问题
【发布时间】:2015-02-28 20:53:40
【问题描述】:

我正在构建扫雷背后的逻辑,而不是实际游戏,我只是设置一个默认值为 0 的 4*4 mineField 数组,并在其中随机生成 4 个值为 1 的炸弹。我的问题是我的 checkBomb() 方法,它应该占用数组中的每个插槽并检查它的所有 8 个相邻插槽及其本身的值 1 ,就像这样

[ ][ ][ ]

[ ][x][ ]

[ ][ ][ ]

并计算那里有多少炸弹,这个数字存储在一个“平行数组”中,然后显示在屏幕上。

现在我可以使用以下代码创建包含 4 个随机生成的炸弹的字段: 公共类扫雷器 {

public static int[][] afterCheck=new int[4][4];
public static int[][] mineField=new int[4][4];
public static int bombNumber=4;



public static  void setBombs()
{

    //bombNumber variable will decide the number of loops
    for(int i=0;i<bombNumber;)
    {
        int firstRandom=(int)(Math.random()*4);
        int secondRandom=(int)(Math.random()*4);
        if(mineField[firstRandom][secondRandom]== 0)
            {
                mineField[firstRandom][secondRandom]=1;
                i++;

            }

但至于 checkBomb() 方法,到目前为止,我已经提出了两个不同的代码,但没有一个有效。 代码1: 公共静态无效检查炸弹() {

    for(int i=0;i<4;i++)
    {
        int counter=0;
        try{
        for(int y=0;y<4;y++)
        {
            if (mineField[i][y + 1] == 1)
                counter++;
            if (mineField[i][y - 1] == 1)
                counter++;
            if (mineField[i - 1][y] == 1)
                counter++;
            if (mineField[i - 1][y + 1] == 1)
                counter++;
            if (mineField[i - 1][y - 1] == 1)
                counter++;
            if (mineField[i + 1][y] == 1)
                counter++;
            if (mineField[i + 1][y + 1] == 1)
                counter++;
            if (mineField[i + 1][y - 1] == 1)
                counter++;


            afterCheck[i][y] = counter;
        }
        } catch(Exception e){}
    }



}

第二个代码:

public static void checkBombs()
{

    for(int i=0;i<4;i++)
    {
        int counter=0;
        try{
        for(int y=0;y<4;y++)
        {
           for(int a=i-1;a<i+1;a++)
            {
                for (int b=y-1;b<y+1;b++)
                {
                    if(mineField[a][b]==1)
                        counter++;


                }


            }
            */

            afterCheck[i][y] = counter;
        }
        } catch(Exception e){}
    }



}

我需要一些帮助你们。

【问题讨论】:

  • 停止捕获和忽略异常:它们会告诉您代码中的错误是什么以及在哪里,而您故意选择忽略它们。
  • 我没有意识到这是不好的做法(如果这就是你的意思)......对我来说,我试图忽略通过检查边缘上的插槽生成的 .ArrayIndexOutOfBoundsException。
  • 抛出异常时,您也会忽略所有随后检查的单元格,即使它们没有越界。
  • ArrayIndexOutOfBoundsException 表示您的代码中存在错误:您正在越过数组的边界。捕获异常并将其隐藏起来,就好像它没有被抛出一样不会修复错误。它只会使诊断变得更加困难。您所做的基本上与禁用汽车中的所有警告标志和声音,然后抱怨您不知道为什么它不再启动相同。所以现在你知道什么问题了。堆栈跟踪还告诉您哪里问题出在哪里。
  • @Tom 有两个数组:一个用于放置炸弹,另一个用于相邻炸弹计数。放置炸弹的那个实际上应该是一个boolean 数组。

标签: java arrays minesweeper


【解决方案1】:

介绍一种安全处理棋盘边缘的方法:

int bombCount(int i, int j) { 
  if (i < 0 || j < 0 || i >= mineField.length || j >= mineField[i].length)
    return 0;
  return mineField[i][j];
}

然后您可以使用带有 for 循环的第二个版本,通过替换来总结相邻炸弹计数

mineField[i][j]

bombCount(i, j)

你也可以消除那里的所有 if-ology,只需使用

counter += bombCount(i,j);

只是为了兴趣,一个“不好的做法”,但是正确,相当于上面的方法是

int bombCount(int i, int j) { 
  try { return mineField[i][j]; }
  catch (ArrayIndexOutOfBoundsException _) { return 0; }
}

上述代码与您的代码之间的区别在于,每个数组访问都会单独捕获异常,而您的方式会在遇到第一个边缘情况时将其余的评估短路。

最后,作为旁注,最近 HotSpot 已经针对不良实践变体进行了优化,因此该习语实际上不会对性能造成太大影响。大多数 Java 专家都会对此感到不满。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-08
    • 2013-11-16
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    相关资源
    最近更新 更多