扫雷揭示邻居需要帮助 java

发布于 2025-01-07 03:22:10 字数 4721 浏览 0 评论 0原文

我目前正在开发一个扫雷程序,我需要一些帮助来揭露其中的邻居。目前我的程序可以执行的操作如下:

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;
}

I am currently working on a minesweeper program and i need a little help on revealing neighbors in it. Currently what my program can do for reveals is the following

The 1 would be the button that was selected and the lines are what i need to be
filled in. Currently the buttons of around the button selected are what i can get to fill in.

I can post code if necessary.

Thanks for the help in advance.
enter image description here

1 is a mine, 4 is a flagged spot on the array

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌逼全场 2025-01-14 03:22:10

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

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

While I haven't read your code, it looks like you need to learn some more basic techniques such as loops and refactoring using small helper functions. I can see that you're not interested in exception handling, which is fine for now for a program of this scale, but there are more visually-pleasing (and readability-increasing) solutions, such as merging the consecutive try-catch blocks into one or simply declaring the function to possibly throw.

As for your question, recursion is the answer. You cannot keep checking neighbors and neighbors-of-neighbors and their neighbors and so on. You need to come up with a repeating pattern. Flood fill is the actual answer, but you need to familiarize yourself with recursion and learn to identify problems it might solve.

夜血缘 2025-01-14 03:22:10

好吧,在看到您的代码后,我认为最好给您一些一般准则,而不是尝试解决这个特定问题。

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));
}

请注意再次递归调用同一方法。这将导致细胞链被掩盖。

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

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

Alright, after seeing your code i think it's best to give you some general guidelines rather than trying to fix this specific problem.

Java is a language designed for object-oriented programming. What you did is more of a procedural approach, which also works of course, but since you are working with Java, I assume you want to use the language features to your advantage.

Let's see what kind of 'objects' we can find in your project. You already have a board, the array of the cells. The code you showed would be part of this board, which you can seperate from the code that has nothing to do with the board.

Currently, your board consists of integers representing the state of that cell. Now, wouldn't it be interesting to make cell an object as well? That way, a board would have an array of cells, which have a state. Now you could say this just increases the number of levels you have to reason about. In a way this is also true, however, each of these levels is a clearly defined concept which you can reason about individually. Let's look at some example code:

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

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

Now we can add some methods to inspect the state:

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

Similarly, you can add methods to change the state:

    public void flag() {
        state = 4;
    }

I've only listed a few methods, I think it should be clear how to write the further ones.
(Also, I've kept the state as an integer for now. Once you're more advanced in OO-programming you may want to look at Java Enumerations or the State pattern)

Now let's look at the board. You currently have a method called findneighbours, which returns the number of adjecent mines. Personally, I would call this method something more clear, like getAdjecentMineCount. However, I would expect a getNeighbours method to exist as well, which returns the all the adjecent cells of a cell. You can then use this getNeighbours method to easily find the number of adjecent mines, like this:

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;
}

Now, let's look at revealing a cell. Let's not make it hard and make a method called 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));
}

Notice the recursive call to the same method again. This will cause the chain of cells to be reveiled.

I've purposefully left some holes in my code, such as the methods to find the neighbours. I hope that my explanation will push you in the right way, and that you can figure out more about the language by yourself. Feel free to contact me if you have further problems.

(Disclaimer: by no means do I claim that the solution I'm feeding to you here is the ideal solution. All I'm aiming to do is guide you to write cleaner and more object oriented code.)

苍风燃霜 2025-01-14 03:22:10

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

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);
                    }
                }
            }
        }
    }

注意:我还没有测试该代码,但我希望您能明白这一点。

Forgive me for reimplementing your entire code but that's faster than trying to understand yours ...

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);
                    }
                }
            }
        }
    }

Note: I haven't tested that code, but I hope you'll get the idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文