HIDE NAV

MineSweeper CLI 2020 - Pt.3

This code adds a menu for a user to actually take turns and make selections along with a printed coordinate system.
Also detection of win and loss conditions was added.
The MineSweeper Pt.3 video lesson documents the writing of this code and explains its structure.

MineSweeper.java


package ceccs;

public class MineSweeper {
    public static void main(String[] args){
        Grid gameGrid = new Grid();
        gameGrid.createTestMinefield();
        gameGrid.calcAdjNums();
        boolean keepPlaying = true;
        while(keepPlaying) {
            gameGrid.printGrid();
            gameGrid.playerTurn();
            keepPlaying = gameGrid.checkLoss();
            if (gameGrid.checkWin()) keepPlaying = false;
        }

    }
}

Grid.java


package ceccs;

import java.util.Scanner;

public class Grid {
    int width, height;
    Tile[][] tiles;

    Grid(int w, int h){
        width = w;
        height = h;

        tiles = new Tile[width][height];
        for(int j = 0 ; j < height; j++){
            for(int i = 0; i < width; i++){
                tiles[i][j] = new Tile(i, j, false);
            }
        }
    }

    Grid() {
        width = 8;
        height = 7;

        tiles = new Tile[width][height];
        for(int j = 0 ; j < height; j++){
            for(int i = 0; i < width; i++){
                tiles[i][j] = new Tile(i, j, false);
            }
        }
    }

    void printGrid(){

        System.out.print("\n    ");
        for(int i = 0; i < width; i++){
            if (i < 10) System.out.print(" " + i + " ");
            else System.out.print(i + " ");
        }
        System.out.print("\n   ");
        for(int i = 0; i < width; i++){
            System.out.print("___");
        }
        System.out.print("\n");

        for(int j = 0; j < height; j++){

            if (j<10) System.out.print(j + "  |");
            else System.out.print(j + " |");

            for (int i =0; i < width; i++){
                if (tiles[i][j].isCovered) {
                    System.out.print(" = ");
                } else if (tiles[i][j].isBomb) {
                    System.out.print(" * ");
                } else {
                    System.out.print(" " + tiles[i][j].numAdjBombs + " ");
                }
            }
            System.out.print("\n");
        }

    }

    void createTestMinefield(){
        if(width != 8 && height != 7) {
            System.out.println("Error: Grid must be 8x7 for test field!");
            return;
        } else{
            for(int j = 0; j < height; j++){
                for(int i = 0; i < width; i++){
                    //tiles[i][j].isCovered = false;
                }
            }
            tiles[0][0].isBomb = true;
            tiles[0][1].isBomb = true;
            tiles[0][2].isBomb = true;
            tiles[1][0].isBomb = true;
            tiles[1][2].isBomb = true;
            tiles[1][5].isBomb = true;
            tiles[2][0].isBomb = true;
            tiles[2][1].isBomb = true;
            tiles[2][2].isBomb = true;
            tiles[4][0].isBomb = true;
            tiles[4][1].isBomb = true;
            tiles[5][0].isBomb = true;
            tiles[5][4].isBomb = true;
            tiles[5][5].isBomb = true;
            tiles[5][6].isBomb = true;
            tiles[6][0].isBomb = true;
            tiles[6][1].isBomb = true;
            tiles[6][2].isBomb = true;
            tiles[6][4].isBomb = true;
            tiles[6][6].isBomb = true;
            tiles[7][4].isBomb = true;
            tiles[7][5].isBomb = true;

        }

    }

    void calcAdjNums(){
        for( int j = 0; j < height; j++){
            for( int i = 0; i < width; i++){
                // find out which neighbors are bombs!
                int count = 0;
                // top [i][j-1]
                if(j-1 >= 0){
                    if (tiles[i][j-1].isBomb) count++;
                }
                //top-right [i+1][j-1]
                if(i+1 < width && j-1 >= 0){
                    if(tiles[i+1][j-1].isBomb) count++;
                }
                //right[i+1][j]
                if(i+1 < width){
                    if(tiles[i+1][j].isBomb) count++;
                }
                //bottom-right[i+1][j+1]
                if(i+1 < width && j+1 < height){
                    if(tiles[i+1][j+1].isBomb) count++;
                }
                //bottom[i][j+1]
                if(j+1 < height){
                    if(tiles[i][j+1].isBomb) count++;
                }
                //bottom-left[i-1][j+1]
                if(i-1 >= 0 && j+1 < height){
                    if(tiles[i-1][j+1].isBomb) count++;
                }
                //left[i-1][j]
                if(i-1 >= 0){
                    if(tiles[i-1][j].isBomb) count++;
                }
                //top-left [i-1][j-1]
                if(i-1 >= 0 && j-1 >= 0){
                    if(tiles[i-1][j-1].isBomb) count++;
                }
                tiles[i][j].numAdjBombs = count;
            }
        }
    }

    void playerTurn(){
        Scanner scanner = new Scanner(System.in);
        int c = -1;
        while (c < 0 || c >= width) {
            System.out.println("\nSelect a Column: [0 ... " + (width - 1) + "]");
            c = scanner.nextInt();
        }
        int r = -1;
        while( r < 0 || r >= height) {
            System.out.println("Select a Row: [0 ... " + (height - 1) + "]");
            r = scanner.nextInt();
        }
        tiles[c][r].isCovered = false;
    }

    // returns false if player has blowed up.
    boolean checkLoss(){
        for(int j = 0; j < height; j++){
            for (int i = 0; i < width; i++) {
                if (tiles[i][j].isBomb && !tiles[i][j].isCovered) {
                    System.out.println();
                    System.out.println("**********");
                    System.out.println("*BOOOOOM!*");
                    System.out.println("**********");
                    System.out.println("You Lose.");
                    return false;
                }
            }
        }
        return true;
    }

    boolean checkWin(){
        boolean win = true;
        for (int j = 0; j < height; j++){
            for (int i = 0; i < width; i++){
                if(tiles[i][j].isCovered && !tiles[i][j].isBomb){
                    win = false;
                }
            }
        }
        if (win) System.out.println("\nYou Win!");

        return win;
    }

Tile.java


package ceccs;

public class Tile {

    boolean isCovered, isBomb, isFlagged;
    int numAdjBombs, x, y;

    Tile(){
        isCovered = true;
        isBomb = false;
        isFlagged = false;
        numAdjBombs = 0;
        x = 0;
        y = 0;
    }

    Tile(int xCoord, int yCoord, boolean bomb){
        x = xCoord;
        y = yCoord;
        isBomb = bomb;
        isCovered = true;
        numAdjBombs = 0;
        isFlagged = false;
    }
}