Added events for changes of the game state and flagged tiles
This commit is contained in:
parent
0b927c5c9f
commit
5535a59a73
@ -8,7 +8,9 @@ import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@ -31,8 +33,9 @@ public class Board extends JPanel {
|
||||
private GameState gameState;
|
||||
private int mines, activeTiles, flaggedTiles;
|
||||
private Tile[][] board;
|
||||
private BoardConfig initialConfig;
|
||||
|
||||
private BoardConfig initialConfig;
|
||||
private List<GameListener> listeners;
|
||||
|
||||
static {
|
||||
icons = new HashMap<>();
|
||||
@ -45,6 +48,7 @@ public class Board extends JPanel {
|
||||
public Board() {
|
||||
// Not using a layout manager
|
||||
super(null);
|
||||
listeners = new ArrayList<>();
|
||||
addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
@ -84,6 +88,7 @@ public class Board extends JPanel {
|
||||
for (int j = 0; j < boardHeight; j++)
|
||||
board[i][j] = new Tile();
|
||||
initMines();
|
||||
notifyFlaggedTilesEvent(new FlaggedTilesEvent(this, flaggedTiles));
|
||||
repaint();
|
||||
}
|
||||
|
||||
@ -91,6 +96,18 @@ public class Board extends JPanel {
|
||||
init(initialConfig);
|
||||
}
|
||||
|
||||
public void registerGameListener(GameListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
private void notifyGameStateEvent(GameStateEvent evt) {
|
||||
listeners.forEach(listener -> listener.onGameStateEvent(evt));
|
||||
}
|
||||
|
||||
private void notifyFlaggedTilesEvent(FlaggedTilesEvent evt) {
|
||||
listeners.forEach(listener -> listener.onFlaggedTilesEvent(evt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
@ -172,11 +189,21 @@ public class Board extends JPanel {
|
||||
if (tile.isFlagged()) {
|
||||
tile.setFlagged(false);
|
||||
flaggedTiles--;
|
||||
notifyFlaggedTilesEvent(new FlaggedTilesEvent(this, flaggedTiles));
|
||||
}
|
||||
|
||||
// Test if the game is won or lost
|
||||
if (tile.isMine()) gameState = GameState.LOST;
|
||||
else if (mines == activeTiles) gameState = GameState.WON;
|
||||
if (tile.isMine()) {
|
||||
gameState = GameState.LOST;
|
||||
repaint();
|
||||
GameStateEvent evt = new GameStateEvent(this, gameState);
|
||||
notifyGameStateEvent(evt);
|
||||
} else if (mines == activeTiles) {
|
||||
gameState = GameState.WON;
|
||||
repaint();
|
||||
GameStateEvent evt = new GameStateEvent(this, gameState);
|
||||
notifyGameStateEvent(evt);
|
||||
}
|
||||
|
||||
// Touch surrounding tiles when there are zero surrounding mines
|
||||
else if (tile.getSurroundingMines() == 0)
|
||||
@ -198,6 +225,7 @@ public class Board extends JPanel {
|
||||
tile.setFlagged(true);
|
||||
flaggedTiles++;
|
||||
}
|
||||
notifyFlaggedTilesEvent(new FlaggedTilesEvent(this, flaggedTiles));
|
||||
repaintTile(n, m);
|
||||
}
|
||||
}
|
||||
|
63
src/dev/kske/minesweeper/CustomDialog.java
Normal file
63
src/dev/kske/minesweeper/CustomDialog.java
Normal file
@ -0,0 +1,63 @@
|
||||
package dev.kske.minesweeper;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
|
||||
/**
|
||||
* Project: <strong>Minesweeper</strong><br>
|
||||
* File: <strong>CustomDialog.java</strong><br>
|
||||
* Created: <strong>03.04.2019</strong><br>
|
||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||
*/
|
||||
public class CustomDialog extends JDialog {
|
||||
|
||||
private static final long serialVersionUID = -4019516811065781434L;
|
||||
private final JPanel mcontentPanel = new JPanel();
|
||||
|
||||
/**
|
||||
* Launch the application.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
CustomDialog dialog = new CustomDialog();
|
||||
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
dialog.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the dialog.
|
||||
*/
|
||||
public CustomDialog() {
|
||||
setBounds(100, 100, 450, 300);
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
mcontentPanel.setLayout(new FlowLayout());
|
||||
mcontentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
getContentPane().add(mcontentPanel, BorderLayout.CENTER);
|
||||
{
|
||||
JPanel buttonPane = new JPanel();
|
||||
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
|
||||
getContentPane().add(buttonPane, BorderLayout.SOUTH);
|
||||
{
|
||||
JButton okButton = new JButton("OK");
|
||||
okButton.setActionCommand("OK");
|
||||
buttonPane.add(okButton);
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
}
|
||||
{
|
||||
JButton cancelButton = new JButton("Cancel");
|
||||
cancelButton.setActionCommand("Cancel");
|
||||
buttonPane.add(cancelButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
27
src/dev/kske/minesweeper/FlaggedTilesEvent.java
Normal file
27
src/dev/kske/minesweeper/FlaggedTilesEvent.java
Normal file
@ -0,0 +1,27 @@
|
||||
package dev.kske.minesweeper;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* Project: <strong>Minesweeper</strong><br>
|
||||
* File: <strong>FlaggedTilesEvent.java</strong><br>
|
||||
* Created: <strong>03.04.2019</strong><br>
|
||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||
*/
|
||||
public class FlaggedTilesEvent extends EventObject {
|
||||
|
||||
private static final long serialVersionUID = -5809857531886339312L;
|
||||
|
||||
private final Board board;
|
||||
private final int flagged;
|
||||
|
||||
public FlaggedTilesEvent(Object source, int flagged) {
|
||||
super(source);
|
||||
board = (Board) source;
|
||||
this.flagged = flagged;
|
||||
}
|
||||
|
||||
public Board getBoard() { return board; }
|
||||
|
||||
public int getFlagged() { return flagged; }
|
||||
}
|
14
src/dev/kske/minesweeper/GameListener.java
Normal file
14
src/dev/kske/minesweeper/GameListener.java
Normal file
@ -0,0 +1,14 @@
|
||||
package dev.kske.minesweeper;
|
||||
|
||||
/**
|
||||
* Project: <strong>Minesweeper</strong><br>
|
||||
* File: <strong>GameStateListener.java</strong><br>
|
||||
* Created: <strong>03.04.2019</strong><br>
|
||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||
*/
|
||||
public interface GameListener {
|
||||
|
||||
void onGameStateEvent(GameStateEvent evt);
|
||||
|
||||
void onFlaggedTilesEvent(FlaggedTilesEvent evt);
|
||||
}
|
27
src/dev/kske/minesweeper/GameStateEvent.java
Normal file
27
src/dev/kske/minesweeper/GameStateEvent.java
Normal file
@ -0,0 +1,27 @@
|
||||
package dev.kske.minesweeper;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* Project: <strong>Minesweeper</strong><br>
|
||||
* File: <strong>GameStateEvent.java</strong><br>
|
||||
* Created: <strong>03.04.2019</strong><br>
|
||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||
*/
|
||||
public class GameStateEvent extends EventObject {
|
||||
|
||||
private static final long serialVersionUID = -966111253980213845L;
|
||||
|
||||
private final Board board;
|
||||
private final GameState gameState;
|
||||
|
||||
public GameStateEvent(Object source, GameState gameState) {
|
||||
super(source);
|
||||
board = (Board) source;
|
||||
this.gameState = gameState;
|
||||
}
|
||||
|
||||
public Board getBoard() { return board; }
|
||||
|
||||
public GameState getGameState() { return gameState; }
|
||||
}
|
@ -2,14 +2,18 @@ package dev.kske.minesweeper;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
/**
|
||||
* Project: <strong>Minesweeper</strong><br>
|
||||
@ -68,9 +72,38 @@ public class Minesweeper {
|
||||
mframe.getContentPane().setLayout(new BorderLayout(0, 0));
|
||||
mframe.getContentPane().add(board, BorderLayout.CENTER);
|
||||
|
||||
|
||||
JPanel headerPanel = new JPanel();
|
||||
mframe.getContentPane().add(headerPanel, BorderLayout.NORTH);
|
||||
headerPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
|
||||
|
||||
JLabel lblRemainingMines = new JLabel("Remaining Mines:");
|
||||
lblRemainingMines.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
headerPanel.add(lblRemainingMines);
|
||||
|
||||
board.registerGameListener(new GameListener() {
|
||||
|
||||
@Override
|
||||
public void onGameStateEvent(GameStateEvent evt) {
|
||||
switch (evt.getGameState()) {
|
||||
case LOST:
|
||||
JOptionPane.showMessageDialog(mframe, "Game lost!");
|
||||
break;
|
||||
case WON:
|
||||
JOptionPane.showMessageDialog(mframe, "Game won!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFlaggedTilesEvent(FlaggedTilesEvent evt) {
|
||||
lblRemainingMines.setText("Remaining Mines: " + (evt.getBoard().getMines() - evt.getFlagged()));
|
||||
mframe.pack();
|
||||
}
|
||||
});
|
||||
|
||||
JButton btnRestart = new JButton("Restart");
|
||||
headerPanel.add(btnRestart);
|
||||
btnRestart.addActionListener((evt) -> board.reset());
|
||||
mframe.getContentPane().add(btnRestart, BorderLayout.NORTH);
|
||||
mframe.pack();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user