Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Implement a graphical version of the Minefield Game . The game will have a 5x5 g

ID: 3546085 • Letter: I

Question

Implement a graphical version of the Minefield Game.  The game will have a 5x5 grid of squares, with two of the squares designated as the Start and Finish.  Hidden underneath two of the squares will be landmines.  The objective of the game is to move from the Start to the Finish without encountering any landmines.  The player cannot move diagonally.

Start

(Hidden Mine)

(Hidden Mine)

Finish

Clear

Done

Write a class MineField that extends JFrame and implements ActionListener.  It should have two panels: the top panel contains a 5x5 grid of buttons simulating a minefield and the bottom panel contains a Clear button and a Done button.  Pushing the Clear button begins the game.  It should cause two randomly chosen minefield buttons to be designated as Start and Finish, and two randomly chosen minefield buttons to have mines hidden below them.  When a user clicks on a minefield button (from Start to Finish), it should change color to show the selected path.  After a user completes the path, pushing the Done button should cause a check to see whether a mine was encountered and a message to appear indicating safe passage or failure.


So it is not a full minefield game, just a 5x5 grid, and it is all in one class.

Start

(Hidden Mine)

(Hidden Mine)

Finish

Explanation / Answer

import java.util.Scanner;

import javax.swing.*; // GUI classes


import java.awt.event.*; // for ActionListener

import java.awt.*;



public class MineSweeperGUI implements ActionListener { // GUI: ActionListener for monitoring user interaction

// main method

public static void main(String[] args){

int width, depth, bombs, result; // game setup

boolean gameOver = false;

java.util.Scanner console; // Java console Scanner

console = new java.util.Scanner(System.in);

// System.out.println("MINE SWEEPER");

// Input data

// System.out.print("Enter Mine Field Width:");

// width = console.nextInt();


// GUI: .showInputDialog(String prompt, String defaultValue)

width = Integer.parseInt(JOptionPane.showInputDialog("Enter Field Width", "20"));

//System.out.print("Enter Mine Field Depth:");

//depth = console.nextInt();

depth = Integer.parseInt(JOptionPane.showInputDialog("Enter Field Depth", "12"));

//System.out.print(" Enter Number of Bombs:");

//bombs = console.nextInt();

bombs = Integer.parseInt(JOptionPane.showInputDialog("Enter Number of Bombs", "20"));

// create MineSweeper instance

// MineSweeperGUI mGame = new MineSweeperGUI(width, depth, bombs);

mGame = new MineSweeperGUI(width, depth, bombs);


//System.out.println("PLAY MINE SWEEPER!!");


/* GUI: Afer the construction of MineSweeperGUI object

* the monitoring of user input will now be handled by the actionPerformed method as

* required by the implementation of the actionListener.

*

* The below operations will be performed in the actionPerformed method.

*

while (!gameOver) {

//mGame.printTiles();

//mGame.printTileValues(); //DEBUG

long start = System.currentTimeMillis(); // a System method for elapsed time monitoring

System.out.println("Enter Row and Column:");

depth = console.nextInt();

width = console.nextInt();

result = mGame.play(depth, width);

if (result == BAD_COORDINATE) {

System.out.println("** Incorrect Coordinate - Try Again **");

} else if (result == DONE) {

long end = System.currentTimeMillis(); // a System method for elapsed time monitoring

mGame.printTiles();

System.out.println("Congratulations, mine field cleared.");

System.out.println("Elapsed Time = " + ((end-start)/1000/60) + " minutes and " + ((end-start)/1000%60) + " seconds.");

gameOver = true;

} else if (result == LOSE) {

mGame.printTiles();

System.out.println("KA BOOM, Game Over.");

gameOver = true;

}

}

//System.out.println("Program Done");


*/

}


// GUI: this required method will receive and process user interaction

// with GUI objects.

public void actionPerformed(ActionEvent e)

{

int userRow=0, userCol=0;

int result;


Object evtSource = e.getSource(); // ActionEvent method that returns reference of object that initiated event

// determine which object initiated event

// GUI Only has the 2D array of buttons.

// Determine which button was clicked.

for (int row=1; row<=rowSize; row++) {

for (int col=1; col<=colSize; col++){

if (evtSource == tiles[row][col].display) {

// record the row and col

userRow = row;

userCol = col;

}

}

}


result = mGame.play(userRow, userCol);

// GUI: no longer possible since user can only click an enabled button.

// if (result == BAD_COORDINATE) {

// System.out.println("** Incorrect Coordinate - Try Again **");

if (result == DONE) {

//long end = System.currentTimeMillis(); // a System method for elapsed time monitoring

//mGame.printTiles();

//System.out.println("Congratulations, mine field cleared.");

JOptionPane.showMessageDialog(frame, "Congratulations, mine field cleared.");

initialize(); // GUI: new game

//System.out.println("Elapsed Time = " + ((end-start)/1000/60) + " minutes and " + ((end-start)/1000%60) + " seconds.");

//gameOver = true;

} else if (result == LOSE) {

//mGame.printTiles();

//System.out.println("KA BOOM, Game Over.");

JOptionPane.showMessageDialog(frame, "KA BOOM, Game Over.");

initialize(); // GUI: new game

//gameOver = true;

}


// GUI:

// method is done

// program will be idle until next event occurs

}


// class constants

private final char COVERED = 'X';

private final char CLEAR = ' ';

private final int BOMB = 9;

private final int OPEN = 0;

private final int PROCESSED = -1;

private static final int CONTINUE = 0;

private static final int BAD_COORDINATE = -1;

private static final int LOSE = -10;

private static final int DONE = 10;


// (A nested Tile class)

// Class Tile

// Used to monitor program values and user display information.

// (with public class variables, a.k.a struct)

private class Tile {

public int value; // program information

// public char display; // user display info

public JButton display; // GUI: use JButtons for display instead of chars

// constructor, default settings

public Tile () {

value = PROCESSED;

//display = CLEAR;

display = new JButton(""); // GUI: no button label to begin

display.setFocusable(false); // GUI: do not allow focus highlighting

}

}


// class variables

private Tile[][] tiles; // 2D array, choosing to view model as [rows][columns]

private int rowSize, colSize, numBombs;


// GUI: class variables (Added as part of March 2011 Revision)

private JFrame frame; // Main frame to contain 2D grid of buttons

private static MineSweeperGUI mGame; // Make MineSweeperGUI object class accessible for use in main and actionPerformed methods.


// GUI: class constants

private final int BUTTON_WIDTH = 50; // pixel size for each button

private final int BUTTON_HEIGHT = 50;


// Method: printTiles

// Show tile chars

public int play(int row, int col) {

int response = CONTINUE;

// check for bomb


// GUI: two conditionals no longer possible with button management.

// if (row<1 || row >rowSize || col<1 || col>colSize) {

// response = BAD_COORDINATE;

// } else if (tiles[row][col].display!=COVERED) {

// response = BAD_COORDINATE;

if (tiles[row][col].value==BOMB) {

response = LOSE;

uncoverBombs();

} else {

uncoverTile(row, col);

if (gameOver()) {

response = DONE;

}

}

// print Tile.display

return (response);

}


// Constructor: setup 2D array, initialize bombs, initialize variables.

public MineSweeperGUI(int w, int d, int b){

rowSize = d;

colSize = w;

numBombs = b;

// create arrays with a single element buffer around the array rectangle

// i.e. the top left corner of the playing area is [1][1]

tiles = new Tile[rowSize+2][colSize+2];

// fill to buffer as PROCESSED

for (int row=0; row<rowSize+2; row++) {

for (int col=0; col<colSize+2; col++){

tiles[row][col] = new Tile();

}

}


/* GUI: moved to initialize() method

// clear field values

for (int row=1; row<=rowSize; row++) {

for (int col=1; col<=colSize; col++){

tiles[row][col].value=OPEN;

tiles[row][col].display=COVERED;

}

}

*/


// GUI: Setup JFrame and fill with buttons

frame = new JFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Dimension(int width, int height)

frame.setSize(new Dimension(colSize*BUTTON_WIDTH, rowSize*BUTTON_HEIGHT)); // Dimension class in java.awt.*;

frame.setTitle("Mine Sweeper 1.0");

frame.setLayout(new GridLayout(rowSize, colSize)); // set JFrame with containers for display buttons

frame.setResizable(false); // do not allow window resizing


// GUI: add buttons on the field to the JFrame

for (int row=1; row<=rowSize; row++) {

for (int col=1; col<=colSize; col++){

// add the respective display button to the frame grid; columns filled first

frame.add(tiles[row][col].display);

// include button as a GUI object to be montitored for events

tiles[row][col].display.addActionListener(this);

}

}


frame.setVisible(true); // show frame to screen


// debug

//printTiles();

//printTileValues();

//System.out.println("+++++++++++++++++++++");

initialize();

showButtonValues(); // DEBUG tool // GUI: equivalent to printTileValues console method

}


// Method: printTiles

// Show tile chars

public void printTiles() {

// print Tile.display

for (int row=0; row<rowSize+2; row++) {

for (int col=0; col<colSize+2; col++){

System.out.printf("%2c", tiles[row][col].display);

}

System.out.println();

}

}

// Method: printTileValues

// Show tile value

public void printTileValues() {

// print Tile.display

for (int row=0; row<rowSize+2; row++) {

for (int col=0; col<colSize+2; col++){

System.out.printf("%2d", tiles[row][col].value);

}

System.out.println();

}

}


// Method: showButtonValues

// Show value associated with each button

public void showButtonValues() {

// set button text

for (int row=0; row<rowSize+2; row++) {

for (int col=0; col<colSize+2; col++){

tiles[row][col].display.setText(""+tiles[row][col].value);

}

}

}


// Method: uncoverBombs

// Game is over, uncover all bombs

public void uncoverBombs() {

for (int row=1; row<=rowSize; row++) {

for (int col=1; col<=colSize; col++){

if (tiles[row][col].value==BOMB){

// tiles[row][col].display=toDisplayChar(tiles[row][col].value);

tiles[row][col].display.setText("B"); // GUI: set button text to bomb

tiles[row][col].display.setEnabled(false); // GUI: disable button

}

}

}

}


// Method: gameOver

// check if player has one; number of tiles not processed = numBombs

public boolean gameOver() {

boolean gameover = false;

int count = 0;

for (int row=1; row<=rowSize; row++) {

for (int col=1; col<=colSize; col++){

//if (tiles[row][col].display==COVERED){

if (tiles[row][col].display.isEnabled()==true){ // GUI: count covered by counted enabled buttons

count++;

}

}

}

if (count==numBombs) {

gameover = true;

}

return(gameover);

}


// Method: initialize

// Fill field with bombs and compute neighboring bombs information

private void initialize() {

java.util.Random rand = new java.util.Random(); // Random class

int a, b, count=0;


// GUI: clear field values and set up display buttons

for (int row=1; row<=rowSize; row++) {

for (int col=1; col<=colSize; col++){

tiles[row][col].value=OPEN;

// tiles[row][col].display=COVERED;

tiles[row][col].display.setEnabled(true); // enable all buttons for a new game

tiles[row][col].display.setText(" "); // GUI: already done in Tile constructor, this line demonstrates changing button text with .setText

}

}


// add random bombs

while (count<numBombs) {

a = rand.nextInt(rowSize)+1; // pick a row (+1 for buffer compensation)

b = rand.nextInt(colSize)+1; // pick a col

// confirm no Bomb is already at the position

if (tiles[a][b].value != BOMB) {

// place a Bomb at this position

tiles[a][b].value = BOMB;

count++;

} else {

//System.out.println("Repeat");

}

}

//

// TO DO:

// Fill tiles with number of neighboring bombs information

// (quadruple nested loops with conditional)

for (int row=1; row<=rowSize; row++) {

for (int col=1; col<=colSize; col++){

// if no bomb at this position ...

if (tiles[row][col].value!=BOMB) {

// ... count number of bombs in neighboring tiles

for (int rowShift=-1; rowShift<=1; rowShift++) {

for (int colShift=-1; colShift<=1; colShift++){

// ?

if (tiles[row+rowShift][col+colShift].value==BOMB) {

tiles[row][col].value++;

}

}

} // end of neighboring Bomb count

} // end of if

}


} // end of filling




}


// Method: uncoverTile

// Update Tile.display to show selected tile, r,c.

public void uncoverTile(int r, int c) {

//java.util.Scanner console; // DEBUG

//console = new java.util.Scanner(System.in); // DEBUG


// tiles[r][c].display=toDisplayChar(tiles[r][c].value);

// GUI: use new method to updateButton

updateButton(r,c);

//printTiles(); // DEBUG

//printTileValues(); // DEBUG

//

// Use recursive concepts to display the entire open area if r,c value is OPEN

//

if (tiles[r][c].value==OPEN) {

// mark this spot as being used

tiles[r][c].value=PROCESSED;

// recursively uncoverTile to all neighboring tiles

for (int rowShift=-1; rowShift<=1; rowShift++) {

for (int colShift=-1; colShift<=1; colShift++){

// ?

//console.nextLine(); // DEBUG PAUSE

uncoverTile(r+rowShift, c+colShift);

}

}

}



}


// GUI: (added as part of March 2011 revision)

// Method: updateButton

// update button text and state at row, col

private void updateButton(int row, int col) {

int val = tiles[row][col].value;

String t;


if (val==BOMB) {

t = "B";

} else if (val==OPEN || val==PROCESSED) {

t = " ";

} else if (val==1) {t = "1";

} else if (val==2) {t = "2";

} else if (val==3) {t = "3";

} else if (val==4) {t = "4";

} else if (val==5) {t = "5";

} else if (val==6) {t = "6";

} else if (val==7) {t = "7";

} else if (val==8) {t = "8";

} else {

t = "E"; // Error

}


// adjust button

tiles[row][col].display.setText(t);

tiles[row][col].display.setEnabled(false); // disable button

}



// Method: toDisplayChar

// convert Tile.value to Tile.display character

private char toDisplayChar(int val) {

char c;

if (val==BOMB) {

c = 'B';

} else if (val==OPEN || val==PROCESSED) {

c = CLEAR;

} else if (val==1) {c = '1';

} else if (val==2) {c = '2';

} else if (val==3) {c = '3';

} else if (val==4) {c = '4';

} else if (val==5) {c = '5';

} else if (val==6) {c = '6';

} else if (val==7) {c = '7';

} else if (val==8) {c = '8';

} else {

c = 'E'; // Error

}

return (c);

}


}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote