├── resources ├── bomb.png ├── five.png ├── flag.png ├── four.png ├── one.png ├── six.png ├── two.png ├── eight.png ├── empty.png ├── seven.png ├── three.png ├── unclicked.png └── questionMark.png ├── src ├── Main.java ├── Square.java ├── UI.java └── Board.java ├── .classpath ├── .project └── .settings └── org.eclipse.jdt.core.prefs /resources/bomb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/bomb.png -------------------------------------------------------------------------------- /resources/five.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/five.png -------------------------------------------------------------------------------- /resources/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/flag.png -------------------------------------------------------------------------------- /resources/four.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/four.png -------------------------------------------------------------------------------- /resources/one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/one.png -------------------------------------------------------------------------------- /resources/six.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/six.png -------------------------------------------------------------------------------- /resources/two.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/two.png -------------------------------------------------------------------------------- /resources/eight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/eight.png -------------------------------------------------------------------------------- /resources/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/empty.png -------------------------------------------------------------------------------- /resources/seven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/seven.png -------------------------------------------------------------------------------- /resources/three.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/three.png -------------------------------------------------------------------------------- /resources/unclicked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/unclicked.png -------------------------------------------------------------------------------- /resources/questionMark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contribution/Minesweeper/master/resources/questionMark.png -------------------------------------------------------------------------------- /src/Main.java: -------------------------------------------------------------------------------- 1 | 2 | public class Main { 3 | 4 | public static void main(String[] args) { 5 | new UI(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Minesweeper 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /src/Square.java: -------------------------------------------------------------------------------- 1 | import java.net.URL; 2 | 3 | import javax.swing.ImageIcon; 4 | import javax.swing.JButton; 5 | 6 | public class Square { 7 | private int number; 8 | private JButton button; 9 | private URL imagePath; 10 | private static final int BOMB = 9; 11 | 12 | Square() { 13 | number = 0; 14 | imagePath = imageURL("/unclicked.png"); 15 | } 16 | 17 | public int getNumber() { 18 | return number; 19 | } 20 | 21 | public void setNumber(int number) { 22 | this.number = number; 23 | } 24 | 25 | public URL getImagePath() { 26 | return imagePath; 27 | } 28 | 29 | public void setImage(URL url) { 30 | this.imagePath = url; 31 | ImageIcon ic = new ImageIcon(url); 32 | this.getButton().setIcon(ic); 33 | } 34 | 35 | public void revealImage() { 36 | switch (this.getNumber()) { 37 | case 0: 38 | this.setImage(imageURL("/empty.png")); 39 | break; 40 | case 1: 41 | this.setImage(imageURL("/one.png")); 42 | break; 43 | case 2: 44 | this.setImage(imageURL("/two.png")); 45 | break; 46 | case 3: 47 | this.setImage(imageURL("/three.png")); 48 | break; 49 | case 4: 50 | this.setImage(imageURL("/four.png")); 51 | break; 52 | case 5: 53 | this.setImage(imageURL("/five.png")); 54 | break; 55 | case 6: 56 | this.setImage(imageURL("/six.png")); 57 | break; 58 | case 7: 59 | this.setImage(imageURL("/seven.png")); 60 | break; 61 | case 8: 62 | this.setImage(imageURL("/eight.png")); 63 | break; 64 | case BOMB: 65 | this.setImage(imageURL("/bomb.png")); 66 | } 67 | } 68 | 69 | public JButton getButton() { 70 | return button; 71 | } 72 | 73 | public void setButton(JButton button) { 74 | this.button = button; 75 | this.button.setBorder(null); 76 | } 77 | 78 | private URL imageURL(String image) { 79 | return getClass().getResource(image); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/UI.java: -------------------------------------------------------------------------------- 1 | import java.awt.Dimension; 2 | import java.awt.GridBagConstraints; 3 | import java.awt.GridBagLayout; 4 | import java.awt.event.ActionEvent; 5 | import java.awt.event.ActionListener; 6 | 7 | import javax.swing.BoxLayout; 8 | import javax.swing.JButton; 9 | import javax.swing.JFrame; 10 | import javax.swing.JLabel; 11 | import javax.swing.JPanel; 12 | import javax.swing.JSpinner; 13 | import javax.swing.SpinnerNumberModel; 14 | import javax.swing.event.ChangeEvent; 15 | import javax.swing.event.ChangeListener; 16 | 17 | public class UI { 18 | 19 | private JFrame boardGUI = new JFrame(); 20 | private JLabel time; 21 | private JFrame currentGameWindow; 22 | final JSpinner heightSpinner = new JSpinner(); 23 | final JSpinner widthSpinner = new JSpinner(); 24 | 25 | UI() { 26 | createMainMenuUI(); 27 | } 28 | 29 | UI(JLabel time, JFrame currentGameWindow) { 30 | this.time = time; 31 | this.currentGameWindow = currentGameWindow; 32 | } 33 | 34 | public void createMainMenuUI() { 35 | JFrame gui = new JFrame(); 36 | gui.setLocationRelativeTo(null); 37 | JPanel menuPanel = new JPanel(); 38 | JButton beginnerButton = new JButton("Beginner"); 39 | addNewMenuComponentListener(beginnerButton, "beginner", gui); 40 | JButton intermediateButton = new JButton("Intermediate"); 41 | addNewMenuComponentListener(intermediateButton, "intermediate", gui); 42 | JButton advancedButton = new JButton("Advanced"); 43 | addNewMenuComponentListener(advancedButton, "advanced", gui); 44 | JButton customButton = new JButton("Custom"); 45 | addNewMenuComponentListener(customButton, "custom", gui); 46 | menuPanel.add(beginnerButton); 47 | menuPanel.add(intermediateButton); 48 | menuPanel.add(advancedButton); 49 | menuPanel.add(customButton); 50 | menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.Y_AXIS)); 51 | gui.setLayout(new GridBagLayout()); 52 | gui.add(menuPanel); 53 | gui.setMinimumSize(new Dimension(250, 200)); 54 | gui.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 55 | gui.setTitle("Difficulty"); 56 | gui.pack(); 57 | gui.setVisible(true); 58 | } 59 | 60 | private void addNewMenuComponentListener(JButton button, String actionName, 61 | final JFrame frame) { 62 | button.addActionListener(new ActionListener() { 63 | public void actionPerformed(ActionEvent e) { 64 | frame.dispose(); 65 | menuClickHandling(e); 66 | } 67 | }); 68 | button.setActionCommand(actionName); 69 | } 70 | 71 | private void menuClickHandling(ActionEvent e) { 72 | switch (e.getActionCommand()) { 73 | case "beginner": 74 | createBoardUI(initMinesweeper(9, 9, 10)); 75 | break; 76 | case "intermediate": 77 | createBoardUI(initMinesweeper(16, 16, 40)); 78 | break; 79 | case "advanced": 80 | createBoardUI(initMinesweeper(30, 16, 99)); 81 | break; 82 | case "custom": 83 | createCustomBoardMenuUI(); 84 | break; 85 | } 86 | } 87 | 88 | private Board initMinesweeper(int row, int column, int bombCount) { 89 | Board minesweeper = new Board(row, column, bombCount, boardGUI); 90 | minesweeper.setBombLocations(); 91 | minesweeper.surroundBombLocations(); 92 | System.out.println(minesweeper.printArray()); 93 | return minesweeper; 94 | } 95 | 96 | private void createBoardUI(Board minesweeper) { 97 | boardGUI.setLayout(new GridBagLayout()); 98 | boardGUI.setLocationRelativeTo(null); 99 | boardGUI.setTitle("Minesweeper"); 100 | boardGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 101 | GridBagConstraints c = new GridBagConstraints(); 102 | JPanel mineLabelPanel = new JPanel(); 103 | c.gridx = 0; 104 | c.gridy = 0; 105 | c.anchor = GridBagConstraints.WEST; 106 | boardGUI.add(mineLabelPanel, c); 107 | JLabel mineLabel = minesweeper.getMineLabel(); 108 | c.gridx = 0; 109 | c.gridy = 0; 110 | mineLabelPanel.add(mineLabel, c); 111 | JPanel timeLabelPanel = new JPanel(); 112 | c.gridx = 0; 113 | c.gridy = 0; 114 | c.anchor = GridBagConstraints.EAST; 115 | boardGUI.add(timeLabelPanel, c); 116 | JLabel timeLabel = minesweeper.getTimerLabel(); 117 | c.gridx = 0; 118 | c.gridy = 0; 119 | timeLabel.setText("0"); 120 | timeLabelPanel.add(timeLabel, c); 121 | JPanel cellPanel = new JPanel(); 122 | c.gridx = 0; 123 | c.gridy = 1; 124 | cellPanel.setBorder(null); 125 | cellPanel.add(minesweeper.generateImageButtons()); 126 | boardGUI.add(cellPanel, c); 127 | boardGUI.pack(); 128 | Dimension size = boardGUI.getBounds().getSize(); 129 | boardGUI.setMinimumSize(size); 130 | boardGUI.setVisible(true); 131 | } 132 | 133 | public void winLossUI(String state) { 134 | JFrame winLossFrame = new JFrame(); 135 | winLossFrame.setLocationRelativeTo(null); 136 | winLossFrame.setLayout(new GridBagLayout()); 137 | winLossFrame.setMinimumSize(new Dimension(240, 65)); 138 | GridBagConstraints c = new GridBagConstraints(); 139 | winLossFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 140 | JPanel timePanel = new JPanel(); 141 | JPanel winLossPanel = new JPanel(); 142 | JButton play = new JButton("Play Again"); 143 | addWinLossListener(play, "play", winLossFrame); 144 | JButton exit = new JButton("Exit"); 145 | addWinLossListener(exit, "exit", winLossFrame); 146 | // so the time doesn't disappear from the main UI 147 | JLabel timePlayed = new JLabel("Time: " + time.getText() + " seconds"); 148 | if (state.equals("win")) { 149 | winLossFrame.setTitle("You Win!"); 150 | } else if (state.equals("loss")) { 151 | winLossFrame.setTitle("You Lose!"); 152 | } 153 | timePanel.add(timePlayed); 154 | winLossPanel.add(exit); 155 | winLossPanel.add(play); 156 | c.gridx = 0; 157 | c.gridy = 0; 158 | c.anchor = GridBagConstraints.WEST; 159 | winLossFrame.add(timePanel, c); 160 | c.gridx = 0; 161 | c.gridy = 1; 162 | winLossFrame.add(winLossPanel, c); 163 | winLossFrame.pack(); 164 | winLossFrame.setVisible(true); 165 | } 166 | 167 | private void addWinLossListener(JButton button, String actionName, 168 | final JFrame frame) { 169 | button.addActionListener(new ActionListener() { 170 | public void actionPerformed(ActionEvent e) { 171 | frame.dispose(); 172 | winLossListenerClick(e); 173 | } 174 | }); 175 | button.setActionCommand(actionName); 176 | } 177 | 178 | private void winLossListenerClick(ActionEvent e) { 179 | if (e.getActionCommand().equals("play")) { 180 | currentGameWindow.dispose(); 181 | createMainMenuUI(); 182 | } else if (e.getActionCommand().equals("exit")) { 183 | currentGameWindow.dispose(); 184 | } 185 | } 186 | 187 | private void createCustomBoardMenuUI() { 188 | final JFrame customMenuFrame = new JFrame(); 189 | customMenuFrame.setLocationRelativeTo(null); 190 | customMenuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 191 | customMenuFrame.setMinimumSize(new Dimension(240, 150)); 192 | customMenuFrame.setLayout(new GridBagLayout()); 193 | customMenuFrame.setTitle("Custom"); 194 | GridBagConstraints c = new GridBagConstraints(); 195 | JLabel heightLabel = new JLabel("Height (9 - 24): "); 196 | c.gridx = 0; 197 | c.gridy = 0; 198 | customMenuFrame.add(heightLabel, c); 199 | JLabel widthLabel = new JLabel("Width (9 - 30): "); 200 | c.gridx = 0; 201 | c.gridy = 1; 202 | customMenuFrame.add(widthLabel, c); 203 | JLabel bombsLabel = new JLabel("Bombs (10 - 667): "); 204 | c.gridx = 0; 205 | c.gridy = 2; 206 | customMenuFrame.add(bombsLabel, c); 207 | SpinnerNumberModel height = new SpinnerNumberModel(9, 9, 24, 1); 208 | heightSpinner.setModel(height); 209 | c.gridx = 1; 210 | c.gridy = 0; 211 | customMenuFrame.add(heightSpinner, c); 212 | SpinnerNumberModel width = new SpinnerNumberModel(9, 9, 30, 1); 213 | widthSpinner.setModel(width); 214 | c.gridx = 1; 215 | c.gridy = 1; 216 | customMenuFrame.add(widthSpinner, c); 217 | SpinnerNumberModel bombs = new SpinnerNumberModel(10, 10, 218 | getMaxBombsAllowed((int) heightSpinner.getValue(), 219 | (int) widthSpinner.getValue()), 1); 220 | final JSpinner bombSpinner = new JSpinner(bombs); 221 | bombSpinner.setToolTipText("Max bombs = (height - 1) * (width - 1)"); 222 | c.gridx = 1; 223 | c.gridy = 2; 224 | customMenuFrame.add(bombSpinner, c); 225 | JButton playButton = new JButton("Play"); 226 | playButton.addActionListener(new ActionListener() { 227 | public void actionPerformed(ActionEvent e) { 228 | customMenuFrame.dispose(); 229 | int height = (int) heightSpinner.getValue(); 230 | int width = (int) widthSpinner.getValue(); 231 | int bombCount = (int) bombSpinner.getValue(); 232 | createBoardUI(initMinesweeper(height, width, bombCount)); 233 | } 234 | }); 235 | c.gridx = 1; 236 | c.gridy = 3; 237 | 238 | spinnerListener(height, bombs); 239 | spinnerListener(width, bombs); 240 | customMenuFrame.add(playButton, c); 241 | customMenuFrame.pack(); 242 | customMenuFrame.setVisible(true); 243 | } 244 | 245 | private void spinnerListener(SpinnerNumberModel spinner, 246 | final SpinnerNumberModel bombs) { 247 | spinner.addChangeListener(new ChangeListener() { 248 | 249 | @Override 250 | public void stateChanged(ChangeEvent e) { 251 | int heightValue = (int) heightSpinner.getValue(); 252 | int widthValue = (int) widthSpinner.getValue(); 253 | int bombsValue = (int) bombs.getValue(); 254 | bombs.setMaximum(getMaxBombsAllowed(heightValue, widthValue)); 255 | if (bombsValue > getMaxBombsAllowed(heightValue,widthValue)) { 256 | bombs.setValue(getMaxBombsAllowed(heightValue,widthValue)); 257 | } 258 | } 259 | }); 260 | } 261 | 262 | private int getMaxBombsAllowed(int a, int b) { 263 | return ((a - 1) * (b - 1)); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /src/Board.java: -------------------------------------------------------------------------------- 1 | import java.awt.GridBagConstraints; 2 | import java.awt.GridBagLayout; 3 | import java.awt.event.MouseAdapter; 4 | import java.awt.event.MouseEvent; 5 | import java.net.URL; 6 | import java.util.Timer; 7 | import java.util.TimerTask; 8 | 9 | import javax.swing.ImageIcon; 10 | import javax.swing.JButton; 11 | import javax.swing.JFrame; 12 | import javax.swing.JLabel; 13 | import javax.swing.JPanel; 14 | import javax.swing.SwingUtilities; 15 | 16 | public class Board { 17 | 18 | private int column; 19 | private int row; 20 | private int bombCount; 21 | private int flagCount; 22 | private boolean timerStarted; 23 | private JLabel mineLabel; 24 | private JLabel timerLabel; 25 | private Timer timer; 26 | private Square[][] cells; 27 | private static final int BOMB = 9; 28 | private static final int EMPTY = 0; 29 | private JFrame boardUI; 30 | 31 | Board(int column, int row, int bombCount, JFrame boardUI) { 32 | this.row = row; 33 | this.column = column; 34 | this.bombCount = bombCount; 35 | this.boardUI = boardUI; 36 | mineLabel = new JLabel(); 37 | mineLabel.setText("" + bombCount); 38 | timerLabel = new JLabel(); 39 | flagCount = bombCount; 40 | timerStarted = false; 41 | cells = new Square[row][column]; 42 | for (int i = 0; i < cells.length; i++) { 43 | for (int j = 0; j < cells[i].length; j++) { 44 | cells[i][j] = new Square(); 45 | } 46 | } 47 | } 48 | 49 | public JLabel getTimerLabel() { 50 | return this.timerLabel; 51 | } 52 | 53 | public JLabel getMineLabel() { 54 | return this.mineLabel; 55 | } 56 | 57 | public void setBombLocations() { 58 | int bombsToBeSet = bombCount; 59 | while (bombsToBeSet > 0) { 60 | int randomRow = (int) (Math.random() * cells.length); 61 | int randomColumn = (int) (Math.random() * cells[0].length); 62 | if (cells[randomRow][randomColumn].getNumber() != BOMB) { 63 | cells[randomRow][randomColumn].setNumber(BOMB); 64 | bombsToBeSet--; 65 | } 66 | } 67 | } 68 | 69 | public void surroundBombLocations() { 70 | 71 | for (int i = 0; i < cells.length; i++) { 72 | for (int j = 0; j < cells[i].length; j++) { 73 | if (cells[i][j].getNumber() == BOMB) { 74 | bombBoundsChecking(i, j); 75 | } 76 | } 77 | } 78 | } 79 | 80 | private void bombBoundsChecking(int i, int j) { 81 | // up one over left 82 | if (i != 0 && j != 0) { 83 | bombCheck(i - 1, j - 1); 84 | } 85 | // up one 86 | if (i != 0) { 87 | bombCheck(i - 1, j); 88 | } 89 | // up one over right 90 | if (i != 0 && j != column - 1) { 91 | bombCheck(i - 1, j + 1); 92 | } 93 | // over left 94 | if (j != 0) { 95 | bombCheck(i, j - 1); 96 | } 97 | // over right 98 | if (j != column - 1) { 99 | bombCheck(i, j + 1); 100 | } 101 | // down one over left 102 | if (i != row - 1 && j != 0) { 103 | bombCheck(i + 1, j - 1); 104 | } 105 | // down one 106 | if (i != row - 1) { 107 | bombCheck(i + 1, j); 108 | } 109 | // down one over right 110 | if (i != row - 1 && j != column - 1) { 111 | bombCheck(i + 1, j + 1); 112 | } 113 | } 114 | 115 | // ensures tiles surrounding bombs are not bombs (so bombs don't get 116 | // incremented) 117 | private void bombCheck(int i, int j) { 118 | if (cells[i][j].getNumber() != BOMB) { 119 | cells[i][j].setNumber(cells[i][j].getNumber() + 1); 120 | } 121 | } 122 | 123 | public JPanel generateImageButtons() { 124 | JPanel gridLayout = new JPanel(new GridBagLayout()); 125 | GridBagConstraints c = new GridBagConstraints(); 126 | for (int i = 0; i < cells.length; i++) { 127 | for (int j = 0; j < cells[i].length; j++) { 128 | cells[i][j].setButton(new JButton()); 129 | cells[i][j].getButton().addMouseListener(new MouseAdapter() { 130 | public void mouseReleased(MouseEvent e) { 131 | mouseClickHandling(e); 132 | } 133 | }); 134 | cells[i][j].getButton().setActionCommand(i + "-" + j); 135 | ImageIcon ic = new ImageIcon(cells[i][j].getImagePath()); 136 | cells[i][j].getButton().setIcon(ic); 137 | c.gridx = j; 138 | c.gridy = i; 139 | gridLayout.add(cells[i][j].getButton(), c); 140 | } 141 | } 142 | return gridLayout; 143 | } 144 | 145 | public StringBuilder printArray() { 146 | StringBuilder sb = new StringBuilder(); 147 | for (int i = 0; i < cells.length; i++) { 148 | for (int j = 0; j < cells[i].length; j++) { 149 | sb.append(cells[i][j].getNumber() + " "); 150 | } 151 | sb.append("\n"); 152 | } 153 | return sb; 154 | } 155 | 156 | private void mouseClickHandling(MouseEvent e) { 157 | JButton source = (JButton) e.getSource(); 158 | if (!timerStarted) { 159 | startTimer(); 160 | } 161 | int row = Integer.parseInt(source.getActionCommand().substring(0, 162 | source.getActionCommand().indexOf("-"))); 163 | int column = Integer.parseInt(source.getActionCommand().substring( 164 | source.getActionCommand().indexOf("-") + 1, 165 | source.getActionCommand().length())); 166 | if (cells[row][column].getButton().isEnabled() 167 | && SwingUtilities.isLeftMouseButton(e) 168 | && !cells[row][column].getImagePath().equals(imageURL("/flag.png"))) { 169 | if (cells[row][column].getNumber() == EMPTY) { 170 | revealBlanks(row, column); 171 | // handles non-empty reveals for empty spaces that only span one 172 | // cell 173 | setNextCell(row, column); 174 | } 175 | cells[row][column].revealImage(); 176 | disable(row, column); 177 | if (getRevealsUntilWin() == bombCount) { 178 | gameWon(); 179 | } 180 | if (cells[row][column].getNumber() == BOMB) { 181 | gameOver(); 182 | } 183 | } else if (SwingUtilities.isRightMouseButton(e) 184 | && cells[row][column].getButton().isEnabled()) { 185 | // flag handling 186 | if (cells[row][column].getImagePath().equals( 187 | imageURL("/unclicked.png"))) { 188 | cells[row][column].setImage(imageURL("/flag.png")); 189 | flagCount--; 190 | } else if (cells[row][column].getImagePath().equals( 191 | imageURL("/flag.png"))) { 192 | cells[row][column].setImage(imageURL("/questionMark.png")); 193 | flagCount++; 194 | } else if (cells[row][column].getImagePath().equals( 195 | imageURL("/questionMark.png"))) { 196 | cells[row][column].setImage(imageURL("/unclicked.png")); 197 | } 198 | mineLabel.setText("" + flagCount); 199 | } 200 | 201 | } 202 | 203 | // reveals blank spots when necessary 204 | private void revealBlanks(int i, int j) { 205 | if ((i != 0 && cells[i - 1][j].getNumber() != 0) 206 | && (j != 0 && cells[i][j - 1].getNumber() != 0) 207 | && (j != column - 1 && cells[i][j + 1].getNumber() != 0) 208 | && (i != row - 1 && cells[i + 1][j].getNumber() != 0)) { 209 | return; 210 | } else { 211 | if (i != 0 && cells[i - 1][j].getNumber() == EMPTY) { 212 | if (!cells[i - 1][j].getImagePath().equals( 213 | imageURL("/flag.png"))) { 214 | setNextCell(i - 1, j); 215 | disable(i - 1, j); 216 | } 217 | revealBlanks(i - 1, j); 218 | } 219 | if (j != 0 && cells[i][j - 1].getNumber() == EMPTY) { 220 | if (!cells[i][j - 1].getImagePath().equals( 221 | imageURL("/flag.png"))) { 222 | setNextCell(i, j - 1); 223 | disable(i, j - 1); 224 | } 225 | revealBlanks(i, j - 1); 226 | } 227 | if (j != column - 1 && cells[i][j + 1].getNumber() == EMPTY) { 228 | if (!cells[i][j + 1].getImagePath().equals( 229 | imageURL("/flag.png"))) { 230 | setNextCell(i, j + 1); 231 | disable(i, j + 1); 232 | } 233 | revealBlanks(i, j + 1); 234 | 235 | } 236 | if (i != row - 1 && cells[i + 1][j].getNumber() == EMPTY) { 237 | if (!cells[i + 1][j].getImagePath().equals( 238 | imageURL("/flag.png"))) { 239 | setNextCell(i + 1, j); 240 | disable(i + 1, j); 241 | } 242 | revealBlanks(i + 1, j); 243 | } 244 | } 245 | } 246 | 247 | // sets attributes to cells handled in the revealBlanks function 248 | private void setNextCell(int i, int j) { 249 | // ensures no infinite recursion 250 | cells[i][j].setNumber(-1); 251 | cells[i][j].setImage(imageURL("/empty.png")); 252 | // reveals the closest block that isn't empty at the end of the revealed 253 | // blank spots 254 | if (i != 0 255 | && j != 0 256 | && cells[i - 1][j - 1].getNumber() != EMPTY 257 | && !cells[i - 1][j - 1].getImagePath().equals( 258 | imageURL("/flag.png"))) { 259 | cells[i - 1][j - 1].revealImage(); 260 | disable(i - 1, j - 1); 261 | } 262 | if (i != 0 263 | && cells[i - 1][j].getNumber() != EMPTY 264 | && !cells[i - 1][j].getImagePath() 265 | .equals(imageURL("/flag.png"))) { 266 | cells[i - 1][j].revealImage(); 267 | disable(i - 1, j); 268 | } 269 | if (i != 0 270 | && j != column - 1 271 | && cells[i - 1][j + 1].getNumber() != EMPTY 272 | && !cells[i - 1][j + 1].getImagePath().equals( 273 | imageURL("/flag.png"))) { 274 | cells[i - 1][j + 1].revealImage(); 275 | disable(i - 1, j + 1); 276 | } 277 | if (j != 0 && cells[i][j - 1].getNumber() != EMPTY 278 | && !cells[i][j - 1].getImagePath().equals(("/flag.png"))) { 279 | cells[i][j - 1].revealImage(); 280 | disable(i, j - 1); 281 | } 282 | if (j != column - 1 283 | && cells[i][j + 1].getNumber() != EMPTY 284 | && !cells[i][j + 1].getImagePath() 285 | .equals(imageURL("/flag.png"))) { 286 | cells[i][j + 1].revealImage(); 287 | disable(i, j + 1); 288 | } 289 | if (i != row - 1 290 | && j != 0 291 | && cells[i + 1][j - 1].getNumber() != EMPTY 292 | && !cells[i + 1][j - 1].getImagePath().equals( 293 | imageURL("/flag.png"))) { 294 | cells[i + 1][j - 1].revealImage(); 295 | disable(i + 1, j - 1); 296 | } 297 | if (i != row - 1 298 | && cells[i + 1][j].getNumber() != EMPTY 299 | && !cells[i + 1][j].getImagePath() 300 | .equals(imageURL("/flag.png"))) { 301 | cells[i + 1][j].revealImage(); 302 | disable(i + 1, j); 303 | } 304 | if (i != row - 1 305 | && j != column - 1 306 | && cells[i + 1][j + 1].getNumber() != EMPTY 307 | && !cells[i + 1][j + 1].getImagePath().equals( 308 | imageURL("/flag.png"))) { 309 | cells[i + 1][j + 1].revealImage(); 310 | disable(i + 1, j + 1); 311 | } 312 | } 313 | 314 | // stops cells from being able to be clicked and processed multiple times 315 | private void disable(int i, int j) { 316 | ImageIcon ic = new ImageIcon(cells[i][j].getImagePath()); 317 | cells[i][j].getButton().setDisabledIcon(ic); 318 | cells[i][j].getButton().setEnabled(false); 319 | } 320 | 321 | private void startTimer() { 322 | timerStarted = true; 323 | timer = new Timer(); 324 | timer.scheduleAtFixedRate(new Task(), 1, 1000); 325 | } 326 | 327 | class Task extends TimerTask { 328 | 329 | public void run() { 330 | int i = Integer.parseInt(timerLabel.getText()); 331 | i++; 332 | timerLabel.setText("" + i); 333 | } 334 | 335 | } 336 | 337 | // for determining when a player wins 338 | private int getRevealsUntilWin() { 339 | int totalCells = column * row; 340 | for (int i = 0; i < cells.length; i++) { 341 | for (int j = 0; j < cells[i].length; j++) { 342 | if (!(cells[i][j].getButton().isEnabled()) 343 | && cells[i][j].getNumber() != BOMB) { 344 | totalCells--; 345 | } 346 | } 347 | } 348 | return totalCells; 349 | } 350 | 351 | private void gameWon() { 352 | UI ui = new UI(timerLabel, boardUI); 353 | ui.winLossUI("win"); 354 | timer.cancel(); 355 | for (int i = 0; i < cells.length; i++) { 356 | for (int j = 0; j < cells[i].length; j++) { 357 | if (cells[i][j].getNumber() == BOMB) { 358 | cells[i][j].setImage(imageURL("/flag.png")); 359 | } 360 | disable(i, j); 361 | } 362 | } 363 | } 364 | 365 | private void gameOver() { 366 | UI ui = new UI(timerLabel, boardUI); 367 | ui.winLossUI("loss"); 368 | timer.cancel(); 369 | ImageIcon ic; 370 | for (int i = 0; i < cells.length; i++) { 371 | for (int j = 0; j < cells[i].length; j++) { 372 | ic = new ImageIcon(cells[i][j].getImagePath()); 373 | // reveals all bombs 374 | if (cells[i][j].getNumber() == BOMB) { 375 | ic = new ImageIcon(imageURL("/bomb.png")); 376 | cells[i][j].getButton().setIcon(ic); 377 | } 378 | cells[i][j].getButton().setDisabledIcon(ic); 379 | cells[i][j].getButton().setEnabled(false); 380 | } 381 | } 382 | } 383 | 384 | private URL imageURL(String image) { 385 | return getClass().getResource(image); 386 | } 387 | } --------------------------------------------------------------------------------