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;
}
}