我正在写一个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
*/
}
答案 0 :(得分:2)
我相信你想要
if(isValidSquare(r, c))
而不是
if (grid[r][c].isValidSquare(int rr, int cc) == true)
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"