From 7bc2a0711e51775c19239012156d2867b08d8827 Mon Sep 17 00:00:00 2001 From: kske Date: Mon, 1 Apr 2019 14:57:29 +0200 Subject: [PATCH] Added board init and reset methods, added BoardConfig object --- src/dev/kske/minesweeper/Board.java | 91 ++++++++++++++++------- src/dev/kske/minesweeper/BoardConfig.java | 20 +++++ src/dev/kske/minesweeper/Minesweeper.java | 19 +++-- 3 files changed, 99 insertions(+), 31 deletions(-) create mode 100644 src/dev/kske/minesweeper/BoardConfig.java diff --git a/src/dev/kske/minesweeper/Board.java b/src/dev/kske/minesweeper/Board.java index 2580511..93574e7 100644 --- a/src/dev/kske/minesweeper/Board.java +++ b/src/dev/kske/minesweeper/Board.java @@ -1,12 +1,14 @@ package dev.kske.minesweeper; import java.awt.Color; +import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Image; import java.awt.Point; -import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.HashMap; import java.util.Map; import java.util.Random; @@ -26,13 +28,14 @@ public class Board extends JPanel { private static Map icons; - private int width, height; - private Rectangle screen; + private int boardWidth, boardHeight; private GameState gameState; private int mines, activeTiles, flaggedTiles; private Tile[][] board; + private BoardConfig initialConfig; + static { icons = new HashMap<>(); final String[] names = { "mine2", "mine4", "tile", "tile3", "flag" }; @@ -41,31 +44,66 @@ public class Board extends JPanel { } } - public Board(int x, int y, int width, int height, int mines) { + public Board() { // Not using a layout manager super(null); - this.width = width; - this.height = height; - screen = new Rectangle(x, y, x + width * tileSize, y + height * tileSize); + + addMouseListener(new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent evt) { + Point tilePos = getTilePos(evt.getX(), evt.getY()); + int n = tilePos.x, m = tilePos.y; + Tile tile = board[n][m]; + + if (tile.isTouched() || gameState != GameState.ACTIVE) return; + + switch (evt.getButton()) { + case MouseEvent.BUTTON1: + // Touch tile + touchTile(n, m); + break; + case MouseEvent.BUTTON3: + // Flag tile + flagTile(n, m); + } + } + }); + } + + public void init(BoardConfig config) { + initialConfig = config; + + boardWidth = config.width; + boardHeight = config.height; + + setPreferredSize(new Dimension(config.width * tileSize, config.height * tileSize)); gameState = GameState.ACTIVE; - this.mines = mines; - activeTiles = width * height; + this.mines = config.mines; + activeTiles = boardWidth * boardHeight; flaggedTiles = 0; - board = new Tile[width][height]; - for (int i = 0; i < width; i++) - for (int j = 0; j < height; j++) + // Init board + board = new Tile[boardWidth][boardHeight]; + for (int i = 0; i < boardWidth; i++) + for (int j = 0; j < boardHeight; j++) board[i][j] = new Tile(); + + repaint(); + } + + public void reset() { + init(initialConfig); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); - for (int i = 0; i < width; i++) - for (int j = 0; j < height; j++) { + for (int i = 0; i < boardWidth; i++) + for (int j = 0; j < boardHeight; j++) { Tile tile = board[i][j]; - int x = screen.x + i * tileSize, y = screen.y + j * tileSize; + int x = i * tileSize, y = j * tileSize; // Draw background with grid g.setColor(Color.gray); @@ -77,11 +115,11 @@ public class Board extends JPanel { switch (gameState) { case LOST: // Draw tile with normal mine - g.drawImage(icons.get("mine2"), x, y, this); + if (tile.isMine()) g.drawImage(icons.get("mine2"), x, y, this); break; case WON: // Draw tile with diffused mine - g.drawImage(icons.get("mine4"), x, y, this); + if (tile.isMine()) g.drawImage(icons.get("mine4"), x, y, this); break; default: if (tile.isTouched()) { @@ -109,8 +147,12 @@ public class Board extends JPanel { } } + private void repaintTile(int n, int m) { + repaint(n * tileSize, m * tileSize, (n + 1) * tileSize, (n + 1) * tileSize); + } + public Point getTilePos(int x, int y) { - return new Point((x - screen.x) / tileSize, (y - screen.y) / tileSize); + return new Point(x / tileSize, y / tileSize); } public void initMines() { @@ -118,8 +160,8 @@ public class Board extends JPanel { Random random = new Random(); while (remaining > 0) { // Randomly select a tile - int n = random.nextInt(width); - int m = random.nextInt(height); + int n = random.nextInt(boardWidth); + int m = random.nextInt(boardHeight); // Check if the selected tile already is a mine if (!board[n][m].isMine()) { @@ -156,12 +198,11 @@ public class Board extends JPanel { // Touch surrounding tiles when there are zero surrounding mines else if (tile.getSurroundingMines() == 0) - for (int i = Math.max(0, n - 1); i < Math.min(n + 1, board.length); i++) - for (int j = Math.max(0, m - 1); j < Math.min(m + 1, board[i].length); j++) + for (int i = Math.max(0, n - 1); i < Math.min(n + 2, board.length); i++) + for (int j = Math.max(0, m - 1); j < Math.min(m + 2, board[i].length); j++) touchTile(i, j); - // Redraw the touched tile - repaint(n * tileSize, m * tileSize, (n + 1) * tileSize, (n + 1) * tileSize); + repaintTile(n, m); } } @@ -175,7 +216,7 @@ public class Board extends JPanel { tile.setFlagged(true); flaggedTiles++; } - repaint(n * tileSize, m * tileSize, (n + 1) * tileSize, (n + 1) * tileSize); + repaintTile(n, m); } } } diff --git a/src/dev/kske/minesweeper/BoardConfig.java b/src/dev/kske/minesweeper/BoardConfig.java new file mode 100644 index 0000000..1d97ba9 --- /dev/null +++ b/src/dev/kske/minesweeper/BoardConfig.java @@ -0,0 +1,20 @@ +package dev.kske.minesweeper; + +/** + * Project: Minesweeper
+ * File: BoardConfig.java
+ * Created: 01.04.2019
+ * Author: Kai S. K. Engelbart + */ +public class BoardConfig { + + public final int x, y, width, height, mines; + + public BoardConfig(int x, int y, int width, int height, int mines) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.mines = mines; + } +} diff --git a/src/dev/kske/minesweeper/Minesweeper.java b/src/dev/kske/minesweeper/Minesweeper.java index 8af2231..ca963b3 100644 --- a/src/dev/kske/minesweeper/Minesweeper.java +++ b/src/dev/kske/minesweeper/Minesweeper.java @@ -23,7 +23,9 @@ public class Minesweeper { private JFrame mframe; - private Board board; + private Board board; + private final BoardConfig easyConfig = new BoardConfig(0, 48, 8, 8, 10), + mediumConfig = new BoardConfig(0, 48, 16, 16, 40), hardConfig = new BoardConfig(0, 48, 30, 16, 99); /** * Launch the application. @@ -56,22 +58,24 @@ public class Minesweeper { mframe = new JFrame(); mframe.setResizable(false); mframe.setTitle("Minesweeper"); - mframe.setBounds(100, 100, 450, 300); + mframe.setBounds(100, 100, 384, 308); mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); createMenuBar(); - board = new Board(0, 0, 10, 10, 10); + board = new Board(); + board.init(easyConfig); mframe.getContentPane().add(board); JButton btnRestart = new JButton("Restart"); + btnRestart.addActionListener((evt) -> { board.reset(); }); mframe.getContentPane().add(btnRestart, BorderLayout.NORTH); } private void createMenuBar() { var menubar = new JMenuBar(); - var gameMenu = new JMenu("Game"); + var gameMenu = new JMenu("Game"); var aboutMenuItem = new JMenuItem("About"); var easyMenuItem = new JMenuItem("Easy"); @@ -85,10 +89,13 @@ public class Minesweeper { hardMenuItem.setMnemonic(KeyEvent.VK_H); customMenuItem.setMnemonic(KeyEvent.VK_C); - aboutMenuItem.addActionListener((event) -> { + easyMenuItem.addActionListener((evt) -> { board.init(easyConfig); }); + mediumMenuItem.addActionListener((evt) -> { board.init(mediumConfig); }); + hardMenuItem.addActionListener((evt) -> { board.init(hardConfig); }); + aboutMenuItem.addActionListener((evt) -> { JOptionPane.showMessageDialog(board, "Minesweeper version " + VERSION + "\nby Kai S. K. Engelbart"); }); - + gameMenu.add(easyMenuItem); gameMenu.add(mediumMenuItem); gameMenu.add(hardMenuItem);