0

我正在编写一个扫雷程序,我正在尝试编写代码,它将显示相邻网格中有多少地雷,但是我收到一个错误,说需要一个类,我不知道为什么。我是在假设下,因为这两种方法都在 MSgrid 方法中是可以的。我已将出错的行注释为 ERROR HERE。这是我的代码:

/**
 * Represents a single square in Minesweeper.
 * 
 * @author Sophia Ali
 * June 17, 2012
 */
public class MineSquare
{


    // Fields:
    /**
     * initialize variables
     */
    private  String  _shown;      // What a square is showing now
    private  boolean _mined;      // Square is mined or not
    private  boolean _flagged;    // Square is flagged or not
    private  boolean _questioned; // Square is question marked or not
    private  int     _minecount;  // Square's surrounding mine count
    private  boolean _opened;     // Player has opened this square or not



    // Constructors & Methods:

    /**
     * Default constructor
     * Sets _mined and _opened to false.
     */
    public MineSquare()
    {
        _mined = false;
        _opened = false;
        setShown(" ");
    }





    /**
     * Returns flagged status of square.
     * @return  _flagged    Flagged status
     */
    public boolean isFlagged() {
        return _flagged;
    }





    /**
     * Sets or unsets flag on a square.
     * @param   flagged    True or false (square is flagged or not)
     */
    public void setFlagged(boolean flagged, boolean opened) {
        _flagged = flagged;
        _opened = opened;

        /*
        // If Minesquare opened do nothing:
        if (opened == true)
        setShown(" ");*/
        if ( isOpened() == false )
        {
        // If flagged, square should show "F":
        if ( isFlagged() == true )
            setShown("F"); 
        else
            setShown(" ");            
        }
        /* else
        {} not needed but shows it does nothing*/
        }


    /**
     * Returns _minecount amount.
     * @return  _minecount
     */
    public int getMinecount() {
        return _minecount;
    }




/**
     * Checks minecount
     * If minecount between 0 and 8 _minecount not set and error message outputs.
     */
    public void setMinecount(int minecount) {
        if(minecount >=0 && minecount <= 8)
            _minecount = minecount;
        else //invalid minecount
            System.out.println("Invalid minecount in setMinecount: " +minecount);
        /*
        if ( minecount > 0 && minecount < 8 ) 
        {
       getMinecount();
    }
       else System.out.println("Error :" +  minecount);
        */

}




/**
     * Returns mined status of square.
     * @return  _mined   Mined status
     */
    public boolean isMined() {
        return _mined;
    }




/**
     * Sets or unsets mine on a square.
     * @param   mined    True or false (square is mined or not)
     */
    public void setMined(boolean mined) {
        _mined = mined;


        // If mine, square should show "F":
        if ( isMined() == true )
            setShown("F");
        else
            setShown(" ");  

    }




/**
     * Returns opened status of square.
     * @return _opened Opened status
     */
    public boolean isOpened() {
        return _opened;
    }





    /**
     * Open a square.
     * (Once opened, a square can't be unopened.)
     */
    public void setOpened() {
        _opened = true;

        if ( isMined() == true )
            setShown("X");
        else if ( getMinecount() > 0 )
            setShown(_minecount + "");
        else // blank space for _minecount = 0
            setShown(" ");
    }




/**
     * Returns openequestion status of square.
     * @return _questioned Questioned status
     */
    public boolean isQuestioned() {
        return _questioned;
    }




/**
     * Sets or unsets question on a square.
     * @param   questioned    True or false (square is questioned or not)
     */
    public void setQuestioned(boolean questioned, boolean opened) {
        _questioned = questioned;
        _opened = opened;
        // If Minesquare opened do nothing:
        /*if (opened == true)
        setShown(" ");

        // If Questioned, square should show "F":
        if ( isQuestioned() == true )
            setShown("F");
        else
            setShown(" ");  
            */
         if ( isOpened() == false )
        {
        // If flagged, square should show "F":
        if ( isQuestioned() == true )
            setShown("?"); 
        else
            setShown(" ");            
        }
        /* else
        {} not needed but shows it does nothing*/
        }


 /**
     * Returns what is in getShown.
     * @return  _shown
     */
    public String getShown() {
        return _shown;
    }


       /**
          * Increment _minecount by 1.
          * Calls setMinecount() to make sure that an illegal value (>8) is
          * not assigned to _minecount.
          */
    public void increMinecount()
         {
            int mc = _minecount;
            mc++;

            setMinecount(mc);
         }

/**
     * Checks shown
     * If _shown is one of legal values prints _shown if not prints error.
     */
    public void setShown(String shown) {
    if ( shown.equals ("X") || shown.equals("F") || shown.equals("?") || 
        shown.equals (" ") || shown.equals ("1") || shown.equals ("2") || shown.equals ("3") ||
        shown.equals ("4") || shown.equals ("5") || shown.equals ("6") || shown.equals ("7") || 
        shown.equals ("8") )
        _shown = shown;
    else //invalid value of shown
        System.out.println("Invalid value of shown in setShown: " + shown);
    }


    }

/**
 * MSGrid class that contains a 2-D array of MineSquare objects
 * 
 * @author J. Chung
 * @version CS-501B
 */
public class MSGrid
{
    // instance variables - replace the example below with your own
    // 2-D array of MineSquare objects:
    private final int ROWS = 20;
    private final int COLS = 20;
    private MineSquare [][] grid = new MineSquare[ROWS][COLS];
    // Actual size of grid that we use in rows and cols:
    private int rows = 9;
    private int cols = 9;
    // Number of mines that go in grid:
    private int mines = 10;


    /**
     * Constructor for objects of class MSGrid
     */
    public MSGrid()
    {
        // initialise the grid of MineSquare objects:
        // (construct individual MineSquare objects within grid array)
        for ( int r = 1; r <= rows; r++ ) {
            for ( int c = 1; c <= cols; c++ ) {
                grid[r][c] = new MineSquare();
            }
        }
    }


    /*
     * MSGrid methods:
     * 
     * - Set mines
     * - Compute and set minecounts
     */

    /**
     * Set some number of mines at random within the grid.
     */
    public void setMines() //scattering mines
    {
        // Choose random row, choose random col, place mine there:
        for ( int i = 1; i <= mines; i++ )
        {
            int randomrow = randbetween( 1, rows );
            int randomcol = randbetween( 1, cols );

            // If square is already mined, do it again:
            while ( grid[randomrow][randomcol].isMined() == true )
            {
                randomrow = randbetween( 1, rows );
                randomcol = randbetween( 1, cols );
            }

            grid[randomrow][randomcol].setMined(true);
        }
    }




    /*
     * Compute and set square minecounts.
     */
    public void setMinecounts()
    {
        // Approach #1: Visit each square in grid; examine all adjacent
        //              squares; for each mine found, increment minecount
        //              by 1.

        // Approach #2: Visit each mined square in grid; increment minecount
        //              of all adjacent squares by 1. plus one for all neighbors of mined grid (even if it already +1) - easier way to do it
            //**do nested for loop to access every square in grid
    for ( int r = 1; r <= rows; r++ ) {
           for ( int c = 1; c <= cols; c++ ) {
                // if current square at r,c has a mine:
            if ( grid[r][c].isMined() == true )
            {    
                if (grid[r][c].isValidSquare(int rr, int cc) == true) //***ERROR HERE***
                {
                    grid[r-1][c-1].increMinecount();
                    grid[r][c-1].increMinecount();
                    grid[r+1][c-1].increMinecount();
                    grid[r+1][c].increMinecount();
                    grid[r-1][c].increMinecount();
                    grid[r+1][c+1].increMinecount();
                    grid[r][c+1].increMinecount();
                    grid[r-1][c+1].increMinecount();
            }    
            }
        }
    }
}
  // Note: In both approaches, must exclude squares that are not in grid.
  //       (Must use the isValidSquare() method below.)





    /*
     * See if a square at some row, col is within the grid.
     * 
     * @param   rr row of square in question
     * @param   cc col of square in question
     * @return  True if square is in grid, false if square not in grid
     */
    private boolean isValidSquare( int rr, int cc )
    {
        if ( rr >= 1 && rr <= rows && cc >= 1 && cc <= cols )
            return true;
        else
            return false;
    }






    /**
     * Show the grid, for testing purposes only.
     */
    public void showMSGrid()
    {
        for ( int r = 1; r <= rows; r++ ) {
            for ( int c = 1; c <= cols; c++ ) {
                // Call a MineSquare method:
                int mc = grid[r][c].getMinecount();

                // Show a mine or a minecount number:
                if ( grid[r][c].isMined() == true )
                    System.out.print(" " + "X" );
                else
                    System.out.print(" " + mc);
            } // end of column

            System.out.println(); // line break

        } // end of row
    }





    /**
     * randbetween: Return a random integer between low and high values
     * 
     * @param: low - low value
     * @param: high - high value
     * @return: random integer b/w low and high
     */ 
    private int randbetween( int low, int high ) {
        // Make sure that low and high values are in correct positions:
        // If low > high, swap low and high.
        if ( low > high ) {
            int temp = low;
            low = high;
            high = temp;
        }

        int scale = high - low + 1;
        int shift = low;
        int randnum = (int)(Math.random() * scale) + shift;

        return randnum;
    }

    /*first setmines
    then setminecount
    then showmsgrid
    */
}
4

4 回答 4

2

我相信你想要

if(isValidSquare(r, c))

代替

if (grid[r][c].isValidSquare(int rr, int cc) == true)
  • isValidSquare 是为MSGridand not定义的MineSquare,但 grid[r][c] 是MineSquare
  • 其他提到的问题
    • 在这里使用int是无效的(讽刺啊)代码。
    • == true这里是可选的。

你现在得到 NPE 是因为假设if (isValidSquare(int rr, int cc) )它有 8 个有效邻居。这是错误的,因为如果这个正方形位于网格的边缘( r == 0 || c == 0 || r == rows-1 || c == cols-1),那么它可能没有很多这样的邻居。

在增加地雷计数之前,您需要检查每个条件。例如

if( r > 0){

     grid[r-1][c+1].increMinecount();
     grid[r-1][c].increMinecount();
     grid[r-1][c-1].increMinecount();
}

请注意,这只是一个示例,您还需要同时检查c。或者您可以使用先UpdateMineCount(r,c)调用isValidSquare然后才调用的函数increMinecount

 public void IncrementMineCount(MineSquare ms, int r, int c){
       if(isValidSquare(r,c)){
            ms.increMineCount();
       }     
 }

现在替换grid[r-1][c-1].increMinecount();IncrementMineCount(grid[r-1][c-1],r,c)

于 2013-06-27T01:24:41.333 回答
0

你的grid持有MineSquare对象。但是,您的isValidSquare方法是在 class 中定义的MSGridgrid[r][c]将返回一个MineSquare对象,因此尝试调用isValidSquare该对象是错误的。您将收到一个编译时错误,指出该方法对于 MineSquare 类型未定义。

将该方法移至您的MineSquare班级,很可能应该没问题。当然,您需要isVaidSquare通过这样做来修复对的调用(grid[r][c].isValidSquare(r,c))。毕竟这是一个方法调用,所以去掉ints 并将 rr 和 cc 分别更改为 r 和 c 。

编辑

抱歉,没注意是做什么isValidSquare的。正如@KarthikT 指出的那样,if(isValidSquare(r,c))会做得很好。如果isValidSquare正在处理 的某些成员MineSquare,可以考虑将方法移至该类。

于 2013-06-27T01:35:37.423 回答
0

if (grid[r][c].isValidSquare(int rr, int cc) == true)

不是有效代码。尝试

if (grid[r][c].isValidSquare(rr, cc) == true).

此外,检查布尔值是真还是假通常不使用真/假值。即if (grid[r][c].isValidSquare(rr, cc))

于 2013-06-27T01:11:17.783 回答
0

如果矩阵包含每个方块中地雷存在的真/假布尔值。然后这段代码有效:

int[][] minesweeper(boolean[][] matrix) {
    int row = matrix.length;
    int col = matrix[0].length;
    int[][] newArr = new int[row][col];
    for(int i=0;i<row;i++){
        for(int j=0; j<col;j++){
            int count = 0;
            for(int x=i-1;x<=i+1;x++){
                for(int y=j-1;y<=j+1;y++){
                    if(x>=0 && y>=0 && x<row && y<col){
                        if(matrix[x][y]==true){
                            count++;
                        }
                    }
                }
            }
            if(matrix[i][j]==true){
                newArr[i][j]=count-1;
            }else{
                newArr[i][j]=count;
            }
           
        }
    }
    return newArr;
}
于 2020-09-21T09:55:05.703 回答