Implemented basic gameplay and window adjustment
This commit is contained in:
parent
4e63dea497
commit
0b927c5c9f
@ -6,7 +6,6 @@ import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.HashMap;
|
||||
@ -28,8 +27,7 @@ public class Board extends JPanel {
|
||||
|
||||
private static Map<String, Image> icons;
|
||||
|
||||
private int boardWidth, boardHeight;
|
||||
|
||||
private int boardWidth, boardHeight;
|
||||
private GameState gameState;
|
||||
private int mines, activeTiles, flaggedTiles;
|
||||
private Tile[][] board;
|
||||
@ -47,26 +45,22 @@ public class Board extends JPanel {
|
||||
public Board() {
|
||||
// Not using a layout manager
|
||||
super(null);
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent evt) {
|
||||
Point tilePos = getTilePos(evt.getX(), evt.getY());
|
||||
int n = tilePos.x, m = tilePos.y;
|
||||
int n = evt.getX() / tileSize, m = evt.getY() / tileSize;
|
||||
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);
|
||||
}
|
||||
if (gameState != GameState.ACTIVE) repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -84,12 +78,12 @@ public class Board extends JPanel {
|
||||
activeTiles = boardWidth * boardHeight;
|
||||
flaggedTiles = 0;
|
||||
|
||||
// Init board
|
||||
// Initialize 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();
|
||||
|
||||
initMines();
|
||||
repaint();
|
||||
}
|
||||
|
||||
@ -111,39 +105,31 @@ public class Board extends JPanel {
|
||||
g.setColor(Color.black);
|
||||
g.drawRect(x, y, x + tileSize, y + tileSize);
|
||||
|
||||
// Draw all mines when the game is won or lost
|
||||
switch (gameState) {
|
||||
case LOST:
|
||||
// Draw tile with normal mine
|
||||
if (tile.isMine()) g.drawImage(icons.get("mine2"), x, y, this);
|
||||
break;
|
||||
case WON:
|
||||
// Draw tile with diffused mine
|
||||
if (tile.isMine()) g.drawImage(icons.get("mine4"), x, y, this);
|
||||
break;
|
||||
default:
|
||||
if (tile.isTouched()) {
|
||||
// Draw tile with normal mine
|
||||
if (gameState == GameState.LOST && tile.isMine()) g.drawImage(icons.get("mine2"), x, y, this);
|
||||
// Draw tile with diffused mine
|
||||
else if (gameState == GameState.WON && tile.isMine()) g.drawImage(icons.get("mine4"), x, y, this);
|
||||
else if (tile.isTouched()) {
|
||||
|
||||
// Draw tile with mine
|
||||
if (tile.isMine()) g.drawImage(icons.get("mine2"), x, y, this);
|
||||
// Draw tile with mine
|
||||
if (tile.isMine()) g.drawImage(icons.get("mine2"), x, y, this);
|
||||
|
||||
// Draw flagged tile
|
||||
else if (tile.isDrawSurroundingMines() && tile.getSurroundingMines() > 0) {
|
||||
// Draw number of surrounding mines
|
||||
String numStr = String.valueOf(tile.getSurroundingMines());
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int w = fm.stringWidth(numStr), h = fm.getHeight();
|
||||
g.setFont(new Font("Helvetica", Font.PLAIN, 12));
|
||||
g.drawString(numStr, x + tileSize / 2 - w / 2, y + tileSize / 2 - h / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw flagged tile
|
||||
else if (tile.isFlagged()) g.drawImage(icons.get("flag"), x, y, this);
|
||||
|
||||
// Draw normal tile
|
||||
else g.drawImage(icons.get("tile"), x, y, this);
|
||||
// Draw flagged tile
|
||||
else if (tile.isDrawSurroundingMines() && tile.getSurroundingMines() > 0) {
|
||||
// Draw number of surrounding mines
|
||||
String numStr = String.valueOf(tile.getSurroundingMines());
|
||||
g.setFont(new Font("Helvetica", Font.PLAIN, 18));
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int w = fm.stringWidth(numStr), h = fm.getHeight();
|
||||
g.drawString(numStr, x + tileSize / 2 - w / 2, y + tileSize / 2 + h / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw flagged tile
|
||||
else if (tile.isFlagged()) g.drawImage(icons.get("flag"), x, y, this);
|
||||
|
||||
// Draw normal tile
|
||||
else g.drawImage(icons.get("tile"), x, y, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,11 +137,7 @@ public class Board extends JPanel {
|
||||
repaint(n * tileSize, m * tileSize, (n + 1) * tileSize, (n + 1) * tileSize);
|
||||
}
|
||||
|
||||
public Point getTilePos(int x, int y) {
|
||||
return new Point(x / tileSize, y / tileSize);
|
||||
}
|
||||
|
||||
public void initMines() {
|
||||
private void initMines() {
|
||||
int remaining = mines;
|
||||
Random random = new Random();
|
||||
while (remaining > 0) {
|
||||
@ -163,7 +145,7 @@ public class Board extends JPanel {
|
||||
int n = random.nextInt(boardWidth);
|
||||
int m = random.nextInt(boardHeight);
|
||||
|
||||
// Check if the selected tile already is a mine
|
||||
// Check if the selected tile already is a mine and is not touched
|
||||
if (!board[n][m].isMine()) {
|
||||
// Decrement the counter
|
||||
remaining--;
|
||||
@ -172,14 +154,14 @@ public class Board extends JPanel {
|
||||
board[n][m].setMine(true);
|
||||
|
||||
// Adjust surrounding mine counters
|
||||
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++)
|
||||
if (i != n || j != m) board[i][j].setSurroundingMines(board[i][j].getSurroundingMines() + 1);
|
||||
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++)
|
||||
board[i][j].setSurroundingMines(board[i][j].getSurroundingMines() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void touchTile(int n, int m) {
|
||||
private void touchTile(int n, int m) {
|
||||
Tile tile = board[n][m];
|
||||
if (!tile.isTouched()) {
|
||||
tile.setTouched(true);
|
||||
@ -200,13 +182,13 @@ public class Board extends JPanel {
|
||||
else if (tile.getSurroundingMines() == 0)
|
||||
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);
|
||||
if (i != n || j != m && board[i][j].getSurroundingMines() == 0) touchTile(i, j);
|
||||
|
||||
repaintTile(n, m);
|
||||
}
|
||||
}
|
||||
|
||||
public void flagTile(int n, int m) {
|
||||
private void flagTile(int n, int m) {
|
||||
Tile tile = board[n][m];
|
||||
if (!tile.isTouched()) {
|
||||
if (tile.isFlagged()) {
|
||||
@ -219,4 +201,10 @@ public class Board extends JPanel {
|
||||
repaintTile(n, m);
|
||||
}
|
||||
}
|
||||
|
||||
public int getMines() { return mines; }
|
||||
|
||||
public int getActiveTiles() { return activeTiles; }
|
||||
|
||||
public int getFlaggedTiles() { return flaggedTiles; }
|
||||
}
|
||||
|
@ -58,18 +58,20 @@ public class Minesweeper {
|
||||
mframe = new JFrame();
|
||||
mframe.setResizable(false);
|
||||
mframe.setTitle("Minesweeper");
|
||||
mframe.setBounds(100, 100, 384, 308);
|
||||
mframe.setBounds(100, 100, 198, 123);
|
||||
mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
createMenuBar();
|
||||
|
||||
board = new Board();
|
||||
board.init(easyConfig);
|
||||
mframe.getContentPane().add(board);
|
||||
mframe.getContentPane().setLayout(new BorderLayout(0, 0));
|
||||
mframe.getContentPane().add(board, BorderLayout.CENTER);
|
||||
|
||||
JButton btnRestart = new JButton("Restart");
|
||||
btnRestart.addActionListener((evt) -> { board.reset(); });
|
||||
btnRestart.addActionListener((evt) -> board.reset());
|
||||
mframe.getContentPane().add(btnRestart, BorderLayout.NORTH);
|
||||
mframe.pack();
|
||||
}
|
||||
|
||||
private void createMenuBar() {
|
||||
@ -89,9 +91,9 @@ public class Minesweeper {
|
||||
hardMenuItem.setMnemonic(KeyEvent.VK_H);
|
||||
customMenuItem.setMnemonic(KeyEvent.VK_C);
|
||||
|
||||
easyMenuItem.addActionListener((evt) -> { board.init(easyConfig); });
|
||||
mediumMenuItem.addActionListener((evt) -> { board.init(mediumConfig); });
|
||||
hardMenuItem.addActionListener((evt) -> { board.init(hardConfig); });
|
||||
easyMenuItem.addActionListener((evt) -> initGame(easyConfig));
|
||||
mediumMenuItem.addActionListener((evt) -> initGame(mediumConfig));
|
||||
hardMenuItem.addActionListener((evt) -> initGame(hardConfig));
|
||||
aboutMenuItem.addActionListener((evt) -> {
|
||||
JOptionPane.showMessageDialog(board, "Minesweeper version " + VERSION + "\nby Kai S. K. Engelbart");
|
||||
});
|
||||
@ -106,4 +108,9 @@ public class Minesweeper {
|
||||
|
||||
mframe.setJMenuBar(menubar);
|
||||
}
|
||||
|
||||
private void initGame(BoardConfig config) {
|
||||
board.init(config);
|
||||
mframe.pack();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user