Minesweeper implementation in Java












7














I am nearly complete with my Minesweeper game but the rough idea is done.



My approach is with three classes. One is the tile class which represents a tile on the gameboard. The other is the actual gameboard which is made out of a 2-d array from the tiles. There is no function when you win but wanted to get ideas/ tips from coders. You can play until you lose.



I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile but for now that is all I could think of. Furthermore, I implemented nearly every possible edge case I could think of for the board.



The main area I would like more help in is checking whether an given coordinate is within bounds.



 public class Tile {

private int numBombsNearBy;
private String faceUp;
private boolean isBomb;

public Tile(){
numBombsNearBy = 0;
faceUp = "X";
isBomb = false;
}


GameBoard class:



public class GameBoard {

/*
TO DO:
Create method to show the rest ofthe bombs when the user loses.
*/
private Tile gameBoard;
private int xdim = 8;
private int ydim = 8;
private List<Pair> listOfBombs = new ArrayList<>();

public GameBoard(){
gameBoard = new Tile[xdim][ydim];
for(int row = 0; row < xdim; row++){
for(int col = 0; col < ydim; col++){
gameBoard[row][col] = new Tile();
}
}
}

public Tile getGameBoard(){
return gameBoard;
}
public void gameOver(Tile gameBoard){
for(int bomb = 0; bomb < listOfBombs.size();bomb++){
Pair temp = listOfBombs.get(bomb);
gameBoard[temp.getX()][temp.getY()].setFaceUp("*");
}
displaygameBoard();
}

public void displaygameBoard(){
for(int row = 0; row < xdim; row++){
for(int col = 0; col < ydim; col++){
System.out.print(gameBoard[row][col].getFaceUp() + "|");
}
System.out.println();
}
}

public int generateRandomNumber(){

Random rn = new Random();
int range = 7 - 0+ 1;
int randomNum = rn.nextInt(range) + 0;
return randomNum;
}

public void fillBoardBombs(){
int row, col = 0;
for(int i = 0; i < 9; i++){
row = generateRandomNumber();
col = generateRandomNumber();
listOfBombs.add(new Pair(row, col));
gameBoard[row][col].setBomb(true);
updateNearByBombs(row, col);
}
}

public boolean checkIfBomb(int x, int y){
if(gameBoard[x][y].isBomb() == true){
return true;
}
return false;
}

public void showTileBomb(int x, int y){
gameBoard[x][y].setFaceUp(String.valueOf(gameBoard[x][y].getNumBombsNearBy()));
}




public void updateNearByBombs(int inputrow, int inputcol){

//For (0,0)
if(inputrow == 0 && inputcol == 0){
for(int row = inputrow; row <= inputrow + 1; row++){
for(int col = inputcol; col <= inputcol + 1; col++){
if(row == inputrow && col == inputcol){
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}
}

//For (0, (1 - 6))
else if(inputrow == 0 &&(inputcol >= 1 && inputcol <= 6)){
for(int row = inputrow; row <= inputrow + 1; row++){
for(int col = inputcol - 1; col <= inputcol + 1; col++){
if(row == inputrow && col == inputcol){
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}
}

//For (0,7)
else if(inputrow == 0 && inputcol == 7){
for(int row = inputrow; row <= inputrow + 1; row++){
for(int col = inputcol - 1; col <= inputcol;col++){
if(row == inputrow && col == inputcol){
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}
}


//For (1 - 6), 0)
else if((inputrow >= 1 && inputrow <= 6) && inputcol == 0){
for(int row = inputrow - 1; row <= inputrow + 1; row++){
for(int col = inputcol; col <= inputcol + 1; col++){
if(row == inputrow && col == inputcol){
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}
}

//For (7,0)
else if(inputrow == 7 && inputcol == 0){
for(int row = inputrow - 1; row<= inputrow;row++){
for(int col = inputcol; col <= inputcol + 1;col++){
if(row == inputrow && col == inputcol){
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}
}

//For (7, (1 - 6))
else if(inputrow == 7 && (inputcol >= 1 && inputcol <= 6)){
for(int row = inputrow - 1; row <= inputrow; row++){
for(int col = inputcol - 1; col <= inputcol + 1; col++){
if(row == inputrow && col == inputcol){
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}
}

//For (7,7)
else if(inputrow == 7 && inputcol == 7){
for(int row = inputrow - 1; row <= inputrow; row++){
for(int col = inputcol - 1; col <= inputcol; col++){
if(row == inputrow && col == inputcol){
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}
}


//For (1 - 6), 7)
else if((inputrow >= 1 && inputrow <= 6) && inputcol == 7){
for(int row = inputrow - 1; row<= inputrow + 1; row++){
for(int col = inputcol - 1; col <= inputcol;col++){
if(row == inputrow && col == inputcol){
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}
}


//for the rest
else for(int row = inputrow - 1; row <= inputrow + 1; row++){
for(int col = inputcol - 1; col<= inputcol + 1;col++){
if(row == inputrow && col == inputcol) {
gameBoard[row][col].setNumBombsNearBy(0);
}else{
gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

}
}
}

}

}


Main:



public class JMineSweeper {

final static String regex = "^[0-7]\s+[0-7]$";


public static String askForUserInput() {
Scanner input = new Scanner(System.in);
String xy = null;
System.out.print("Enter x and y coordinates seperated by a space: ");
return xy = input.nextLine();
}

public static boolean isCorrectInput(String input){
if(input.matches(regex)){
return true;
}
return false;
}

public static List<Integer> convertUserInput(String input){
String splited = input.split("\s+");
List<Integer> coordinates = new ArrayList<>();
for(int i = 0; i < splited.length; i++){
coordinates.add(Integer.parseInt(splited[i]));
}
return coordinates;
}



public static void main(String args) {
Boolean gameOver = false;
GameBoard gameBoard = new GameBoard();
gameBoard.fillBoardBombs();


while(!gameOver){
try{
gameBoard.displaygameBoard();
String userInput = askForUserInput();
if(isCorrectInput(userInput)){
List<Integer> coordinates = convertUserInput(userInput);
System.out.println(coordinates.toString());
if(gameBoard.checkIfBomb(coordinates.get(0), coordinates.get(1))){
System.out.println("You lose, tile is a bomb");
gameBoard.gameOver(gameBoard.getGameBoard());
gameOver = true;
}else{
gameBoard.showTileBomb(coordinates.get(0), coordinates.get(1));
}
}
}catch (Exception e){
System.out.println("Incorrect input");
}
}
}
}'









share|improve this question





























    7














    I am nearly complete with my Minesweeper game but the rough idea is done.



    My approach is with three classes. One is the tile class which represents a tile on the gameboard. The other is the actual gameboard which is made out of a 2-d array from the tiles. There is no function when you win but wanted to get ideas/ tips from coders. You can play until you lose.



    I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile but for now that is all I could think of. Furthermore, I implemented nearly every possible edge case I could think of for the board.



    The main area I would like more help in is checking whether an given coordinate is within bounds.



     public class Tile {

    private int numBombsNearBy;
    private String faceUp;
    private boolean isBomb;

    public Tile(){
    numBombsNearBy = 0;
    faceUp = "X";
    isBomb = false;
    }


    GameBoard class:



    public class GameBoard {

    /*
    TO DO:
    Create method to show the rest ofthe bombs when the user loses.
    */
    private Tile gameBoard;
    private int xdim = 8;
    private int ydim = 8;
    private List<Pair> listOfBombs = new ArrayList<>();

    public GameBoard(){
    gameBoard = new Tile[xdim][ydim];
    for(int row = 0; row < xdim; row++){
    for(int col = 0; col < ydim; col++){
    gameBoard[row][col] = new Tile();
    }
    }
    }

    public Tile getGameBoard(){
    return gameBoard;
    }
    public void gameOver(Tile gameBoard){
    for(int bomb = 0; bomb < listOfBombs.size();bomb++){
    Pair temp = listOfBombs.get(bomb);
    gameBoard[temp.getX()][temp.getY()].setFaceUp("*");
    }
    displaygameBoard();
    }

    public void displaygameBoard(){
    for(int row = 0; row < xdim; row++){
    for(int col = 0; col < ydim; col++){
    System.out.print(gameBoard[row][col].getFaceUp() + "|");
    }
    System.out.println();
    }
    }

    public int generateRandomNumber(){

    Random rn = new Random();
    int range = 7 - 0+ 1;
    int randomNum = rn.nextInt(range) + 0;
    return randomNum;
    }

    public void fillBoardBombs(){
    int row, col = 0;
    for(int i = 0; i < 9; i++){
    row = generateRandomNumber();
    col = generateRandomNumber();
    listOfBombs.add(new Pair(row, col));
    gameBoard[row][col].setBomb(true);
    updateNearByBombs(row, col);
    }
    }

    public boolean checkIfBomb(int x, int y){
    if(gameBoard[x][y].isBomb() == true){
    return true;
    }
    return false;
    }

    public void showTileBomb(int x, int y){
    gameBoard[x][y].setFaceUp(String.valueOf(gameBoard[x][y].getNumBombsNearBy()));
    }




    public void updateNearByBombs(int inputrow, int inputcol){

    //For (0,0)
    if(inputrow == 0 && inputcol == 0){
    for(int row = inputrow; row <= inputrow + 1; row++){
    for(int col = inputcol; col <= inputcol + 1; col++){
    if(row == inputrow && col == inputcol){
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }
    }

    //For (0, (1 - 6))
    else if(inputrow == 0 &&(inputcol >= 1 && inputcol <= 6)){
    for(int row = inputrow; row <= inputrow + 1; row++){
    for(int col = inputcol - 1; col <= inputcol + 1; col++){
    if(row == inputrow && col == inputcol){
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }
    }

    //For (0,7)
    else if(inputrow == 0 && inputcol == 7){
    for(int row = inputrow; row <= inputrow + 1; row++){
    for(int col = inputcol - 1; col <= inputcol;col++){
    if(row == inputrow && col == inputcol){
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }
    }


    //For (1 - 6), 0)
    else if((inputrow >= 1 && inputrow <= 6) && inputcol == 0){
    for(int row = inputrow - 1; row <= inputrow + 1; row++){
    for(int col = inputcol; col <= inputcol + 1; col++){
    if(row == inputrow && col == inputcol){
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }
    }

    //For (7,0)
    else if(inputrow == 7 && inputcol == 0){
    for(int row = inputrow - 1; row<= inputrow;row++){
    for(int col = inputcol; col <= inputcol + 1;col++){
    if(row == inputrow && col == inputcol){
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }
    }

    //For (7, (1 - 6))
    else if(inputrow == 7 && (inputcol >= 1 && inputcol <= 6)){
    for(int row = inputrow - 1; row <= inputrow; row++){
    for(int col = inputcol - 1; col <= inputcol + 1; col++){
    if(row == inputrow && col == inputcol){
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }
    }

    //For (7,7)
    else if(inputrow == 7 && inputcol == 7){
    for(int row = inputrow - 1; row <= inputrow; row++){
    for(int col = inputcol - 1; col <= inputcol; col++){
    if(row == inputrow && col == inputcol){
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }
    }


    //For (1 - 6), 7)
    else if((inputrow >= 1 && inputrow <= 6) && inputcol == 7){
    for(int row = inputrow - 1; row<= inputrow + 1; row++){
    for(int col = inputcol - 1; col <= inputcol;col++){
    if(row == inputrow && col == inputcol){
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }
    }


    //for the rest
    else for(int row = inputrow - 1; row <= inputrow + 1; row++){
    for(int col = inputcol - 1; col<= inputcol + 1;col++){
    if(row == inputrow && col == inputcol) {
    gameBoard[row][col].setNumBombsNearBy(0);
    }else{
    gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

    }
    }
    }

    }

    }


    Main:



    public class JMineSweeper {

    final static String regex = "^[0-7]\s+[0-7]$";


    public static String askForUserInput() {
    Scanner input = new Scanner(System.in);
    String xy = null;
    System.out.print("Enter x and y coordinates seperated by a space: ");
    return xy = input.nextLine();
    }

    public static boolean isCorrectInput(String input){
    if(input.matches(regex)){
    return true;
    }
    return false;
    }

    public static List<Integer> convertUserInput(String input){
    String splited = input.split("\s+");
    List<Integer> coordinates = new ArrayList<>();
    for(int i = 0; i < splited.length; i++){
    coordinates.add(Integer.parseInt(splited[i]));
    }
    return coordinates;
    }



    public static void main(String args) {
    Boolean gameOver = false;
    GameBoard gameBoard = new GameBoard();
    gameBoard.fillBoardBombs();


    while(!gameOver){
    try{
    gameBoard.displaygameBoard();
    String userInput = askForUserInput();
    if(isCorrectInput(userInput)){
    List<Integer> coordinates = convertUserInput(userInput);
    System.out.println(coordinates.toString());
    if(gameBoard.checkIfBomb(coordinates.get(0), coordinates.get(1))){
    System.out.println("You lose, tile is a bomb");
    gameBoard.gameOver(gameBoard.getGameBoard());
    gameOver = true;
    }else{
    gameBoard.showTileBomb(coordinates.get(0), coordinates.get(1));
    }
    }
    }catch (Exception e){
    System.out.println("Incorrect input");
    }
    }
    }
    }'









    share|improve this question



























      7












      7








      7







      I am nearly complete with my Minesweeper game but the rough idea is done.



      My approach is with three classes. One is the tile class which represents a tile on the gameboard. The other is the actual gameboard which is made out of a 2-d array from the tiles. There is no function when you win but wanted to get ideas/ tips from coders. You can play until you lose.



      I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile but for now that is all I could think of. Furthermore, I implemented nearly every possible edge case I could think of for the board.



      The main area I would like more help in is checking whether an given coordinate is within bounds.



       public class Tile {

      private int numBombsNearBy;
      private String faceUp;
      private boolean isBomb;

      public Tile(){
      numBombsNearBy = 0;
      faceUp = "X";
      isBomb = false;
      }


      GameBoard class:



      public class GameBoard {

      /*
      TO DO:
      Create method to show the rest ofthe bombs when the user loses.
      */
      private Tile gameBoard;
      private int xdim = 8;
      private int ydim = 8;
      private List<Pair> listOfBombs = new ArrayList<>();

      public GameBoard(){
      gameBoard = new Tile[xdim][ydim];
      for(int row = 0; row < xdim; row++){
      for(int col = 0; col < ydim; col++){
      gameBoard[row][col] = new Tile();
      }
      }
      }

      public Tile getGameBoard(){
      return gameBoard;
      }
      public void gameOver(Tile gameBoard){
      for(int bomb = 0; bomb < listOfBombs.size();bomb++){
      Pair temp = listOfBombs.get(bomb);
      gameBoard[temp.getX()][temp.getY()].setFaceUp("*");
      }
      displaygameBoard();
      }

      public void displaygameBoard(){
      for(int row = 0; row < xdim; row++){
      for(int col = 0; col < ydim; col++){
      System.out.print(gameBoard[row][col].getFaceUp() + "|");
      }
      System.out.println();
      }
      }

      public int generateRandomNumber(){

      Random rn = new Random();
      int range = 7 - 0+ 1;
      int randomNum = rn.nextInt(range) + 0;
      return randomNum;
      }

      public void fillBoardBombs(){
      int row, col = 0;
      for(int i = 0; i < 9; i++){
      row = generateRandomNumber();
      col = generateRandomNumber();
      listOfBombs.add(new Pair(row, col));
      gameBoard[row][col].setBomb(true);
      updateNearByBombs(row, col);
      }
      }

      public boolean checkIfBomb(int x, int y){
      if(gameBoard[x][y].isBomb() == true){
      return true;
      }
      return false;
      }

      public void showTileBomb(int x, int y){
      gameBoard[x][y].setFaceUp(String.valueOf(gameBoard[x][y].getNumBombsNearBy()));
      }




      public void updateNearByBombs(int inputrow, int inputcol){

      //For (0,0)
      if(inputrow == 0 && inputcol == 0){
      for(int row = inputrow; row <= inputrow + 1; row++){
      for(int col = inputcol; col <= inputcol + 1; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (0, (1 - 6))
      else if(inputrow == 0 &&(inputcol >= 1 && inputcol <= 6)){
      for(int row = inputrow; row <= inputrow + 1; row++){
      for(int col = inputcol - 1; col <= inputcol + 1; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (0,7)
      else if(inputrow == 0 && inputcol == 7){
      for(int row = inputrow; row <= inputrow + 1; row++){
      for(int col = inputcol - 1; col <= inputcol;col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }


      //For (1 - 6), 0)
      else if((inputrow >= 1 && inputrow <= 6) && inputcol == 0){
      for(int row = inputrow - 1; row <= inputrow + 1; row++){
      for(int col = inputcol; col <= inputcol + 1; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (7,0)
      else if(inputrow == 7 && inputcol == 0){
      for(int row = inputrow - 1; row<= inputrow;row++){
      for(int col = inputcol; col <= inputcol + 1;col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (7, (1 - 6))
      else if(inputrow == 7 && (inputcol >= 1 && inputcol <= 6)){
      for(int row = inputrow - 1; row <= inputrow; row++){
      for(int col = inputcol - 1; col <= inputcol + 1; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (7,7)
      else if(inputrow == 7 && inputcol == 7){
      for(int row = inputrow - 1; row <= inputrow; row++){
      for(int col = inputcol - 1; col <= inputcol; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }


      //For (1 - 6), 7)
      else if((inputrow >= 1 && inputrow <= 6) && inputcol == 7){
      for(int row = inputrow - 1; row<= inputrow + 1; row++){
      for(int col = inputcol - 1; col <= inputcol;col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }


      //for the rest
      else for(int row = inputrow - 1; row <= inputrow + 1; row++){
      for(int col = inputcol - 1; col<= inputcol + 1;col++){
      if(row == inputrow && col == inputcol) {
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }

      }

      }


      Main:



      public class JMineSweeper {

      final static String regex = "^[0-7]\s+[0-7]$";


      public static String askForUserInput() {
      Scanner input = new Scanner(System.in);
      String xy = null;
      System.out.print("Enter x and y coordinates seperated by a space: ");
      return xy = input.nextLine();
      }

      public static boolean isCorrectInput(String input){
      if(input.matches(regex)){
      return true;
      }
      return false;
      }

      public static List<Integer> convertUserInput(String input){
      String splited = input.split("\s+");
      List<Integer> coordinates = new ArrayList<>();
      for(int i = 0; i < splited.length; i++){
      coordinates.add(Integer.parseInt(splited[i]));
      }
      return coordinates;
      }



      public static void main(String args) {
      Boolean gameOver = false;
      GameBoard gameBoard = new GameBoard();
      gameBoard.fillBoardBombs();


      while(!gameOver){
      try{
      gameBoard.displaygameBoard();
      String userInput = askForUserInput();
      if(isCorrectInput(userInput)){
      List<Integer> coordinates = convertUserInput(userInput);
      System.out.println(coordinates.toString());
      if(gameBoard.checkIfBomb(coordinates.get(0), coordinates.get(1))){
      System.out.println("You lose, tile is a bomb");
      gameBoard.gameOver(gameBoard.getGameBoard());
      gameOver = true;
      }else{
      gameBoard.showTileBomb(coordinates.get(0), coordinates.get(1));
      }
      }
      }catch (Exception e){
      System.out.println("Incorrect input");
      }
      }
      }
      }'









      share|improve this question















      I am nearly complete with my Minesweeper game but the rough idea is done.



      My approach is with three classes. One is the tile class which represents a tile on the gameboard. The other is the actual gameboard which is made out of a 2-d array from the tiles. There is no function when you win but wanted to get ideas/ tips from coders. You can play until you lose.



      I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile but for now that is all I could think of. Furthermore, I implemented nearly every possible edge case I could think of for the board.



      The main area I would like more help in is checking whether an given coordinate is within bounds.



       public class Tile {

      private int numBombsNearBy;
      private String faceUp;
      private boolean isBomb;

      public Tile(){
      numBombsNearBy = 0;
      faceUp = "X";
      isBomb = false;
      }


      GameBoard class:



      public class GameBoard {

      /*
      TO DO:
      Create method to show the rest ofthe bombs when the user loses.
      */
      private Tile gameBoard;
      private int xdim = 8;
      private int ydim = 8;
      private List<Pair> listOfBombs = new ArrayList<>();

      public GameBoard(){
      gameBoard = new Tile[xdim][ydim];
      for(int row = 0; row < xdim; row++){
      for(int col = 0; col < ydim; col++){
      gameBoard[row][col] = new Tile();
      }
      }
      }

      public Tile getGameBoard(){
      return gameBoard;
      }
      public void gameOver(Tile gameBoard){
      for(int bomb = 0; bomb < listOfBombs.size();bomb++){
      Pair temp = listOfBombs.get(bomb);
      gameBoard[temp.getX()][temp.getY()].setFaceUp("*");
      }
      displaygameBoard();
      }

      public void displaygameBoard(){
      for(int row = 0; row < xdim; row++){
      for(int col = 0; col < ydim; col++){
      System.out.print(gameBoard[row][col].getFaceUp() + "|");
      }
      System.out.println();
      }
      }

      public int generateRandomNumber(){

      Random rn = new Random();
      int range = 7 - 0+ 1;
      int randomNum = rn.nextInt(range) + 0;
      return randomNum;
      }

      public void fillBoardBombs(){
      int row, col = 0;
      for(int i = 0; i < 9; i++){
      row = generateRandomNumber();
      col = generateRandomNumber();
      listOfBombs.add(new Pair(row, col));
      gameBoard[row][col].setBomb(true);
      updateNearByBombs(row, col);
      }
      }

      public boolean checkIfBomb(int x, int y){
      if(gameBoard[x][y].isBomb() == true){
      return true;
      }
      return false;
      }

      public void showTileBomb(int x, int y){
      gameBoard[x][y].setFaceUp(String.valueOf(gameBoard[x][y].getNumBombsNearBy()));
      }




      public void updateNearByBombs(int inputrow, int inputcol){

      //For (0,0)
      if(inputrow == 0 && inputcol == 0){
      for(int row = inputrow; row <= inputrow + 1; row++){
      for(int col = inputcol; col <= inputcol + 1; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (0, (1 - 6))
      else if(inputrow == 0 &&(inputcol >= 1 && inputcol <= 6)){
      for(int row = inputrow; row <= inputrow + 1; row++){
      for(int col = inputcol - 1; col <= inputcol + 1; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (0,7)
      else if(inputrow == 0 && inputcol == 7){
      for(int row = inputrow; row <= inputrow + 1; row++){
      for(int col = inputcol - 1; col <= inputcol;col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }


      //For (1 - 6), 0)
      else if((inputrow >= 1 && inputrow <= 6) && inputcol == 0){
      for(int row = inputrow - 1; row <= inputrow + 1; row++){
      for(int col = inputcol; col <= inputcol + 1; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (7,0)
      else if(inputrow == 7 && inputcol == 0){
      for(int row = inputrow - 1; row<= inputrow;row++){
      for(int col = inputcol; col <= inputcol + 1;col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (7, (1 - 6))
      else if(inputrow == 7 && (inputcol >= 1 && inputcol <= 6)){
      for(int row = inputrow - 1; row <= inputrow; row++){
      for(int col = inputcol - 1; col <= inputcol + 1; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }

      //For (7,7)
      else if(inputrow == 7 && inputcol == 7){
      for(int row = inputrow - 1; row <= inputrow; row++){
      for(int col = inputcol - 1; col <= inputcol; col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }


      //For (1 - 6), 7)
      else if((inputrow >= 1 && inputrow <= 6) && inputcol == 7){
      for(int row = inputrow - 1; row<= inputrow + 1; row++){
      for(int col = inputcol - 1; col <= inputcol;col++){
      if(row == inputrow && col == inputcol){
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }
      }


      //for the rest
      else for(int row = inputrow - 1; row <= inputrow + 1; row++){
      for(int col = inputcol - 1; col<= inputcol + 1;col++){
      if(row == inputrow && col == inputcol) {
      gameBoard[row][col].setNumBombsNearBy(0);
      }else{
      gameBoard[row][col].setNumBombsNearBy(gameBoard[row][col].getNumBombsNearBy() + 1);

      }
      }
      }

      }

      }


      Main:



      public class JMineSweeper {

      final static String regex = "^[0-7]\s+[0-7]$";


      public static String askForUserInput() {
      Scanner input = new Scanner(System.in);
      String xy = null;
      System.out.print("Enter x and y coordinates seperated by a space: ");
      return xy = input.nextLine();
      }

      public static boolean isCorrectInput(String input){
      if(input.matches(regex)){
      return true;
      }
      return false;
      }

      public static List<Integer> convertUserInput(String input){
      String splited = input.split("\s+");
      List<Integer> coordinates = new ArrayList<>();
      for(int i = 0; i < splited.length; i++){
      coordinates.add(Integer.parseInt(splited[i]));
      }
      return coordinates;
      }



      public static void main(String args) {
      Boolean gameOver = false;
      GameBoard gameBoard = new GameBoard();
      gameBoard.fillBoardBombs();


      while(!gameOver){
      try{
      gameBoard.displaygameBoard();
      String userInput = askForUserInput();
      if(isCorrectInput(userInput)){
      List<Integer> coordinates = convertUserInput(userInput);
      System.out.println(coordinates.toString());
      if(gameBoard.checkIfBomb(coordinates.get(0), coordinates.get(1))){
      System.out.println("You lose, tile is a bomb");
      gameBoard.gameOver(gameBoard.getGameBoard());
      gameOver = true;
      }else{
      gameBoard.showTileBomb(coordinates.get(0), coordinates.get(1));
      }
      }
      }catch (Exception e){
      System.out.println("Incorrect input");
      }
      }
      }
      }'






      java minesweeper






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jun 27 '17 at 10:28









      Timothy Truckle

      4,838416




      4,838416










      asked Jun 27 '17 at 6:37









      TheLearner

      400314




      400314






















          2 Answers
          2






          active

          oldest

          votes


















          4














          Thanks for sharing the code!




          I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile [...].




          No, it isn't.



          You already modeled the fields as objects of a class Tile. You should go one step further:



          There are three types of "Tiles" with different behavior:





          1. bombs which explode when clicked,


          2. neighbors of bombs which show how many bombs are around them.


          3. safe fields without neighboring bombs


          In OOP we create new classes when we have differing behavior. So you need to create 3 more classes extending the Tile class (which should rather be an interface though...)



          Having this you can move some of the logic to the different subclasses of Tile.
          E.g.: a safe field could uncover its neighbors automatically:



          class SafeTile{
          private final Collection<Tile> neighbors = new HashSet<>();
          @Override
          public void addNeighbor(Tile neighbor){ neighbors.add(neighbor);}
          @Override
          public void coverUp(){
          for(Tile neighbor : neighbors)
          neighbors.coverUp();
          }
          }



          I implemented nearly every possible edge case I could think of for the board.




          There is a natural way to deal with that: when the tiles know their neighbors you don't need a sophisticated logic to deal with edges and corners. These tiles just have less neighbors...



          All you need is a smart way to fill the game board initially. YOu could do like this:



          class GameBoard{
          private final Tile fields;
          GameBoard(int width, int height, int bombCount){
          fields = new Tile[width][height];
          // deploy bombs
          List<Pair> fieldPositions = new ArrayList<>();
          for(int i =0;i<width;i++)
          for(int j=0; j<height;j++)
          fieldPositions.add(new Pair(i,j));
          List<Pair> bombPositions = new ArrayList<>();
          for(int i =0;i< bombCount;i++)
          bombPositions.add(fieldPositions.remove(new Random().nextInt(fieldPositions.size()));
          for(Pair bombPos : bombPositions){
          fields[bombPos.x][bombPos.y]= new TileBomb();
          // set bomb neigbors, corners and edges not yet handled...
          for(int i =-1; i< 2; i++)
          for(int j =-1; j< 2; j++)
          if(null==fields[bombPos.x+i][bombPos.y+j])
          fields[bombPos.x+i][bombPos.y+j]= new NeighborTile();
          }
          // set safe fields
          for(int i =0;i<width;i++)
          for(int j=0; j<height;j++)
          if(null==fields[i][j])
          fields[i][j]= new SafeTile();
          // set neigbours
          for(int i =0;i<width-1;i++)
          for(int j=0; j<height-1;j++){
          fields[i][j].addNeigbor(fields[i][j+1]);
          fields[i][j].addNeigbor(fields[i+1][j+1]);
          fields[i][j].addNeigbor(fields[i+1][j]);
          fields[i][j+1].addNeigbor(fields[i][j]);
          fields[i+1][j+1].addNeigbor(fields[i][j]);
          fields[i+1][j].addNeigbor(fields[i][j]);
          }
          }
          }


          The advantage is that you do not need handle field positions during runtime anymore. Just select a field and tell it that it has been uncovered.






          Why in the if statement for setting neighbor bombs is there if(null == field...).




          Initially there are no objects in the field array, any field refers to null.



          After placing a new bomb (b) we want to place all neighbor fields with new objects:



           - - -      n n n
          - b - -> n b n
          - - - n n n


          The two inner loops iterate the sequence -1, 0, 1. This means we get all 9 possible combinations. But at x+0 - y+0 is the bomb object we don't want to overwrite.
          We could have checked for k and l not being both 0 which would have worked for the current bomb position. But what if we have placed another bomb (B) in a field nearby in some previous iteration?



           N N N -
          N B N -
          N N b -
          - - - -


          By checking the possible neighbor field for being empty (referencing to null) we do not need a sophisticated logic to avoid replacing the actual or any previously placed bomb with a neighbor object by accident. We also don't replace any already placed neighbor field (except with a bomb) but that is less important.



          On the other hand a new bomb can (and should) replace a previously placed neighbor. Therefore we do not check when placing a bomb.






          why does a safe tile need to know tis neighbors




          A SafeTile is a field without a bomb in any of its neighbor fields. By the rules of "mine sweeper" all connected safe and neighbor fields are uncovered when a safe field is hit.



          By having the SafeTile knowing its neighbors (which are either of class SafeTile too or of class NeighborTile, but never bombs) the current SafeTile can call the coverUp() method on its neigbors. Any neighbor which is a SafeTile itself will also propagate the call to its neighbors recursively, causing a chain reaction.
          keep in mind that my quick shot causes an infinite loop...




          and what would be the meaning of cover up?




          The method coverUp() is meant to be called by the User Interface (UI) to trigger the state change from "unknown" to "visited". Obviously the subclasses of Tile will behave differently when this method is called on them.






          share|improve this answer























          • Thank you for your feedback Timothy! I am going over the code to see how I can implement it but before I do, I have a question. Why in the if statement for setting neighbor bombs is there if(null == field...). I have not seen this before and wanted to get an understanding of it.
            – TheLearner
            Jun 27 '17 at 19:56










          • @TheLearner "Why in the if statement for setting neighbor bombs is there if(null == field...). " - Answer updated.
            – Timothy Truckle
            Jun 27 '17 at 20:44










          • Awesome explanation! One more question if I may. Within the set safe fields code block, why do we make all other tiles Neighbor tiles?
            – TheLearner
            Jun 27 '17 at 20:49












          • @TheLearner "Within the set safe fields code block, why do we make all other tiles Neighbor tiles?" - because I did not correct it after copy/paste (but now...) ;o)
            – Timothy Truckle
            Jun 27 '17 at 20:51












          • Actually I have one more question why does a safe tile need to know tis neighbors and what would be the meaning of cover up?, Thank you for your feedback this is helping me! I am going to make these improvements within my code thank you Timothy!
            – TheLearner
            Jun 27 '17 at 20:58



















          0














          You can check the Minesweeper Java code present in https://tutorialflow.com where there is a working code in Swing. You can download and execute in your editor with the icons.
          https://tutorialflow.com/generalexamples/minesweeper-in-java/






          share|improve this answer








          New contributor




          coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.


















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f166737%2fminesweeper-implementation-in-java%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            4














            Thanks for sharing the code!




            I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile [...].




            No, it isn't.



            You already modeled the fields as objects of a class Tile. You should go one step further:



            There are three types of "Tiles" with different behavior:





            1. bombs which explode when clicked,


            2. neighbors of bombs which show how many bombs are around them.


            3. safe fields without neighboring bombs


            In OOP we create new classes when we have differing behavior. So you need to create 3 more classes extending the Tile class (which should rather be an interface though...)



            Having this you can move some of the logic to the different subclasses of Tile.
            E.g.: a safe field could uncover its neighbors automatically:



            class SafeTile{
            private final Collection<Tile> neighbors = new HashSet<>();
            @Override
            public void addNeighbor(Tile neighbor){ neighbors.add(neighbor);}
            @Override
            public void coverUp(){
            for(Tile neighbor : neighbors)
            neighbors.coverUp();
            }
            }



            I implemented nearly every possible edge case I could think of for the board.




            There is a natural way to deal with that: when the tiles know their neighbors you don't need a sophisticated logic to deal with edges and corners. These tiles just have less neighbors...



            All you need is a smart way to fill the game board initially. YOu could do like this:



            class GameBoard{
            private final Tile fields;
            GameBoard(int width, int height, int bombCount){
            fields = new Tile[width][height];
            // deploy bombs
            List<Pair> fieldPositions = new ArrayList<>();
            for(int i =0;i<width;i++)
            for(int j=0; j<height;j++)
            fieldPositions.add(new Pair(i,j));
            List<Pair> bombPositions = new ArrayList<>();
            for(int i =0;i< bombCount;i++)
            bombPositions.add(fieldPositions.remove(new Random().nextInt(fieldPositions.size()));
            for(Pair bombPos : bombPositions){
            fields[bombPos.x][bombPos.y]= new TileBomb();
            // set bomb neigbors, corners and edges not yet handled...
            for(int i =-1; i< 2; i++)
            for(int j =-1; j< 2; j++)
            if(null==fields[bombPos.x+i][bombPos.y+j])
            fields[bombPos.x+i][bombPos.y+j]= new NeighborTile();
            }
            // set safe fields
            for(int i =0;i<width;i++)
            for(int j=0; j<height;j++)
            if(null==fields[i][j])
            fields[i][j]= new SafeTile();
            // set neigbours
            for(int i =0;i<width-1;i++)
            for(int j=0; j<height-1;j++){
            fields[i][j].addNeigbor(fields[i][j+1]);
            fields[i][j].addNeigbor(fields[i+1][j+1]);
            fields[i][j].addNeigbor(fields[i+1][j]);
            fields[i][j+1].addNeigbor(fields[i][j]);
            fields[i+1][j+1].addNeigbor(fields[i][j]);
            fields[i+1][j].addNeigbor(fields[i][j]);
            }
            }
            }


            The advantage is that you do not need handle field positions during runtime anymore. Just select a field and tell it that it has been uncovered.






            Why in the if statement for setting neighbor bombs is there if(null == field...).




            Initially there are no objects in the field array, any field refers to null.



            After placing a new bomb (b) we want to place all neighbor fields with new objects:



             - - -      n n n
            - b - -> n b n
            - - - n n n


            The two inner loops iterate the sequence -1, 0, 1. This means we get all 9 possible combinations. But at x+0 - y+0 is the bomb object we don't want to overwrite.
            We could have checked for k and l not being both 0 which would have worked for the current bomb position. But what if we have placed another bomb (B) in a field nearby in some previous iteration?



             N N N -
            N B N -
            N N b -
            - - - -


            By checking the possible neighbor field for being empty (referencing to null) we do not need a sophisticated logic to avoid replacing the actual or any previously placed bomb with a neighbor object by accident. We also don't replace any already placed neighbor field (except with a bomb) but that is less important.



            On the other hand a new bomb can (and should) replace a previously placed neighbor. Therefore we do not check when placing a bomb.






            why does a safe tile need to know tis neighbors




            A SafeTile is a field without a bomb in any of its neighbor fields. By the rules of "mine sweeper" all connected safe and neighbor fields are uncovered when a safe field is hit.



            By having the SafeTile knowing its neighbors (which are either of class SafeTile too or of class NeighborTile, but never bombs) the current SafeTile can call the coverUp() method on its neigbors. Any neighbor which is a SafeTile itself will also propagate the call to its neighbors recursively, causing a chain reaction.
            keep in mind that my quick shot causes an infinite loop...




            and what would be the meaning of cover up?




            The method coverUp() is meant to be called by the User Interface (UI) to trigger the state change from "unknown" to "visited". Obviously the subclasses of Tile will behave differently when this method is called on them.






            share|improve this answer























            • Thank you for your feedback Timothy! I am going over the code to see how I can implement it but before I do, I have a question. Why in the if statement for setting neighbor bombs is there if(null == field...). I have not seen this before and wanted to get an understanding of it.
              – TheLearner
              Jun 27 '17 at 19:56










            • @TheLearner "Why in the if statement for setting neighbor bombs is there if(null == field...). " - Answer updated.
              – Timothy Truckle
              Jun 27 '17 at 20:44










            • Awesome explanation! One more question if I may. Within the set safe fields code block, why do we make all other tiles Neighbor tiles?
              – TheLearner
              Jun 27 '17 at 20:49












            • @TheLearner "Within the set safe fields code block, why do we make all other tiles Neighbor tiles?" - because I did not correct it after copy/paste (but now...) ;o)
              – Timothy Truckle
              Jun 27 '17 at 20:51












            • Actually I have one more question why does a safe tile need to know tis neighbors and what would be the meaning of cover up?, Thank you for your feedback this is helping me! I am going to make these improvements within my code thank you Timothy!
              – TheLearner
              Jun 27 '17 at 20:58
















            4














            Thanks for sharing the code!




            I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile [...].




            No, it isn't.



            You already modeled the fields as objects of a class Tile. You should go one step further:



            There are three types of "Tiles" with different behavior:





            1. bombs which explode when clicked,


            2. neighbors of bombs which show how many bombs are around them.


            3. safe fields without neighboring bombs


            In OOP we create new classes when we have differing behavior. So you need to create 3 more classes extending the Tile class (which should rather be an interface though...)



            Having this you can move some of the logic to the different subclasses of Tile.
            E.g.: a safe field could uncover its neighbors automatically:



            class SafeTile{
            private final Collection<Tile> neighbors = new HashSet<>();
            @Override
            public void addNeighbor(Tile neighbor){ neighbors.add(neighbor);}
            @Override
            public void coverUp(){
            for(Tile neighbor : neighbors)
            neighbors.coverUp();
            }
            }



            I implemented nearly every possible edge case I could think of for the board.




            There is a natural way to deal with that: when the tiles know their neighbors you don't need a sophisticated logic to deal with edges and corners. These tiles just have less neighbors...



            All you need is a smart way to fill the game board initially. YOu could do like this:



            class GameBoard{
            private final Tile fields;
            GameBoard(int width, int height, int bombCount){
            fields = new Tile[width][height];
            // deploy bombs
            List<Pair> fieldPositions = new ArrayList<>();
            for(int i =0;i<width;i++)
            for(int j=0; j<height;j++)
            fieldPositions.add(new Pair(i,j));
            List<Pair> bombPositions = new ArrayList<>();
            for(int i =0;i< bombCount;i++)
            bombPositions.add(fieldPositions.remove(new Random().nextInt(fieldPositions.size()));
            for(Pair bombPos : bombPositions){
            fields[bombPos.x][bombPos.y]= new TileBomb();
            // set bomb neigbors, corners and edges not yet handled...
            for(int i =-1; i< 2; i++)
            for(int j =-1; j< 2; j++)
            if(null==fields[bombPos.x+i][bombPos.y+j])
            fields[bombPos.x+i][bombPos.y+j]= new NeighborTile();
            }
            // set safe fields
            for(int i =0;i<width;i++)
            for(int j=0; j<height;j++)
            if(null==fields[i][j])
            fields[i][j]= new SafeTile();
            // set neigbours
            for(int i =0;i<width-1;i++)
            for(int j=0; j<height-1;j++){
            fields[i][j].addNeigbor(fields[i][j+1]);
            fields[i][j].addNeigbor(fields[i+1][j+1]);
            fields[i][j].addNeigbor(fields[i+1][j]);
            fields[i][j+1].addNeigbor(fields[i][j]);
            fields[i+1][j+1].addNeigbor(fields[i][j]);
            fields[i+1][j].addNeigbor(fields[i][j]);
            }
            }
            }


            The advantage is that you do not need handle field positions during runtime anymore. Just select a field and tell it that it has been uncovered.






            Why in the if statement for setting neighbor bombs is there if(null == field...).




            Initially there are no objects in the field array, any field refers to null.



            After placing a new bomb (b) we want to place all neighbor fields with new objects:



             - - -      n n n
            - b - -> n b n
            - - - n n n


            The two inner loops iterate the sequence -1, 0, 1. This means we get all 9 possible combinations. But at x+0 - y+0 is the bomb object we don't want to overwrite.
            We could have checked for k and l not being both 0 which would have worked for the current bomb position. But what if we have placed another bomb (B) in a field nearby in some previous iteration?



             N N N -
            N B N -
            N N b -
            - - - -


            By checking the possible neighbor field for being empty (referencing to null) we do not need a sophisticated logic to avoid replacing the actual or any previously placed bomb with a neighbor object by accident. We also don't replace any already placed neighbor field (except with a bomb) but that is less important.



            On the other hand a new bomb can (and should) replace a previously placed neighbor. Therefore we do not check when placing a bomb.






            why does a safe tile need to know tis neighbors




            A SafeTile is a field without a bomb in any of its neighbor fields. By the rules of "mine sweeper" all connected safe and neighbor fields are uncovered when a safe field is hit.



            By having the SafeTile knowing its neighbors (which are either of class SafeTile too or of class NeighborTile, but never bombs) the current SafeTile can call the coverUp() method on its neigbors. Any neighbor which is a SafeTile itself will also propagate the call to its neighbors recursively, causing a chain reaction.
            keep in mind that my quick shot causes an infinite loop...




            and what would be the meaning of cover up?




            The method coverUp() is meant to be called by the User Interface (UI) to trigger the state change from "unknown" to "visited". Obviously the subclasses of Tile will behave differently when this method is called on them.






            share|improve this answer























            • Thank you for your feedback Timothy! I am going over the code to see how I can implement it but before I do, I have a question. Why in the if statement for setting neighbor bombs is there if(null == field...). I have not seen this before and wanted to get an understanding of it.
              – TheLearner
              Jun 27 '17 at 19:56










            • @TheLearner "Why in the if statement for setting neighbor bombs is there if(null == field...). " - Answer updated.
              – Timothy Truckle
              Jun 27 '17 at 20:44










            • Awesome explanation! One more question if I may. Within the set safe fields code block, why do we make all other tiles Neighbor tiles?
              – TheLearner
              Jun 27 '17 at 20:49












            • @TheLearner "Within the set safe fields code block, why do we make all other tiles Neighbor tiles?" - because I did not correct it after copy/paste (but now...) ;o)
              – Timothy Truckle
              Jun 27 '17 at 20:51












            • Actually I have one more question why does a safe tile need to know tis neighbors and what would be the meaning of cover up?, Thank you for your feedback this is helping me! I am going to make these improvements within my code thank you Timothy!
              – TheLearner
              Jun 27 '17 at 20:58














            4












            4








            4






            Thanks for sharing the code!




            I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile [...].




            No, it isn't.



            You already modeled the fields as objects of a class Tile. You should go one step further:



            There are three types of "Tiles" with different behavior:





            1. bombs which explode when clicked,


            2. neighbors of bombs which show how many bombs are around them.


            3. safe fields without neighboring bombs


            In OOP we create new classes when we have differing behavior. So you need to create 3 more classes extending the Tile class (which should rather be an interface though...)



            Having this you can move some of the logic to the different subclasses of Tile.
            E.g.: a safe field could uncover its neighbors automatically:



            class SafeTile{
            private final Collection<Tile> neighbors = new HashSet<>();
            @Override
            public void addNeighbor(Tile neighbor){ neighbors.add(neighbor);}
            @Override
            public void coverUp(){
            for(Tile neighbor : neighbors)
            neighbors.coverUp();
            }
            }



            I implemented nearly every possible edge case I could think of for the board.




            There is a natural way to deal with that: when the tiles know their neighbors you don't need a sophisticated logic to deal with edges and corners. These tiles just have less neighbors...



            All you need is a smart way to fill the game board initially. YOu could do like this:



            class GameBoard{
            private final Tile fields;
            GameBoard(int width, int height, int bombCount){
            fields = new Tile[width][height];
            // deploy bombs
            List<Pair> fieldPositions = new ArrayList<>();
            for(int i =0;i<width;i++)
            for(int j=0; j<height;j++)
            fieldPositions.add(new Pair(i,j));
            List<Pair> bombPositions = new ArrayList<>();
            for(int i =0;i< bombCount;i++)
            bombPositions.add(fieldPositions.remove(new Random().nextInt(fieldPositions.size()));
            for(Pair bombPos : bombPositions){
            fields[bombPos.x][bombPos.y]= new TileBomb();
            // set bomb neigbors, corners and edges not yet handled...
            for(int i =-1; i< 2; i++)
            for(int j =-1; j< 2; j++)
            if(null==fields[bombPos.x+i][bombPos.y+j])
            fields[bombPos.x+i][bombPos.y+j]= new NeighborTile();
            }
            // set safe fields
            for(int i =0;i<width;i++)
            for(int j=0; j<height;j++)
            if(null==fields[i][j])
            fields[i][j]= new SafeTile();
            // set neigbours
            for(int i =0;i<width-1;i++)
            for(int j=0; j<height-1;j++){
            fields[i][j].addNeigbor(fields[i][j+1]);
            fields[i][j].addNeigbor(fields[i+1][j+1]);
            fields[i][j].addNeigbor(fields[i+1][j]);
            fields[i][j+1].addNeigbor(fields[i][j]);
            fields[i+1][j+1].addNeigbor(fields[i][j]);
            fields[i+1][j].addNeigbor(fields[i][j]);
            }
            }
            }


            The advantage is that you do not need handle field positions during runtime anymore. Just select a field and tell it that it has been uncovered.






            Why in the if statement for setting neighbor bombs is there if(null == field...).




            Initially there are no objects in the field array, any field refers to null.



            After placing a new bomb (b) we want to place all neighbor fields with new objects:



             - - -      n n n
            - b - -> n b n
            - - - n n n


            The two inner loops iterate the sequence -1, 0, 1. This means we get all 9 possible combinations. But at x+0 - y+0 is the bomb object we don't want to overwrite.
            We could have checked for k and l not being both 0 which would have worked for the current bomb position. But what if we have placed another bomb (B) in a field nearby in some previous iteration?



             N N N -
            N B N -
            N N b -
            - - - -


            By checking the possible neighbor field for being empty (referencing to null) we do not need a sophisticated logic to avoid replacing the actual or any previously placed bomb with a neighbor object by accident. We also don't replace any already placed neighbor field (except with a bomb) but that is less important.



            On the other hand a new bomb can (and should) replace a previously placed neighbor. Therefore we do not check when placing a bomb.






            why does a safe tile need to know tis neighbors




            A SafeTile is a field without a bomb in any of its neighbor fields. By the rules of "mine sweeper" all connected safe and neighbor fields are uncovered when a safe field is hit.



            By having the SafeTile knowing its neighbors (which are either of class SafeTile too or of class NeighborTile, but never bombs) the current SafeTile can call the coverUp() method on its neigbors. Any neighbor which is a SafeTile itself will also propagate the call to its neighbors recursively, causing a chain reaction.
            keep in mind that my quick shot causes an infinite loop...




            and what would be the meaning of cover up?




            The method coverUp() is meant to be called by the User Interface (UI) to trigger the state change from "unknown" to "visited". Obviously the subclasses of Tile will behave differently when this method is called on them.






            share|improve this answer














            Thanks for sharing the code!




            I have my concerns with the current way I have coded things for example, I am unsure if using faceUp is the best way I can represent an unopened tile [...].




            No, it isn't.



            You already modeled the fields as objects of a class Tile. You should go one step further:



            There are three types of "Tiles" with different behavior:





            1. bombs which explode when clicked,


            2. neighbors of bombs which show how many bombs are around them.


            3. safe fields without neighboring bombs


            In OOP we create new classes when we have differing behavior. So you need to create 3 more classes extending the Tile class (which should rather be an interface though...)



            Having this you can move some of the logic to the different subclasses of Tile.
            E.g.: a safe field could uncover its neighbors automatically:



            class SafeTile{
            private final Collection<Tile> neighbors = new HashSet<>();
            @Override
            public void addNeighbor(Tile neighbor){ neighbors.add(neighbor);}
            @Override
            public void coverUp(){
            for(Tile neighbor : neighbors)
            neighbors.coverUp();
            }
            }



            I implemented nearly every possible edge case I could think of for the board.




            There is a natural way to deal with that: when the tiles know their neighbors you don't need a sophisticated logic to deal with edges and corners. These tiles just have less neighbors...



            All you need is a smart way to fill the game board initially. YOu could do like this:



            class GameBoard{
            private final Tile fields;
            GameBoard(int width, int height, int bombCount){
            fields = new Tile[width][height];
            // deploy bombs
            List<Pair> fieldPositions = new ArrayList<>();
            for(int i =0;i<width;i++)
            for(int j=0; j<height;j++)
            fieldPositions.add(new Pair(i,j));
            List<Pair> bombPositions = new ArrayList<>();
            for(int i =0;i< bombCount;i++)
            bombPositions.add(fieldPositions.remove(new Random().nextInt(fieldPositions.size()));
            for(Pair bombPos : bombPositions){
            fields[bombPos.x][bombPos.y]= new TileBomb();
            // set bomb neigbors, corners and edges not yet handled...
            for(int i =-1; i< 2; i++)
            for(int j =-1; j< 2; j++)
            if(null==fields[bombPos.x+i][bombPos.y+j])
            fields[bombPos.x+i][bombPos.y+j]= new NeighborTile();
            }
            // set safe fields
            for(int i =0;i<width;i++)
            for(int j=0; j<height;j++)
            if(null==fields[i][j])
            fields[i][j]= new SafeTile();
            // set neigbours
            for(int i =0;i<width-1;i++)
            for(int j=0; j<height-1;j++){
            fields[i][j].addNeigbor(fields[i][j+1]);
            fields[i][j].addNeigbor(fields[i+1][j+1]);
            fields[i][j].addNeigbor(fields[i+1][j]);
            fields[i][j+1].addNeigbor(fields[i][j]);
            fields[i+1][j+1].addNeigbor(fields[i][j]);
            fields[i+1][j].addNeigbor(fields[i][j]);
            }
            }
            }


            The advantage is that you do not need handle field positions during runtime anymore. Just select a field and tell it that it has been uncovered.






            Why in the if statement for setting neighbor bombs is there if(null == field...).




            Initially there are no objects in the field array, any field refers to null.



            After placing a new bomb (b) we want to place all neighbor fields with new objects:



             - - -      n n n
            - b - -> n b n
            - - - n n n


            The two inner loops iterate the sequence -1, 0, 1. This means we get all 9 possible combinations. But at x+0 - y+0 is the bomb object we don't want to overwrite.
            We could have checked for k and l not being both 0 which would have worked for the current bomb position. But what if we have placed another bomb (B) in a field nearby in some previous iteration?



             N N N -
            N B N -
            N N b -
            - - - -


            By checking the possible neighbor field for being empty (referencing to null) we do not need a sophisticated logic to avoid replacing the actual or any previously placed bomb with a neighbor object by accident. We also don't replace any already placed neighbor field (except with a bomb) but that is less important.



            On the other hand a new bomb can (and should) replace a previously placed neighbor. Therefore we do not check when placing a bomb.






            why does a safe tile need to know tis neighbors




            A SafeTile is a field without a bomb in any of its neighbor fields. By the rules of "mine sweeper" all connected safe and neighbor fields are uncovered when a safe field is hit.



            By having the SafeTile knowing its neighbors (which are either of class SafeTile too or of class NeighborTile, but never bombs) the current SafeTile can call the coverUp() method on its neigbors. Any neighbor which is a SafeTile itself will also propagate the call to its neighbors recursively, causing a chain reaction.
            keep in mind that my quick shot causes an infinite loop...




            and what would be the meaning of cover up?




            The method coverUp() is meant to be called by the User Interface (UI) to trigger the state change from "unknown" to "visited". Obviously the subclasses of Tile will behave differently when this method is called on them.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jun 27 '17 at 21:11

























            answered Jun 27 '17 at 12:01









            Timothy Truckle

            4,838416




            4,838416












            • Thank you for your feedback Timothy! I am going over the code to see how I can implement it but before I do, I have a question. Why in the if statement for setting neighbor bombs is there if(null == field...). I have not seen this before and wanted to get an understanding of it.
              – TheLearner
              Jun 27 '17 at 19:56










            • @TheLearner "Why in the if statement for setting neighbor bombs is there if(null == field...). " - Answer updated.
              – Timothy Truckle
              Jun 27 '17 at 20:44










            • Awesome explanation! One more question if I may. Within the set safe fields code block, why do we make all other tiles Neighbor tiles?
              – TheLearner
              Jun 27 '17 at 20:49












            • @TheLearner "Within the set safe fields code block, why do we make all other tiles Neighbor tiles?" - because I did not correct it after copy/paste (but now...) ;o)
              – Timothy Truckle
              Jun 27 '17 at 20:51












            • Actually I have one more question why does a safe tile need to know tis neighbors and what would be the meaning of cover up?, Thank you for your feedback this is helping me! I am going to make these improvements within my code thank you Timothy!
              – TheLearner
              Jun 27 '17 at 20:58


















            • Thank you for your feedback Timothy! I am going over the code to see how I can implement it but before I do, I have a question. Why in the if statement for setting neighbor bombs is there if(null == field...). I have not seen this before and wanted to get an understanding of it.
              – TheLearner
              Jun 27 '17 at 19:56










            • @TheLearner "Why in the if statement for setting neighbor bombs is there if(null == field...). " - Answer updated.
              – Timothy Truckle
              Jun 27 '17 at 20:44










            • Awesome explanation! One more question if I may. Within the set safe fields code block, why do we make all other tiles Neighbor tiles?
              – TheLearner
              Jun 27 '17 at 20:49












            • @TheLearner "Within the set safe fields code block, why do we make all other tiles Neighbor tiles?" - because I did not correct it after copy/paste (but now...) ;o)
              – Timothy Truckle
              Jun 27 '17 at 20:51












            • Actually I have one more question why does a safe tile need to know tis neighbors and what would be the meaning of cover up?, Thank you for your feedback this is helping me! I am going to make these improvements within my code thank you Timothy!
              – TheLearner
              Jun 27 '17 at 20:58
















            Thank you for your feedback Timothy! I am going over the code to see how I can implement it but before I do, I have a question. Why in the if statement for setting neighbor bombs is there if(null == field...). I have not seen this before and wanted to get an understanding of it.
            – TheLearner
            Jun 27 '17 at 19:56




            Thank you for your feedback Timothy! I am going over the code to see how I can implement it but before I do, I have a question. Why in the if statement for setting neighbor bombs is there if(null == field...). I have not seen this before and wanted to get an understanding of it.
            – TheLearner
            Jun 27 '17 at 19:56












            @TheLearner "Why in the if statement for setting neighbor bombs is there if(null == field...). " - Answer updated.
            – Timothy Truckle
            Jun 27 '17 at 20:44




            @TheLearner "Why in the if statement for setting neighbor bombs is there if(null == field...). " - Answer updated.
            – Timothy Truckle
            Jun 27 '17 at 20:44












            Awesome explanation! One more question if I may. Within the set safe fields code block, why do we make all other tiles Neighbor tiles?
            – TheLearner
            Jun 27 '17 at 20:49






            Awesome explanation! One more question if I may. Within the set safe fields code block, why do we make all other tiles Neighbor tiles?
            – TheLearner
            Jun 27 '17 at 20:49














            @TheLearner "Within the set safe fields code block, why do we make all other tiles Neighbor tiles?" - because I did not correct it after copy/paste (but now...) ;o)
            – Timothy Truckle
            Jun 27 '17 at 20:51






            @TheLearner "Within the set safe fields code block, why do we make all other tiles Neighbor tiles?" - because I did not correct it after copy/paste (but now...) ;o)
            – Timothy Truckle
            Jun 27 '17 at 20:51














            Actually I have one more question why does a safe tile need to know tis neighbors and what would be the meaning of cover up?, Thank you for your feedback this is helping me! I am going to make these improvements within my code thank you Timothy!
            – TheLearner
            Jun 27 '17 at 20:58




            Actually I have one more question why does a safe tile need to know tis neighbors and what would be the meaning of cover up?, Thank you for your feedback this is helping me! I am going to make these improvements within my code thank you Timothy!
            – TheLearner
            Jun 27 '17 at 20:58













            0














            You can check the Minesweeper Java code present in https://tutorialflow.com where there is a working code in Swing. You can download and execute in your editor with the icons.
            https://tutorialflow.com/generalexamples/minesweeper-in-java/






            share|improve this answer








            New contributor




            coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.























              0














              You can check the Minesweeper Java code present in https://tutorialflow.com where there is a working code in Swing. You can download and execute in your editor with the icons.
              https://tutorialflow.com/generalexamples/minesweeper-in-java/






              share|improve this answer








              New contributor




              coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
              Check out our Code of Conduct.





















                0












                0








                0






                You can check the Minesweeper Java code present in https://tutorialflow.com where there is a working code in Swing. You can download and execute in your editor with the icons.
                https://tutorialflow.com/generalexamples/minesweeper-in-java/






                share|improve this answer








                New contributor




                coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.









                You can check the Minesweeper Java code present in https://tutorialflow.com where there is a working code in Swing. You can download and execute in your editor with the icons.
                https://tutorialflow.com/generalexamples/minesweeper-in-java/







                share|improve this answer








                New contributor




                coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.









                share|improve this answer



                share|improve this answer






                New contributor




                coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.









                answered 16 mins ago









                coder28

                1




                1




                New contributor




                coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.





                New contributor





                coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.






                coder28 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f166737%2fminesweeper-implementation-in-java%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Morgemoulin

                    Scott Moir

                    Souastre