忽略越界异常JAVA的简单方法

时间:2014-08-29 17:22:14

标签: java

我正在创建一个像应用程序一样的扫雷,并且有一些代码旨在检查一个非开采的空间周围有多少个地雷。我已经为此创造了一些东西

int count = 0;
                if(model.get(i-1, j-1) == MinerGridCo.UNTURNED_MINE){ count++;}
                if(model.get(i, j-1) == MinerGridCo.UNTURNED_MINE){ count++;}
                if(model.get(i-1, j) == MinerGridCo.UNTURNED_MINE){ count++;}
                if(model.get(i+1, j) == MinerGridCo.UNTURNED_MINE){ count++;}
                if(model.get(i, j+1) == MinerGridCo.UNTURNED_MINE){ count++;}
                if(model.get(i-1, j+1) == MinerGridCo.UNTURNED_MINE){ count++;}
                if(model.get(i+1, j-1) == MinerGridCo.UNTURNED_MINE){ count++;}
                if(model.get(i+1, j+1) == MinerGridCo.UNTURNED_MINE){ count++;}
                String mineNum = String.valueOf(count);
                cell[i][j].setText(mineNum);
然而,当试图获得围绕电路板边缘的矿号时,这会产生错误。有什么有用的方法可以避免这种情况吗?

在尝试下面的建议之后。我仍然得到越界错误。任何人都有任何建议,如果有人想自己编译https://github.com/phillolivercomp/MineSweeper.git

,这里就是回购

6 个答案:

答案 0 :(得分:2)

帮自己一个忙,然后创建model.countUnturnedMinesAround(i,j)。然后在模型内你有一些选择。

您可以创建视图看不到的额外行/列,以便您可以轻松处理逐个索引。

或者你可以编写一个函数private Cell getCell(i,j),它会在i和j超出范围时返回默认的空单元格。

或者,当i或j离开网格时,您可以让boolean hasUnturnedMine(i,j)返回false。

答案 1 :(得分:2)

您可以避免与循环重复:

for (int iOffset = -1; iOffset <= 1; iOffset++) {
    for (int jOffset = -1; jOffset <= 1; jOffset++) {
        if (iOffset != 0 || jOffset != 0) {
            if (isInGrid(i + iOffset, j + jOffset) && 
                model.get(i + iOffset, j + jOffset) == MinerGridCo.UNTURNED_MINE) {
                    count++;
            }
        }
    }
}

使用@ Emrakul回答建议的isInGrid函数(我实际上将范围检查和UNTURNED_MINE检查合并到一个hasUnturnedMine函数中,如@ Arkadiy的答案中所述。

答案 2 :(得分:1)

使用短路,并编写一个函数isInGrid(int x, int y),用于检查位置是否在网格中。

public boolean isInGrid(int x, int y) {
    //Check if a position is valid in the grid
    if(i < 0 || j < 0) return false;
    if(i >= WIDTH || j >= HEIGHT) return false;
    return true;
}

...

if(isInGrid(i-1, j-1) && model.get(i-1, j-1) == MinerGridCo.UNTURNED_MINE) count++;
if(isInGrid(i+1, j+1) && model.get(i+1, j+1) == MinerGridCo.UNTURNED_MINE) count++;
//Repeat for each location you want to check

如果第一个条件isInGrid(i-1, j-1)不为真,那么条件将退出而不运行[condition]语句。通过这种方式,如果否则[condition]会失败,则会阻止if执行。

这称为&#34;短路&#34; - 如果已经知道代码不会运行,那么会导致isInGrid条件检查退出的优化。您可以在要评估的每个语句之前放置其中一个get检查,如果该位置不在网格中,则不会执行{{1}}。

答案 3 :(得分:0)

创建一行功能:

boolean checkBounds(int i, int j) { //TODO }

然后在进行模型查找之前检查

答案 4 :(得分:0)

另一种方法可能是让方法isBorder(int i,int j)让你知道你是否在界限上。如果它不是边框,您知道可以安全地检查周围的所有方块(i,j)。如果它在边框上,您可以计算它是左/右/上/下边框还是4(不超过2)的某种组合,然后选中相应的框。

免责声明:我假设您已经进行了检查,以确保(i,j)是网格上的有效位置。无论您的实施如何,都应该对此进行检查

答案 5 :(得分:0)

通过更好地构建代码,有更好的方法可以做到这一点。但是,这是您具体问题的答案:

在Java中忽略异常的方法是使用try-catch块。这允许您尝试运行代码块,捕获任何抛出的异常,然后决定如何处理它们(包括忽略它们)。

假设您的out of bounds异常来自model.get()调用,您可以忽略它们:

int count = 0;
try
{
    if(model.get(i-1, j-1) == MinerGridCo.UNTURNED_MINE){ count++;}
    if(model.get(i, j-1) == MinerGridCo.UNTURNED_MINE){ count++;}
    if(model.get(i-1, j) == MinerGridCo.UNTURNED_MINE){ count++;}
    if(model.get(i+1, j) == MinerGridCo.UNTURNED_MINE){ count++;}
    if(model.get(i, j+1) == MinerGridCo.UNTURNED_MINE){ count++;}
    if(model.get(i-1, j+1) == MinerGridCo.UNTURNED_MINE){ count++;}
    if(model.get(i+1, j-1) == MinerGridCo.UNTURNED_MINE){ count++;}
    if(model.get(i+1, j+1) == MinerGridCo.UNTURNED_MINE){ count++;}
}
catch (IndexOutOfBoundsException ex)
{
    // Do nothing
}
String mineNum = String.valueOf(count);
cell[i][j].setText(mineNum);

但是,遇到异常时,将跳过try块中的所有后续代码。这绝对不是你想要的,因为你会错过检查一些邻接。 相反,您需要为每次调用model.get()执行try-catch。最好通过创建一个布尔函数来实现,如:

// Change method visibility and signature accordingly to match your code
public static boolean tileHasMine(int x, int y)
{
    try
    {
        if (model.get(x, y) == MinerGridCo.UNTURNED_MINE)
        {
            return true;
        }
    }
    catch (IndexOutOfBoundsException ex)
    {
        // Do Nothing
    }
    return false;
}

然后你的支票看起来像:

int count = 0;
if(tileHasMine(i-1, j-1)){ count++;}
if(tileHasMine(i, j-1)){ count++;}
if(tileHasMine(i-1, j)){ count++;}
if(tileHasMine(i+1, j)){ count++;}
if(tileHasMine(i, j+1)){ count++;}
if(tileHasMine(i-1, j+1)){ count++;}
if(tileHasMine(i+1, j-1)){ count++;}
if(tileHasMine(i+1, j+1)){ count++;}
String mineNum = String.valueOf(count);
cell[i][j].setText(mineNum);

或者,您可以编写一个布尔函数,该函数首先检查块是否超出模型的边界,甚至在尝试读取之前,这可能是更好的方法。但我认为这就是你所要求的。