├── 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 | }
--------------------------------------------------------------------------------