1

我目前正在开发一个扫雷程序,我需要一些帮助来揭示其中的邻居。目前我的程序可以做的揭示如下

1 将是被选中的按钮,线条是我需要填写的内容。目前,所选按钮周围的按钮是我可以填写的。

如有必要,我可以发布代码。

我在这里先向您的帮助表示感谢。 在此处输入图像描述

1 是地雷,4 是阵列上的标记点

public int findneighbors(int row, int col) {
      int count = 0;
    if (board[row][col] == 2)
        try {
            if (board[row][col + 1] == 1 || board[row][col + 1] == 4)
                count ++;
        }

            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
        if (board[row + 1][col + 1] == 1 || board[row + 1][col + 1] == 4)
            count ++;
            }
        catch( ArrayIndexOutOfBoundsException e)
        {
        }
        try {
        if (board[row + 1][col - 1] == 1 || board[row + 1][col - 1] == 4)
            count ++;
            }
        catch( ArrayIndexOutOfBoundsException e)
        {
        }
        try {
            if (board[row - 1][col - 1] == 1 || board[row - 1][col - 1] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row][col + 1] == 1 || board[row][col + 1] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row + 1][col] == 1 || board[row + 1][col] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row - 1][col] == 1 || board[row - 1][col] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row][col - 1] == 1 || board[row][col - 1] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }
        try {
            if (board[row - 1][col + 1] == 1 || board[row - 1][col + 1] == 4)
                count ++;
                }
            catch( ArrayIndexOutOfBoundsException e)
            {
            }

    return count;
  }
public int buttonFloodFill(int r, int c)
{
    int loopCount = 0;
    int rowCount = 1;
    int colCount = 1;
    while (loopCount < 1)
    {
        try {
    if (g.getFloodValue(r,c + colCount) == true) {
        board[r][c + colCount].setText(Integer.toString(g.findneighbors(r,c + colCount)));
        board[r][c + colCount].setEnabled(false);
    }
        }
    catch( ArrayIndexOutOfBoundsException e)
    {
    }
    try {
    if (g.getFloodValue(r,c - colCount) == true) {
        board[r][c - colCount].setText(Integer.toString(g.findneighbors(r,c - colCount)));
        board[r][c - colCount].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r + rowCount,c + colCount) == true) {
        board[r + rowCount][c + colCount].setText(Integer.toString(g.findneighbors(r + rowCount,c + colCount)));
        board[r + rowCount][c + colCount].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r + rowCount,c - colCount) == true) {
        board[r + rowCount][c - colCount].setText(Integer.toString(g.findneighbors(r + rowCount,c - colCount)));
        board[r + rowCount][c - colCount].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r - rowCount,c - colCount) == true) {
        board[r - rowCount][c - colCount].setText(Integer.toString(g.findneighbors(r - rowCount,c - colCount)));
        board[r - rowCount][c - colCount].setEnabled(false);
        }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r - rowCount,c + colCount) == true) {
        board[r - rowCount][c + colCount].setText(Integer.toString(g.findneighbors(r - rowCount,c + colCount)));
        board[r - rowCount][c + colCount].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r - rowCount,c) == true) {
        board[r - rowCount][c].setText(Integer.toString(g.findneighbors(r - rowCount,c)));
        board[r - rowCount][c].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    try {
    if (g.getFloodValue(r + rowCount,c) == true) {
        board[r + rowCount][c].setText(Integer.toString(g.findneighbors(r+ rowCount,c)));
        board[r + rowCount][c].setEnabled(false);
    }
    }
catch( ArrayIndexOutOfBoundsException e)
{
}
    rowCount ++;
    colCount ++;
    loopCount ++;

    }
    return 0;
}
4

3 回答 3

3

虽然我没有阅读您的代码,但您似乎需要学习一些更基本的技术,例如循环和使用小型辅助函数进行重构。我可以看到您对异常处理不感兴趣,这对于这种规模的程序来说现在很好,但是有更多视觉上令人愉悦(并且可读性增加)的解决方案,例如将连续的 try-catch 块合并到一个或简单地声明可能抛出的函数。

至于你的问题,递归就是答案。你不能一直检查邻居和邻居的邻居以及他们的邻居等等。你需要想出一个重复的模式。填充是实际的答案,但您需要熟悉递归并学会识别它可能解决的问题。

于 2012-02-16T23:09:01.037 回答
1

好吧,在看到你的代码后,我认为最好给你一些一般性的指导方针,而不是试图解决这个特定的问题。

Java 是一种为面向对象编程而设计的语言。您所做的更多是一种程序方法,当然这也有效,但由于您使用的是 Java,我假设您想利用语言特性来发挥自己的优势。

让我们看看我们可以在您的项目中找到什么样的“对象”。你已经有了一块板子,一个单元格的数组。您显示的代码将是该板的一部分,您可以将其与与板无关的代码分开。

目前,您的电路板由表示该单元格状态的整数组成。现在,让 cell 也成为对象不是很有趣吗?那样的话,一块板就会有一个单元数组,它们有一个状态。现在你可以说这只是增加了你必须推理的关卡数量。在某种程度上,这也是正确的,但是,这些级别中的每一个都是一个明确定义的概念,您可以单独推理。让我们看一些示例代码:

class Cell {
    private int state; //whatever your default is

    public Cell(int state) {
        this.state = state;
    }

现在我们可以添加一些方法来检查状态:

    public boolean hasMine() {
         return state == 1;
    }
    public boolean isFlagged() {
         return state == 4;
    }

同样,您可以添加方法来更改状态:

    public void flag() {
        state = 4;
    }

我只列出了几种方法,我认为应该清楚如何编写进一步的方法。(此外,我现在将状态保留为整数。一旦您在 OO 编程方面更高级,您可能需要查看 Java 枚举或状态模式)

现在让我们看看板子。您目前有一个名为 findneighbours 的方法,它返回相邻地雷的数量。就个人而言,我会将此方法称为更清晰的名称,例如 getAdjecentMineCount。但是,我希望 getNeighbours 方法也存在,它返回一个单元格的所有相邻单元格。然后,您可以使用此 getNeighbours 方法轻松找到相邻地雷的数量,如下所示:

public int getAdjecentMineCount(int row, int col) {
    int count=0;
    for (Cell c : getNeighbours(row, col)) //this iterates over the neighbours that are returned by the getNeighbours function
        if (c.hasMine())
             count++;
    return count;
}

现在,让我们看看显示一个单元格。让我们不要让它变得困难,并创建一个名为revealCell的方法:

public void revealCell(int row, int col) {
    if (board[row][col].hasMine())
        System.out.println("BOOM"); //whatever has to happen when you click on a bomb
    //now we also want to reveil any non-diagonal neighbour that doesn't have a mine
    for (Cell c : getNonDiagonalNeighbours(row, col))
        if (!c.hasMine() && !c.isRevealed())
             reveilCell(rowOf(c), columnOf(c));
}

再次注意对同一方法的递归调用。这将导致细胞链被揭开。

我故意在我的代码中留下了一些漏洞,例如查找邻居的方法。我希望我的解释能以正确的方式推动您,并且您可以自己了解更多有关该语言的信息。如果您还有其他问题,请随时与我联系。

(免责声明:我绝不声称我在这里提供给您的解决方案是理想的解决方案。我的目标是指导您编写更清晰、更面向对象的代码。)

于 2012-02-16T23:07:58.347 回答
0

请原谅我重新实现了你的整个代码,但这比试图理解你的要快......

public class Minefield {

    int mx, my;

    /** whether a mine is present */
    boolean[][] mined;

    /** the number of mines in neighboring cells */
    int[][] mines;

    /** whether this cell is revealed */
    boolean[][] revealed;

    public Minefield() {
        Random chaos = new Random();

        mx = 10;
        my = 10;
        for (int x = 0; x < mx; x++) {
            for (int y = 0; y < my; y++) {
                mined[x][y] = chaos.nextFloat() < 0.2;
            }
        }

        for (int x = 0; x < mx; x++) {
            for (int y = 0; y < my; y++) {
                mines[x][y] = 0;
                for (int nx = max(x - 1, 0); nx < mx && nx <= x + 1; nx++) {
                    for (int ny = max(y - 1, 0); ny < my && ny <= y + 1; ny++) {
                        if (mined[nx][ny]) {
                            mines[x][y]++;
                        }
                    }
                }
            }
        }
    }

    void stepOn(int x, int y) {
        reveal(x, y);
        if (mined[x][y]) {
            throw new GameOverException();
        }
    }

    void reveal(int x, int y) {
        if (!revealed[x][y]) {
            revealed[x][y] = true;
            if (mines[x][y] == 0) {
                for (int nx = max(x - 1, 0); nx < mx && nx <= x + 1; nx++) {
                    for (int ny = max(y - 1, 0); ny < my && ny <= y + 1; ny++) {
                        reveal(nx, ny);
                    }
                }
            }
        }
    }

注意:我没有测试过那个代码,但我希望你能明白。

于 2012-02-16T23:25:03.807 回答