2

so basically I've been making a minesweeper clone in Java. I had it working perfectly until I added the game win and lose parts and the big opening print. Now when I run it some of the spots that are next to zero's don't get revealed, even though they should. I can't figure out where the bug is though. Here's my code:

/**
 * A program to play Scat Scout...
 */
import static java.lang.System.*; // so you can write out.println() instead of System.out.println()
import java.util.*;

class ScatScout {
  static final int boardSize = 10;
  static final Random rand = new Random();
  static final boolean SCAT = true;
  static final boolean CLEAR = false;
  static int clearCounter = 100;
  static boolean gameWon = false;
  static boolean gameLost = false;

  public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    boolean[][] board = new boolean[boardSize+2][boardSize+2]; // scat or no scat
    boolean[][] exposed = new boolean[boardSize+2][boardSize+2]; // showing or hidden
    int[][] counts = new int[boardSize+2][boardSize+2]; // number of neighbors with scat
    if (args.length > 0) {
      rand.setSeed(Integer.parseInt(args[0]));
    }
    System.out.println("comment explaining game");
    createScat(board); //initialize the board
    compareScat(board, counts); //find how many scat are next to each spot
    while(!gameWon&&!gameLost){ //keep going until game win or loss
      printBoard(board, counts, exposed);
      System.out.println("Enter two integers (row and column):");
      expose(input.nextInt()+1, input.nextInt()+1, board, exposed, counts);
      if (gameLost){
        for (int i = 1; i<= board.length-2; i++){
          for (int j = 1; j<= board.length-2; j++){
            if (!board[i][j]){
              exposed[i][j] = true;
            }
          }
        }    
        printBoard(board, counts, exposed);
        System.out.print("You stepped in it! Yucky!"); //game lose 
        break;
      }
      gameWon = true; //game is one if all blanks but the bombs are exposed
      for(int i = 1; i<= board.length-2; i++){
        for(int j = 1; j<= board[0].length-2; j++){
          if(!exposed[i][j]&&!board[i][j]){
            gameWon=false; //otherwise continue loop
          }
        }
      }
      if (gameWon){
        System.out.print("You cleared the scat! Congrats!"); //game win message
        break;
      }
    }
    input.close();
  }

  public static void printBoard(boolean[][] board, int[][] counts, boolean[][] exposed){ //initialize board
   int numRows = counts.length;
   int numCols = counts[0].length;
   System.out.println("  0123456789"); //print the border
   for(int i=1; i<=numRows-2; i++){
     System.out.print(i-1 + " "); //border
     for(int j=1; j<=numCols-2; j++){
       if (exposed[i][j] == true){
       System.out.print(counts[i][j]); //print the scat near a spot if it's exposed
       }
      else{
         System.out.print("*"); //print unknown spot
       }
     }
     System.out.print(" ");
     System.out.print(i-1); //border
     System.out.println(" ");
   }
   System.out.println("  0123456789"); //border
  }

  public static void createScat(boolean[][] board){ //randomly seed scat into field
    for(int i=1; i<= board.length-2; i++){
      int x = rand.nextInt(board.length-3)+1;
      int y = rand.nextInt(board.length-3)+1;
      if(x!=0&&x!=11&&y!=0&&y!=11&&board[x][y]==CLEAR){
      board[x][y]=SCAT; //scat in this random spot
      }
    }
  }

  public static void compareScat(boolean[][] board, int[][] counts){ //checks #scat in surrounding spots
    int numRows = counts.length;
    int numCols = counts[0].length;
    for(int i=1; i<=numRows-2; i++){
      for(int j=1; j<=numCols-2; j++){
        for(int ii=i-1; ii<=i+1; ii++){
          for(int jj=j-1; jj<=j+1; jj++){
            if(board[ii][jj]==SCAT){ //this looks at all scat in all directions around the original spot
              counts[i][j]=counts[i][j]+1; //adds to the counter if scat found around it
            }
          }
        }
      }
    }
  }

  static void expose(int c, int r, boolean[][] board, boolean[][] exposed, int[][] counts) { //exposes chosen spot
    if (exposed[r][c]) return; // nothing to do
    if (board[r][c]== SCAT){
      gameLost=true; //lose game if choose a spot with scat
    }
    exposed[r][c] = true;   // expose any neighbors that have zero counts
    if (counts[r][c] > 0) return;
    for (int i = -1; i <= 1; i++) {
      for (int j = -1; j <= 1; j++) {
        int x = r+i;
        int y = c+j;
        if (!(i==1 && j==1) && x >= 1 && x < board.length-1 && y >= 1 && y < board[x].length-1) {
          if (counts[x][y] == 0) {
            expose(x, y, board, exposed, counts);
          }
          else {
            exposed[x][y] = true;
          }
        }
      }
    }
  }   
}
augarte
  • 57
  • 2
  • 8
  • Have you tried stepping through the code? – Steve Smith Feb 17 '17 at 10:28
  • You should check that the input (those 2 ints) cannot be greater than the board itself, cause otherwise you'll get an ArrayIndexOutOfBoundsException. – milt_on Feb 17 '17 at 10:33
  • hmm, no I've never done that before. where would I want breakpoints in order to test this, and how would it work with the user input? for example, if I i break after taking the input but before using it would it just store it until needed? @SteveSmith – Joel Almeida Feb 17 '17 at 10:36
  • @Miles07 its ok to get a outofboundsexception, as long as its not happening when i input 0-9 i dont mind. the only problem really is the 0s not correctly exposing all the spots next to them (though they do expose some...) – Joel Almeida Feb 17 '17 at 10:38
  • Stepping through the code still runs the code in exactly the same way, but also allows you to examine the value of vars and see which lines are being run. – Steve Smith Feb 17 '17 at 10:39
  • @JoelAlmeida yes, but you could catch it and then repeat inputting those integers^^ – milt_on Feb 17 '17 at 10:41
  • You will need to **recursively** reveal all the 0's if the neighboring square is a 0 until a non zero square is revealed. [MineSweeper](http://www.cs.ucf.edu/~dmarino/ucf/bhcsi/asgn/adv/sol/MineSweeper.java) – Uma Kanth Feb 17 '17 at 10:49
  • 1
    Oh, thanks everyone, I realized what the problem was. I accidentally switched r and c in my expose method. Thanks for the comments! – Joel Almeida Feb 17 '17 at 10:53

0 Answers0