161 lines
5.1 KiB
Java
161 lines
5.1 KiB
Java
package de.craftix.game;
|
|
|
|
import javax.swing.*;
|
|
import java.awt.*;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.event.MouseListener;
|
|
import java.util.Random;
|
|
|
|
public class Minesweeper extends JFrame {
|
|
public static boolean showMines = false;
|
|
public static int percentage = 20;
|
|
public static int spacing = 5;
|
|
public static boolean loose = false;
|
|
public static boolean win = false;
|
|
|
|
public static Random rand = new Random();
|
|
public static Board board = new Board();
|
|
|
|
public static int[][] neighbours = new int[16][9];
|
|
public static boolean[][] mines = new boolean[16][9];
|
|
public static boolean[][] revealed = new boolean[16][9];
|
|
public static boolean[][] flagged = new boolean[16][9];
|
|
|
|
public static void main(String[] args) {
|
|
new Minesweeper(1280, 800);
|
|
}
|
|
|
|
public Minesweeper(int width, int height) {
|
|
for (int x = 0; x < 16; x++) for (int y = 0; y < 9; y++) mines[x][y] = (rand.nextInt(100) < percentage);
|
|
|
|
for (int x = 0; x < 16; x++) {
|
|
for (int y = 0; y < 9; y++) {
|
|
revealed[x][y] = true;
|
|
flagged[x][y] = false;
|
|
neighbours[x][y] = getNeighbours(x, y);
|
|
}
|
|
}
|
|
revealed[0][0] = false;
|
|
revealed[1][0] = false;
|
|
mines[0][0] = true;
|
|
|
|
setTitle("Minesweeper");
|
|
setSize(width + 17, height + 40);
|
|
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
|
setResizable(false);
|
|
setLocationRelativeTo(null);
|
|
setVisible(true);
|
|
setContentPane(board);
|
|
}
|
|
|
|
private static class Board extends JPanel {
|
|
public Board() { addMouseListener(new Click()); }
|
|
|
|
@Override
|
|
protected void paintComponent(Graphics g) {
|
|
super.paintComponent(g);
|
|
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
|
|
g.setColor(Color.DARK_GRAY);
|
|
g.fillRect(0, 0, getWidth(), getHeight());
|
|
|
|
for (int x = 0; x < 16; x++) {
|
|
for (int y = 0; y < 9; y++) {
|
|
g.setColor(Color.GRAY);
|
|
if (showMines && mines[x][y]) g.setColor(Color.YELLOW);
|
|
if (getScreenPos(x, y).contains(mousePos())) g.setColor(Color.LIGHT_GRAY);
|
|
if (revealed[x][y]) {
|
|
((Graphics2D) g).draw(getScreenPos(x, y));
|
|
if (mines[x][y]) {
|
|
g.setColor(Color.RED);
|
|
((Graphics2D) g).fill(getScreenPos(x, y));
|
|
loose = true;
|
|
}else {
|
|
g.setColor(Color.WHITE);
|
|
g.setFont(new Font("Tahoma", Font.BOLD, 40));
|
|
g.drawString(Integer.toString(neighbours[x][y]), x * 80 + 27, y * 80 + 135);
|
|
}
|
|
}
|
|
else ((Graphics2D) g).fill(getScreenPos(x, y));
|
|
}
|
|
}
|
|
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
private static class Click implements MouseListener {
|
|
|
|
@Override
|
|
public void mouseClicked(MouseEvent e) {
|
|
System.out.println(checkWinning());
|
|
if (loose || win) return;
|
|
if (checkWinning()) return;
|
|
Point box = inBox(e.getX(), e.getY());
|
|
if (box == null) return;
|
|
revealed[box.x][box.y] = true;
|
|
}
|
|
|
|
@Override
|
|
public void mousePressed(MouseEvent e) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void mouseReleased(MouseEvent e) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void mouseEntered(MouseEvent e) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void mouseExited(MouseEvent e) {
|
|
|
|
}
|
|
}
|
|
|
|
private static boolean checkWinning() {
|
|
int open = 0, bombs = 0;
|
|
for (int x = 0; x < 16; x++) for (int y = 0; y < 9; y++) {
|
|
if (revealed[x][y] && !mines[x][y]) open++;
|
|
if (mines[x][y]) bombs++;
|
|
}
|
|
return (open + bombs - 1) == (16 * 9);
|
|
}
|
|
|
|
private static Point inBox(int mx, int my) {
|
|
for (int x = 0; x < 16; x++) {
|
|
for (int y = 0; y < 9; y++) {
|
|
if (getScreenPos(x, y).contains(mx, my)) return new Point(x, y);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static int getNeighbours(int x, int y) {
|
|
int n = 0;
|
|
if (isBomb(x - 1, y - 1)) n++;
|
|
if (isBomb(x - 1, y)) n++;
|
|
if (isBomb(x - 1, y + 1)) n++;
|
|
if (isBomb(x + 1, y - 1)) n++;
|
|
if (isBomb(x + 1, y)) n++;
|
|
if (isBomb(x + 1, y + 1)) n++;
|
|
if (isBomb(x, y + 1)) n++;
|
|
if (isBomb(x, y - 1)) n++;
|
|
return n;
|
|
}
|
|
|
|
private static boolean isBomb(int x, int y) { try { return mines[x][y]; } catch (Exception ignored) { return false; } }
|
|
|
|
private static Point mousePos() {
|
|
Point p = MouseInfo.getPointerInfo().getLocation();
|
|
SwingUtilities.convertPointFromScreen(p, board);
|
|
return p;
|
|
}
|
|
|
|
private static Rectangle getScreenPos(int x, int y) { return new Rectangle(spacing + x * 80, spacing + y * 80 + 80, 80 - spacing * 2, 80 - spacing * 2); }
|
|
|
|
}
|