Question: The following program works as needed using three classes, but needs to be adjusted to acomplish the same program using two additional classes. MineWalker and
The following program works as needed using three classes, but needs to be adjusted to acomplish the same program using two additional classes. MineWalker and MineWalkerPanel need to expand to also use MineFieldButton and MineFieldPanel. There should be no changes to RandomWalk.The goal is as follows: MineWalker.java - The driver class. Creates the JFrame and add the MineWalkerPanel to the frame. MineWalkerPanel.java - The main game panel class. Must extend JPanel. Creates and adds sub-panels. Manages all game components and the ActionListeners. MineFieldPanel.java - The mine field panel class. Must extend JPanel. Creates and manages grid of MineFieldButtons. MineFieldButton.java - The mine field button class. Must extend JButton. Represents and manages the state of a single button in the MineFieldGrid.
//MineWalker.java
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Random; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.UIManager; @SuppressWarnings("serial") public class MineWalker extends JPanel { static JFrame frame; private JButton newGame, showMines, showPath; private JSlider gridSize, difficultySlider; private JLabel redText, orangeText, yellowText, greenText, blueText, blackText, grayText, violetText, indigoText, sizeLabel, difficultyLabel, livesLabel, scoreLabel; private JPanel red, orange, yellow, green, blue, black, gray, violet, indigo, scorePanel, sizePanel, difficultyPanel; private MineWalkerPanel board; private int nearbyMines, size = 10, difficulty = 25, score = 500, lives = 5; private static final int GRIDSIZE_MIN = 0, GRIDSIZE_MAX = 20, GRIDSIZE_START = 10, DIFFICULTY_MIN = 0, DIFFICULTY_MAX = 100, DIFFICULTY_START = 25; final Color RED = new Color(230, 25, 75); final Color ORANGE = new Color(245, 130, 48); final Color YELLOW = new Color(255, 225, 25); final Color GREEN = new Color(60, 180, 75); final Color BLUE = new Color(0, 130, 200); final Color INDIGO = new Color(145, 30, 180); final Color VIOLET = new Color(100, 105, 255);
Boolean[][] mines; JButton[][] buttons; Random rand; ArrayList path; RandomWalk walk; public MineWalker(int width, int height) { /* SOUTH PANEL */ // the main south panel JPanel southPanel = new JPanel(); // each sub panel JPanel sizePanel = new JPanel(); JPanel difficultyPanel = new JPanel(); difficultyLabel = new JLabel("Difficulty", JLabel.CENTER); sizeLabel = new JLabel("Grid Size", JLabel.CENTER); sizePanel.setLayout(new BoxLayout(sizePanel, BoxLayout.PAGE_AXIS)); difficultyPanel.setLayout(new BoxLayout(difficultyPanel, BoxLayout.PAGE_AXIS)); newGame = new JButton("New Game"); newGame.addActionListener(new newGameListener()); showMines = new JButton("Show Unexploded Mines"); showMines.addActionListener(new showMinesListener()); showPath = new JButton("Show Path"); showPath.addActionListener(new showPathListener()); gridSize = new JSlider(JSlider.HORIZONTAL, GRIDSIZE_MIN, GRIDSIZE_MAX, GRIDSIZE_START); gridSize.addChangeListener(new sizeListener()); gridSize.setMajorTickSpacing(10); gridSize.setMinorTickSpacing(1); gridSize.setPaintTicks(true); gridSize.setPaintLabels(true); difficultySlider = new JSlider(JSlider.HORIZONTAL, DIFFICULTY_MIN, DIFFICULTY_MAX, DIFFICULTY_START); difficultySlider.addChangeListener(new difficutlyListener()); difficultySlider.setMajorTickSpacing(25); difficultySlider.setMinorTickSpacing(5); difficultySlider.setPaintTicks(true); difficultySlider.setPaintLabels(true); difficultyPanel.add(difficultyLabel); difficultyPanel.add(difficultySlider); sizePanel.add(sizeLabel); sizePanel.add(gridSize); southPanel.add(newGame); southPanel.add(showMines); southPanel.add(showPath); southPanel.add(sizePanel); southPanel.add(difficultyPanel); /* WEST PANEL */ // the main west panel JPanel westPanel = new JPanel(); westPanel.setPreferredSize(new Dimension(250, 80)); westPanel.setLayout(new BoxLayout(westPanel, BoxLayout.PAGE_AXIS)); westPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // Creates labels and adds them to their panel greenText = new JLabel("Zero Nearby Mines"); green = new JPanel(); green.setLayout(new GridBagLayout()); green.setPreferredSize(new Dimension(100, 100)); green.setBackground(GREEN); green.add(greenText); yellowText = new JLabel("One Nearby Mines"); yellow = new JPanel(); yellow.setLayout(new GridBagLayout()); yellow.setPreferredSize(new Dimension(100, 100)); yellow.setBackground(YELLOW); yellow.add(yellowText); orangeText = new JLabel("Two Nearby Mines"); orange = new JPanel(); orange.setLayout(new GridBagLayout()); orange.setPreferredSize(new Dimension(100, 100)); orange.setBackground(ORANGE); orange.add(orangeText); redText = new JLabel("Three Nearby Mines"); red = new JPanel(); red.setLayout(new GridBagLayout()); red.setPreferredSize(new Dimension(100, 100)); red.setBackground(RED); red.add(redText); blackText = new JLabel("Exploded Mines"); blackText.setForeground(Color.WHITE); black = new JPanel(); black.setLayout(new GridBagLayout()); black.setPreferredSize(new Dimension(100, 100)); black.setBackground(Color.BLACK); black.add(blackText); blueText = new JLabel("Path"); blueText.setForeground(Color.WHITE); blue = new JPanel(); blue.setLayout(new GridBagLayout()); blue.setPreferredSize(new Dimension(100, 100)); blue.setBackground(Color.WHITE); blue.add(blueText); grayText = new JLabel("Unexploded Mines"); grayText.setForeground(Color.WHITE); gray = new JPanel(); gray.setLayout(new GridBagLayout()); gray.setPreferredSize(new Dimension(100, 100)); gray.setBackground(Color.WHITE); gray.add(grayText); indigoText = new JLabel("Start"); indigoText.setForeground(Color.WHITE); indigo = new JPanel(); indigo.setLayout(new GridBagLayout()); indigo.setPreferredSize(new Dimension(100, 100)); indigo.setBackground(INDIGO); indigo.add(indigoText); violetText = new JLabel("Finish"); violetText.setForeground(Color.WHITE); violet = new JPanel(); violet.setLayout(new GridBagLayout()); violet.setPreferredSize(new Dimension(100, 100)); violet.setBackground(VIOLET); violet.add(violetText); westPanel.add(black); westPanel.add(gray); westPanel.add(red); westPanel.add(orange); westPanel.add(yellow); westPanel.add(green); westPanel.add(blue); westPanel.add(indigo); westPanel.add(violet); // Create new grid panel at specified dimension buildGridPanel(size); this.setLayout(new BorderLayout()); this.add(board, BorderLayout.CENTER); this.add(southPanel, BorderLayout.SOUTH); this.add(westPanel, BorderLayout.WEST); } public void toggleSliders() { if (frame.isActive()) { gridSize.setEnabled(false); difficultySlider.setEnabled(false); } else { gridSize.setEnabled(true); difficultySlider.setEnabled(true); } } // listeners for each button or slider public class sizeListener implements ChangeListener { public void stateChanged(ChangeEvent e) { size = ((JSlider) e.getSource()).getValue(); if (size > 2) { buildGridPanel(size); showMines.setText("Show Mines"); showPath.setText("Show Path"); } } } public class difficutlyListener implements ChangeListener { public void stateChanged(ChangeEvent e) { difficulty = ((JSlider) e.getSource()).getValue(); if (difficulty > 0) { buildGridPanel(size); showMines.setText("Show Mines"); showPath.setText("Show Path"); revalidate(); } } } private class newGameListener implements ActionListener { @Override public void actionPerformed(ActionEvent ae) { buildGridPanel(size); showMines.setText("Show Mines"); showPath.setText("Show Path"); } } private class showMinesListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { if (showMines.getText().equals("Show Mines")) { showMines.setText("Hide Mines"); board.showMines(); gray.setBackground(Color.GRAY); } else if (showMines.getText().equals("Hide Mines")) { showMines.setText("Show Mines"); board.hideMines(); gray.setBackground(Color.WHITE); } } } private class showPathListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { if (showPath.getText().equals("Show Path")) { showPath.setText("Hide Path"); board.showHidePath(); blue.setBackground(BLUE); } else if (showPath.getText().equals("Hide Path")) { showPath.setText("Show Path"); board.showHidePath(); blue.setBackground(Color.WHITE); } } } public void RandomMines(int size) { rand = new Random(); path = walk.getPath(); mines = new Boolean[size][size]; for (int i = 0; i < mines.length; i++) { for (int j = 0; j < mines[i].length; j++) { mines[i][j] = (rand.nextInt(100) + 1 <= difficulty ? true : false); } } for (Point p : path) { mines[p.x][p.y] = false; } } private void buildGridPanel(int size) { // Instantiate new MineWalkerPanel if (this.board != null) { this.remove(this.board); gray.setBackground(Color.WHITE); blue.setBackground(Color.WHITE); } // Creating path with RandomWalk walk = new RandomWalk(size); walk.createWalk(); RandomMines(size); this.board = new MineWalkerPanel(size, mines, walk, path); this.add(board, BorderLayout.CENTER); this.revalidate(); //GUI update } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { // Auto-generated catch block e.printStackTrace(); } frame = new JFrame("Mine Walker"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new MineWalker(100, 100)); frame.pack(); frame.setVisible(true); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation(dim.width / 2 - frame.getSize().width / 2, dim.height / 2 - frame.getSize().height / 2); } } ?//MineWalkerPanel.java import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.Timer; @SuppressWarnings("serial") public class MineWalkerPanel extends JPanel implements ActionListener { private static final int DELAY = 250; private JButton[][] buttons; public Boolean[][] mines; public RandomWalk walk; public int gridSize; private int lives, score, index; private int previousX = 0, previousY = 0; private Timer animationTimer; private boolean state; ArrayList path; JLabel livesLabel; JLabel scoreLabel; JPanel scorePanel; final Color DEFAULT_COLOR = new JButton().getBackground(); final Color RED = new Color(230, 25, 75); final Color ORANGE = new Color(245, 130, 48); final Color YELLOW = new Color(255, 225, 25); final Color GREEN = new Color(60, 180, 75); final Color BLUE = new Color(0, 130, 200); final Color INDIGO = new Color(145, 30, 180); final Color VIOLET = new Color(100, 105, 255);
Color color; Color[] colors = { color, DEFAULT_COLOR }; public MineWalkerPanel(int gridSize, Boolean[][] mines, RandomWalk walk, ArrayList path) { buttons = new JButton[gridSize][gridSize]; this.path = path; this.mines = mines; this.gridSize = gridSize; this.walk = walk; this.state = false; lives = 5; score = 500; index = 0; previousX = gridSize - 1; previousY = 0; this.animationTimer = new Timer(DELAY, new TimerActionListener()); JPanel main = new JPanel(); main.setPreferredSize(new Dimension(500, 500)); //grid layout main.setBackground(Color.BLACK); main.setLayout(new GridLayout(gridSize, gridSize)); for (int i = 0; i < buttons.length; i++) { for (int j = 0; j < buttons[i].length; j++) { buttons[i][j] = new JButton(); buttons[i][j].setEnabled(false); buttons[i][j].addActionListener(this); buttons[i][j].setPreferredSize(new Dimension(20, 20)); main.add(buttons[i][j]); } } buttons[gridSize - 1][0].setEnabled(true); buttons[gridSize - 1][0].setBackground(INDIGO); buttons[0][gridSize - 1].setBackground(VIOLET); this.add(main); JPanel eastPanel = new JPanel(); eastPanel.setPreferredSize(new Dimension(250, 80)); eastPanel.setLayout(new BoxLayout(eastPanel, BoxLayout.PAGE_AXIS)); JPanel scorePanel = new JPanel(); eastPanel.add(scorePanel); livesLabel = new JLabel("Lives: " + lives); livesLabel.setHorizontalAlignment(JLabel.CENTER); livesLabel.setAlignmentX(livesLabel.CENTER_ALIGNMENT); scoreLabel = new JLabel("Score: " + score); scoreLabel.setHorizontalAlignment(JLabel.CENTER); scoreLabel.setAlignmentX(scoreLabel.CENTER_ALIGNMENT); scorePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLoweredBevelBorder(), BorderFactory.createEmptyBorder(10, 10, 10, 10))); scorePanel.add(livesLabel); scorePanel.add(scoreLabel); this.add(eastPanel, BorderLayout.EAST); } public MineWalkerPanel() { } private void setText(JLabel label, final String text) { if (label != null) { label.setText(text); label.paintImmediately(label.getVisibleRect()); revalidate(); repaint(); } } public void showMines() { for (int i = 0; i < mines.length; i++) { for (int j = 0; j < mines.length; j++) { if (mines[i][j] == true && buttons[i][j].getBackground() != Color.BLACK) { buttons[i][j].setBackground(Color.GRAY); } } } } public void hideMines() { for (int i = 0; i < mines.length; i++) { for (int j = 0; j < mines.length; j++) { if (buttons[i][j].getBackground() == Color.GRAY && mines[i][j] == true) { buttons[i][j].setBackground(DEFAULT_COLOR); } } } } public void disableAll() { for (int i = 0; i < mines.length; i++) { for (int j = 0; j < mines.length; j++) { buttons[i][j].setEnabled(false); } } } public void showHidePath() { for (Point p : path) { if (buttons[p.x][p.y].getBackground() == BLUE) { buttons[p.x][p.y].setBackground(DEFAULT_COLOR); } else if (buttons[p.x][p.y].getBackground() == DEFAULT_COLOR) { buttons[p.x][p.y].setBackground(BLUE); } } } private void animateFlash(int x, int y, Color color) { this.previousX = x; this.previousY = y; this.color = color; buttons[x][y].setBackground(colors[index]); index = (index + 1) % colors.length; } /** * Performs action when timer event fires. */ private class TimerActionListener implements ActionListener { public void actionPerformed(ActionEvent evt) { animateFlash(previousX, previousY, color); revalidate(); repaint(); } } /* Public Methods */ /** * Check whether the button is currently animating * * @return true if animation is active, false if not */ public boolean isActive() { return this.animationTimer.isRunning(); } /** * Create an animation thread that runs periodically */ private void startAnimation() { if (state == true && !this.animationTimer.isRunning()) { this.animationTimer.start(); //toggleSliders(); } else if (state == false) { this.animationTimer.stop(); //toggleSliders(); } } public void actionPerformed(ActionEvent ae) { for (int i = 0; i < buttons.length; i++) { for (int j = 0; j < buttons.length; j++) { // button buttons[i][j] was clicked if (ae.getSource() == buttons[i][j] && buttons[i][j].getBackground() != Color.BLACK) { buttons[previousX][previousY].setBackground(colors[0]); index = 0; state = true; int up = 0, down = 0, left = 0, right = 0; startAnimation(); disableAll(); if (i - 1 >= 0) { buttons[i - 1][j].setEnabled(true); up = (mines[i - 1][j]) ? 1 : 0; } if (i + 1 <= buttons.length - 1) { buttons[i + 1][j].setEnabled(true); down = (mines[i + 1][j]) ? 1 : 0; } if (j - 1 >= 0) { buttons[i][j - 1].setEnabled(true); left = (mines[i][j - 1]) ? 1 : 0; } if (j + 1 <= buttons.length - 1) { buttons[i][j + 1].setEnabled(true); right = (mines[i][j + 1]) ? 1 : 0; } int sum = up + down + left + right; if (mines[i][j] == true) { buttons[i][j].setBackground(Color.BLACK); // Mine buttons[previousX][previousY].doClick(); buttons[i][j].setEnabled(true); score -= 100; lives -= 1; } else if (sum >= 3) { buttons[i][j].setBackground(RED); score -= 1; } else if (sum == 2) { buttons[i][j].setBackground(ORANGE); score -= 1; } else if (sum == 1) { buttons[i][j].setBackground(YELLOW); score -= 1; } else { buttons[i][j].setBackground(GREEN); score -= 1; } if (buttons[i][j].getBackground() != Color.BLACK) { // button you're trying to click isn't black colors[0] = buttons[i][j].getBackground(); previousX = i; previousY = j; } setText(livesLabel, "Lives: " + lives); setText(scoreLabel, "Score: " + score); if (lives == 0 || score <= 0) { this.animationTimer.stop(); disableAll(); showMines(); Component frame = null; JOptionPane.showMessageDialog(frame, "You Lose! Your final score is " + score + "."); } if (i == 0 && j == gridSize - 1) { this.animationTimer.stop(); disableAll(); showMines(); Component frame = null; if (lives > 1) { JOptionPane.showMessageDialog(frame, "You made it! You had " + lives + " lives remaing and your final score is " + score + "."); } else { JOptionPane.showMessageDialog(frame, "You made it! You only had one life remaining and your final score is " + score + "."); } } } } } } }
//MineFieldButton.java
import java.awt.Button; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; import java.util.ArrayList; import javax.swing.JButton; public class MineFieldButton extends JButton { }
//MineFieldPanel.java
import java.awt.GridLayout; import java.awt.Point; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.JPanel;
public class MineFieldPanel extends JPanel{ }
//RandomWalk.java
import java.awt.Point; import java.util.ArrayList; import java.util.Random; public class RandomWalk { /** * Instance Data */ private int size; private boolean done; private long seed; private Random rand; private Point end = new Point(getGridSize() - 1, 0), start = new Point(0, getGridSize() - 1), current; ArrayList path;
/** * Constructor * * * @param gridSize */ public RandomWalk(int gridSize) { size = gridSize; rand = new Random(); done = false; path = new ArrayList(); start = new Point(0, gridSize - 1); path.add(start); } /** * Method Overloading Constructor * * @param gridSize * @param seed */ public RandomWalk(int gridSize, long seed) { size = gridSize; rand = new Random(seed); done = false; path = new ArrayList(); start = new Point(0, gridSize - 1); path.add(start); } /** * Moves one more step using methods from point class based on parameters */ int xStep = 1; int yStep = 1; int stepCount = 0;
public void step() { if (xStep == size && yStep == size) { done = true; } else { if (rand.nextBoolean() == false && xStep < size) { Point p1 = new Point(start.x + xStep, path.get(stepCount).y); path.add(p1); stepCount++; xStep++; } else if (yStep < size) { Point p1 = new Point(path.get(stepCount).x, start.y - yStep); path.add(p1); stepCount++; yStep++; } } } /** * Generates full walk */ public void createWalk() { while (done == false) { step(); } } /** * Returns completion status * * @return */ public boolean isDone() { return done; }
/** * sets completion status */ public void setDone(boolean b) { this.done = done; }
/** * Returns grid size */ public int getGridSize() { return size; } /** * Returns start point */ public Point getStartPoint() { return start; } /** * Returns end Point */ public Point getEndPoint() { return end; } /** * returns current point */ public Point getCurrentPoint() { return current; }
/** * Reference to the random walk path. * * @return */
public ArrayList getPath() { return path; }
/** * Returns path as string */
public String toString() { String pathOfTravel = ""; for (Point point : path) { pathOfTravel = pathOfTravel + "[" + (int) point.getX() + "," + (int) point.getY() + "]"; } return pathOfTravel; } }
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
