Added board init and reset methods, added BoardConfig object
This commit is contained in:
parent
892d6be2ef
commit
7bc2a0711e
@ -1,12 +1,14 @@
|
|||||||
package dev.kske.minesweeper;
|
package dev.kske.minesweeper;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.Point;
|
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.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@ -26,13 +28,14 @@ public class Board extends JPanel {
|
|||||||
|
|
||||||
private static Map<String, Image> icons;
|
private static Map<String, Image> icons;
|
||||||
|
|
||||||
private int width, height;
|
private int boardWidth, boardHeight;
|
||||||
private Rectangle screen;
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
icons = new HashMap<>();
|
icons = new HashMap<>();
|
||||||
final String[] names = { "mine2", "mine4", "tile", "tile3", "flag" };
|
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
|
// Not using a layout manager
|
||||||
super(null);
|
super(null);
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
addMouseListener(new MouseAdapter() {
|
||||||
screen = new Rectangle(x, y, x + width * tileSize, y + height * tileSize);
|
|
||||||
|
@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;
|
gameState = GameState.ACTIVE;
|
||||||
this.mines = mines;
|
this.mines = config.mines;
|
||||||
activeTiles = width * height;
|
activeTiles = boardWidth * boardHeight;
|
||||||
flaggedTiles = 0;
|
flaggedTiles = 0;
|
||||||
|
|
||||||
board = new Tile[width][height];
|
// Init board
|
||||||
for (int i = 0; i < width; i++)
|
board = new Tile[boardWidth][boardHeight];
|
||||||
for (int j = 0; j < height; j++)
|
for (int i = 0; i < boardWidth; i++)
|
||||||
|
for (int j = 0; j < boardHeight; j++)
|
||||||
board[i][j] = new Tile();
|
board[i][j] = new Tile();
|
||||||
|
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
init(initialConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintComponent(Graphics g) {
|
public void paintComponent(Graphics g) {
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
for (int i = 0; i < width; i++)
|
for (int i = 0; i < boardWidth; i++)
|
||||||
for (int j = 0; j < height; j++) {
|
for (int j = 0; j < boardHeight; j++) {
|
||||||
Tile tile = board[i][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
|
// Draw background with grid
|
||||||
g.setColor(Color.gray);
|
g.setColor(Color.gray);
|
||||||
@ -77,11 +115,11 @@ public class Board extends JPanel {
|
|||||||
switch (gameState) {
|
switch (gameState) {
|
||||||
case LOST:
|
case LOST:
|
||||||
// Draw tile with normal mine
|
// 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;
|
break;
|
||||||
case WON:
|
case WON:
|
||||||
// Draw tile with diffused mine
|
// 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;
|
break;
|
||||||
default:
|
default:
|
||||||
if (tile.isTouched()) {
|
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) {
|
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() {
|
public void initMines() {
|
||||||
@ -118,8 +160,8 @@ public class Board extends JPanel {
|
|||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
// Randomly select a tile
|
// Randomly select a tile
|
||||||
int n = random.nextInt(width);
|
int n = random.nextInt(boardWidth);
|
||||||
int m = random.nextInt(height);
|
int m = random.nextInt(boardHeight);
|
||||||
|
|
||||||
// Check if the selected tile already is a mine
|
// Check if the selected tile already is a mine
|
||||||
if (!board[n][m].isMine()) {
|
if (!board[n][m].isMine()) {
|
||||||
@ -156,12 +198,11 @@ public class Board extends JPanel {
|
|||||||
|
|
||||||
// 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)
|
||||||
for (int i = Math.max(0, n - 1); i < Math.min(n + 1, board.length); i++)
|
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 + 1, board[i].length); j++)
|
for (int j = Math.max(0, m - 1); j < Math.min(m + 2, board[i].length); j++)
|
||||||
touchTile(i, j);
|
touchTile(i, j);
|
||||||
|
|
||||||
// Redraw the touched tile
|
repaintTile(n, m);
|
||||||
repaint(n * tileSize, m * tileSize, (n + 1) * tileSize, (n + 1) * tileSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +216,7 @@ public class Board extends JPanel {
|
|||||||
tile.setFlagged(true);
|
tile.setFlagged(true);
|
||||||
flaggedTiles++;
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,8 @@ public class Minesweeper {
|
|||||||
private JFrame mframe;
|
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.
|
* Launch the application.
|
||||||
@ -56,15 +58,17 @@ public class Minesweeper {
|
|||||||
mframe = new JFrame();
|
mframe = new JFrame();
|
||||||
mframe.setResizable(false);
|
mframe.setResizable(false);
|
||||||
mframe.setTitle("Minesweeper");
|
mframe.setTitle("Minesweeper");
|
||||||
mframe.setBounds(100, 100, 450, 300);
|
mframe.setBounds(100, 100, 384, 308);
|
||||||
mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
createMenuBar();
|
createMenuBar();
|
||||||
|
|
||||||
board = new Board(0, 0, 10, 10, 10);
|
board = new Board();
|
||||||
|
board.init(easyConfig);
|
||||||
mframe.getContentPane().add(board);
|
mframe.getContentPane().add(board);
|
||||||
|
|
||||||
JButton btnRestart = new JButton("Restart");
|
JButton btnRestart = new JButton("Restart");
|
||||||
|
btnRestart.addActionListener((evt) -> { board.reset(); });
|
||||||
mframe.getContentPane().add(btnRestart, BorderLayout.NORTH);
|
mframe.getContentPane().add(btnRestart, BorderLayout.NORTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +89,10 @@ public class Minesweeper {
|
|||||||
hardMenuItem.setMnemonic(KeyEvent.VK_H);
|
hardMenuItem.setMnemonic(KeyEvent.VK_H);
|
||||||
customMenuItem.setMnemonic(KeyEvent.VK_C);
|
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");
|
JOptionPane.showMessageDialog(board, "Minesweeper version " + VERSION + "\nby Kai S. K. Engelbart");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user