Added board init and reset methods, added BoardConfig object
This commit is contained in:
parent
0d7d498af7
commit
4e63dea497
@ -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<String, Image> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
src/dev/kske/minesweeper/BoardConfig.java
Normal file
20
src/dev/kske/minesweeper/BoardConfig.java
Normal file
@ -0,0 +1,20 @@
|
||||
package dev.kske.minesweeper;
|
||||
|
||||
/**
|
||||
* Project: <strong>Minesweeper</strong><br>
|
||||
* File: <strong>BoardConfig.java</strong><br>
|
||||
* Created: <strong>01.04.2019</strong><br>
|
||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user