【问题标题】:Recursion Showing Adjacent Blank Mines in Minesweeper在扫雷中递归显示相邻的空白地雷
【发布时间】:2021-03-05 11:31:13
【问题描述】:

我是 Java 新手,我一直在开发扫雷游戏。我试图在单击空单元格时递归地显示相邻的单元格。我通过调用如下所示的 showCell() 来做到这一点:

元胞数组声明和填充:

private final Cell[][] cells;

public void newGame()
    {
        numMinesLeft = NUM_MINES;
        numCellsLeft = NUM_ROWS * NUM_COLS;
        hasHitMine = false;

        Cell[] newCells = new Cell[NUM_ROWS * NUM_COLS];

        int k = 0; // index in newCells

        // create the cells with the mines
        while (k < NUM_MINES && k < newCells.length)
        {
            newCells[k] = new Cell(MINE);
            k++;
        }

        // create the cells without the mines
        while (k < newCells.length)
        {
            newCells[k] = new Cell();
            k++;
        }

        // uniformly mix newCells
        for (k = newCells.length; k > 1;)
        {
            int r = generator.nextInt(k);
            k--;

            // interchange newCells[r] and newCells[k]
            Cell temp = newCells[k];
            newCells[k] = newCells[r];
            newCells[r] = temp;
        }

        k = 0;

        // place cells into the cells array
        for (int i = 0; i < NUM_ROWS; ++i)
        {
            for (int j = 0; j < NUM_COLS; ++j)
            {
                cells[i][j] = newCells[k];
                k++;
            }
        }


        for(int i = 0; i<NUM_ROWS; i++)
        {
            for (int j = 0; j<NUM_COLS; j++)
            {
                int numOfBorderMines = 0;
                if (cells[i][j].value != MINE)
                {
                    if(isInTheGrid(i-1, j) == true)
                    {
                        if (cells[i-1][j].value == MINE )
                        {
                            numOfBorderMines++;
                        }
                    }
                    if(isInTheGrid(i+1, j) == true)
                    {
                        if (cells[i+1][j].value == MINE )
                        {
                            numOfBorderMines++;
                        }
                    }
                    if(isInTheGrid(i, j - 1) == true)
                    {
                        if (cells[i][j - 1].value == MINE )
                        {
                            numOfBorderMines++;
                        }
                    }
                    if(isInTheGrid(i, j + 1) == true)
                    {
                        if (cells[i][j + 1].value == MINE )
                        {
                            numOfBorderMines++;
                        }
                    }
                    if(isInTheGrid(i - 1, j + 1) == true)
                    {
                        if (cells[i - 1][j + 1].value == MINE )
                        {
                            numOfBorderMines++;
                        }
                    }
                    if(isInTheGrid(i + 1, j - 1) == true)
                    {
                        if (cells[i + 1][j - 1].value == MINE )
                        {
                            numOfBorderMines++;
                        }
                    }
                    if(isInTheGrid(i + 1, j + 1) == true)
                    {
                        if (cells[i + 1][j + 1].value == MINE )
                        {
                            numOfBorderMines++;
                        }
                    }
                    if(isInTheGrid(i - 1, j - 1) == true)
                    {
                        if (cells[i - 1][j - 1].value == MINE )
                        {
                            numOfBorderMines++;
                        }
                    }

                    cells[i][j].value = numOfBorderMines;
                }
            }
        }
    }

toggleFlag()

public void toggleFlag(int row, int col)
    {
        if (isCellShowing(row, col) || isOver()) return;

        if (isCellFlagged(row, col))
        {
            // unflag cell
            cells[row][col].hasFlag = false;
            numMinesLeft++;
            numCellsLeft++;
        }
        else if (numMinesLeft > 0)
        {
            // flag cell
            cells[row][col].hasFlag = true;
            numMinesLeft--;
            numCellsLeft--;
        }

        ui.updateCell(row, col);
    }

showCell()

public void showCell(int row, int col)
    {
        // checks is cell has been flagged or if the game is over, otherwise it reveals the cell
        if(isCellFlagged(row, col) == true || isOver())
        {
            return;
        }
        else
        {
            cells[row][col].isShowing = true;
            ui.updateCell(row, col);
        }

        // checks if cell has a mine and triggers hasHitMine otherwise subtracts 1 from class variable numCellsLeft
        if (cells[row][col].value == MINE)
        {
            hasHitMine = true;
        }
        else
        {
            numCellsLeft--;
        }

        //  if there are no mines adjacent, recursively reveal the adjacent cells
        if(cells[row][col].value == 0)
        {
            showCell(row + 1, col);
            showCell(row - 1, col);
            showCell(row, col + 1);
            showCell(row, col -1);
            showCell(row + 1, col - 1);
            showCell(row + 1, col + 1);
            showCell(row - 1, col - 1);
            showCell(row - 1, col + 1);
        }

    }

我遇到的问题是,当我点击这部分代码并单击一个空单元格时,它会显示所有相邻的单元格在一个方向上连续向下一列或一行。我无法正确实现递归,也许我的方法是错误的。我的想法是根据网格位置显示每个相邻的单元格。

【问题讨论】:

  • 这里没有足够的细节。显示cells[][] 的声明以及从您的代码调用的所有方法的代码。
  • 正式注明。我已经更新了我的帖子。我将在以后的帖子中添加更多细节。

标签: java recursion minesweeper


【解决方案1】:

我通过实现尾递归解决了我的问题。这是我更新的 showCell() 方法和尾递归方法:

public void showCell(int row, int col)
    {
        // checks is cell has been flagged or if the game is over, otherwise it reveals the cell
        if(isCellFlagged(row, col) == true || isOver())
        {
            return;
        }
        else
        {
            cells[row][col].isShowing = true;
            ui.updateCell(row, col);
        }

        // checks if cell has a mine and triggers hasHitMine otherwise subtracts 1 from class variable numCellsLeft
        if (cells[row][col].value == MINE)
        {
            hasHitMine = true;
        }
        else
        {
            numCellsLeft--;
        }

        //  if there are no mines adjacent, recursively reveal the adjacent cells
        if(cells[row][col].value == 0)
        {
            if(isInTheGrid(row - 1, col) == true)
            {
                showCell(row - 1, col, cells[row - 1][col].isShowing);
            }
            if(isInTheGrid(row + 1, col) == true)
            {
                showCell(row + 1, col, cells[row + 1][col].isShowing);
            }
            if(isInTheGrid(row, col - 1) == true)
            {
                showCell(row, col - 1, cells[row][col - 1].isShowing);
            }
            if(isInTheGrid(row, col + 1) == true)
            {
                showCell(row, col + 1, cells[row][col + 1].isShowing);
            }
            if(isInTheGrid(row + 1, col - 1) == true)
            {
                showCell(row + 1, col - 1, cells[row + 1][col - 1].isShowing);
            }
            if(isInTheGrid(row - 1, col + 1) == true)
            {
                showCell(row - 1, col + 1, cells[row - 1][col + 1].isShowing);
            }
            if(isInTheGrid(row + 1, col + 1) == true)
            {
                showCell(row + 1, col + 1, cells[row + 1][col + 1].isShowing);
            }
            if(isInTheGrid(row - 1, col - 1) == true)
            {
                showCell(row - 1, col - 1, cells[row - 1][col - 1].isShowing);
            }
        }
        else
        {
            return;
        }
    }

    public boolean isInTheGrid(int x, int y)
    {
        if (x < 0 || y < 0) return false;
        if(x >= NUM_ROWS || y >= NUM_COLS) return false;
        return true;
    }

    public void showCell(int row, int col, boolean isShown)
    {
        if (isShown != true)
        {
            cells[row][col].isShowing = true;
            ui.updateCell(row, col);
        }
        else
        {
            return;
        }
    }

【讨论】:

    【解决方案2】:

    当您为周围的单元格调用 show cell 时,您要确保不会重新显示您从中调用它的单元格,或在递归堆栈中的先前调用中显示的过去单元格。

    如果我正确理解了您的问题,我相信您指的是扫雷中的案例,如果您单击一个空单元格,那么它将显示相邻的空单元格。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多