2013-06-27 1 views
0

Я пишу программу Minesweeper, я пытаюсь написать код, для которого он покажет, сколько мин находится в смежных сетках, однако я получаю сообщение об ошибке, предполагая, что класс ожидается, я Не знаю, почему. Я был в предположении, потому что оба метода находятся в методе MSgrid, это нормально. Я прокомментировал строку, которая является ошибкой, поскольку ОШИБКА ЗДЕСЬ. Вот мой код:Minesweeper увеличил количество смежных шахтных сетей

/** 
* 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 
    */ 
} 
+2

Просьба указать конкретную ошибку плюс трассировку стека. Много кода, не очень полезно. Полная ошибка плюс трассировка стека очень полезна. – BevynQ

+0

Для справки, вы обычно должны исключать исключения (например, 'InvalidArgumentException') для вещей, которые не будут выполняться, если класс используется правильно. Помимо всего прочего, вы получаете трассировку стека, которая намного полезнее, чем сообщение об ошибке, показывающее, как код закручивается. – cHao

ответ

0

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

Не правильный код. Попробуйте

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

Кроме того, проверка является логическим значением true для false, как правило, выполняется без использования значений true/false. то есть if (grid[r][c].isValidSquare(rr, cc)).

+0

Я не думаю, что определены rr или cc, поэтому, вероятно, 'isValidSquare (r, c)'. –

2

Я считаю, что вы хотите

if(isValidSquare(r, c)) 

вместо

if (grid[r][c].isValidSquare(int rr, int cc) == true) 
  • isValidSquare определяется для MSGrid и не MineSquare, но сетка [г] [с] является 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)

+0

Благодарю вас за помощь. У меня есть один последний вопрос, в методе setminecounts, когда он является недопустимой сеткой, он дает мне ошибку, говоря «java.lang.NullPointerException: null», но я думал, что метод isvalid позаботится о том, что это не действительная сетка, есть ли способ исправить это? –

+0

@SophiaAli вы проверяете, является ли (r, c) допустимым квадрат, но тогда вы предполагаете, что он имеет все 8 соседей в квадратах valids, что является ложным предположением. Возможно, вам захочется проверить каждое измерение независимо, а затем обработать соседей, только если они будут действительными –

+0

по каждому измерению, вы имеете в виду каждый квадрат? Поэтому мне понадобится больше «grid [r] [c-1] .increMinecount();» линии? –

0

Ваш Интернет grid держит MineSquare объекты. Однако ваш метод isValidSquare определен в классе MSGrid. grid[r][c] вернет объект MineSquare и поэтому пытается вызвать isValidSquare на этом объекте. Вы получите ошибку времени компиляции, в которой говорится, что метод не задан для типа MineSquare.

Переместите этот метод на ваш класс MineSquare и, скорее всего, это должно быть хорошо. Конечно, вам нужно исправить звонок до isVaidSquare, делая это (grid[r][c].isValidSquare(r,c)).Это вызов метода, поэтому избавьтесь от int s и измените rr и cc на r и c соответственно.

EDIT

Жаль, не обратить внимание на то, что isValidSquare делает. Как указывает @KarthikT, if(isValidSquare(r,c)) будет делать все отлично. Если isValidSquare работал над некоторыми членами MineSquare, можно рассмотреть возможность переноса метода в этот класс.

+0

функция проверяет индексы сетки. Перемещение его к элементам сетки не имеет смысла –

+0

да, вы правы @ Karthik T – kau