扫雷增加了相邻矿网的数量

时间:2013-06-27 01:08:54

标签: java subclass superclass minesweeper

我正在写一个Minesweeper程序,我正在尝试编写代码,它将显示相邻网格中有多少个地雷,但是我收到一个错误,说有一个类是预期的,我不知道为什么。我是在假设,因为两种方法都在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 个答案:

答案 0 :(得分:2)

我相信你想要

if(isValidSquare(r, c))

而不是

if (grid[r][c].isValidSquare(int rr, int cc) == true)
  • isValidSquare是为MSGrid而非MineSquare定义的,但网格[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)

答案 1 :(得分:0)

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

不是有效代码。试试

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

此外,检查是布尔值为true,通常在不使用true / false值的情况下完成false。即if (grid[r][c].isValidSquare(rr, cc))

答案 2 :(得分:0)

您的grid拥有MineSquare个对象。但是,您的isValidSquare方法是在课程MSGrid中定义的。 grid[r][c]将返回MineSquare对象,因此尝试在该对象上调用isValidSquare是错误的。您将收到一个编译时错误,该错误表明该方法未定义为类型为MineSquare。

将该方法移至MineSquare课程,并且最有可能应该没问题。当然,您需要通过执行此isVaidSquare来修复对(grid[r][c].isValidSquare(r,c))的调用。毕竟是一个方法调用,所以摆脱int并分别将rr和cc更改为r和c。

修改

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

答案 3 :(得分:0)

如果矩阵在每个正方形中都包含地雷存在的布尔值,则为true / false。然后这段代码起作用:

"Content-Type": "application/json"
"Access-Control-Allow-Origin": "*"
"Access-Control-Allow-Methods": 'POST, GET, PUT, DELETE, OPTIONS'
"Access-Control-Allow-Headers": "Access-Control-Allow-Origin,Authorization, "Access-Control-Allow-Methods,"Content-Type"