Added events for changes of the game state and flagged tiles
This commit is contained in:
parent
463e5b68bc
commit
dea595e695
@ -8,7 +8,9 @@ import java.awt.Graphics;
|
|||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@ -31,8 +33,9 @@ public class Board extends JPanel {
|
|||||||
private GameState gameState;
|
private GameState gameState;
|
||||||
private int mines, activeTiles, flaggedTiles;
|
private int mines, activeTiles, flaggedTiles;
|
||||||
private Tile[][] board;
|
private Tile[][] board;
|
||||||
|
private BoardConfig initialConfig;
|
||||||
|
|
||||||
private BoardConfig initialConfig;
|
private List<GameListener> listeners;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
icons = new HashMap<>();
|
icons = new HashMap<>();
|
||||||
@ -45,6 +48,7 @@ public class Board extends JPanel {
|
|||||||
public Board() {
|
public Board() {
|
||||||
// Not using a layout manager
|
// Not using a layout manager
|
||||||
super(null);
|
super(null);
|
||||||
|
listeners = new ArrayList<>();
|
||||||
addMouseListener(new MouseAdapter() {
|
addMouseListener(new MouseAdapter() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -84,6 +88,7 @@ public class Board extends JPanel {
|
|||||||
for (int j = 0; j < boardHeight; j++)
|
for (int j = 0; j < boardHeight; j++)
|
||||||
board[i][j] = new Tile();
|
board[i][j] = new Tile();
|
||||||
initMines();
|
initMines();
|
||||||
|
notifyFlaggedTilesEvent(new FlaggedTilesEvent(this, flaggedTiles));
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +96,18 @@ public class Board extends JPanel {
|
|||||||
init(initialConfig);
|
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
|
@Override
|
||||||
public void paintComponent(Graphics g) {
|
public void paintComponent(Graphics g) {
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
@ -172,11 +189,21 @@ public class Board extends JPanel {
|
|||||||
if (tile.isFlagged()) {
|
if (tile.isFlagged()) {
|
||||||
tile.setFlagged(false);
|
tile.setFlagged(false);
|
||||||
flaggedTiles--;
|
flaggedTiles--;
|
||||||
|
notifyFlaggedTilesEvent(new FlaggedTilesEvent(this, flaggedTiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if the game is won or lost
|
// Test if the game is won or lost
|
||||||
if (tile.isMine()) gameState = GameState.LOST;
|
if (tile.isMine()) {
|
||||||
else if (mines == activeTiles) gameState = GameState.WON;
|
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
|
// Touch surrounding tiles when there are zero surrounding mines
|
||||||
else if (tile.getSurroundingMines() == 0)
|
else if (tile.getSurroundingMines() == 0)
|
||||||
@ -198,6 +225,7 @@ public class Board extends JPanel {
|
|||||||
tile.setFlagged(true);
|
tile.setFlagged(true);
|
||||||
flaggedTiles++;
|
flaggedTiles++;
|
||||||
}
|
}
|
||||||
|
notifyFlaggedTilesEvent(new FlaggedTilesEvent(this, flaggedTiles));
|
||||||
repaintTile(n, m);
|
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.BorderLayout;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.FlowLayout;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project: <strong>Minesweeper</strong><br>
|
* Project: <strong>Minesweeper</strong><br>
|
||||||
@ -68,9 +72,38 @@ public class Minesweeper {
|
|||||||
mframe.getContentPane().setLayout(new BorderLayout(0, 0));
|
mframe.getContentPane().setLayout(new BorderLayout(0, 0));
|
||||||
mframe.getContentPane().add(board, BorderLayout.CENTER);
|
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");
|
JButton btnRestart = new JButton("Restart");
|
||||||
|
headerPanel.add(btnRestart);
|
||||||
btnRestart.addActionListener((evt) -> board.reset());
|
btnRestart.addActionListener((evt) -> board.reset());
|
||||||
mframe.getContentPane().add(btnRestart, BorderLayout.NORTH);
|
|
||||||
mframe.pack();
|
mframe.pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user