import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JMinesweeper extends JFrame {
private int row = 10;
private int column = 10;
private int bombsNumber = 10;
private static final long serialVersionUID = 1L;
// stores which cells are bombs and which are not
private boolean[][] bombs = new boolean[row][column];
// Stores information on which cell has been displayed
private boolean[][] isShow = new boolean[row][column];
// stores information on surrounding cells
private int[][] showNumber = new int[row][column];
private boolean gameStatue = true; // true for not end, false for end
private JPanel bombsPanel = new JPanel();
private JToggleButton[][] cellButton = new JToggleButton[row][column];
private JPanel jPanel = new JPanel();
private JButton jbtNewButton = new JButton("New game");
private int currentBombsNumber = bombsNumber;
private JLabel jblBombsNumber = new JLabel(String.valueOf(currentBombsNumber));
private JLabel jblTime = new JLabel("0s");
private int time = 0;
private Timer timer = new Timer(1000, new TimerListener());
private JPanel jSetPanel = new JPanel();
private JTextField jtfRowNumber = new JTextField(String.valueOf(row));
private JTextField jtfColumnNumber = new JTextField(String.valueOf(column));
private JTextField jtfBombsNumber = new JTextField(String.valueOf(bombsNumber));
/**
* This is default constructor
*/
public JMinesweeper() {
super();
bombsInitialize();
initializeShowInf();
initializeIsShow();
initializeBoard();
initializeGUI();
}
public static void main(String[] args) {
JMinesweeper frame = new JMinesweeper();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
time++;
if (time < 60)
jblTime.setText(String.valueOf(time) + "s");
else if (time < 3600)
jblTime.setText(String.valueOf(time / 60) + "min" + String.valueOf(time % 60) + "s");
else
jblTime.setText(String.valueOf(time / 3600) + "h" + String.valueOf((time % 3600) / 60) + "min" + String.valueOf(time % 60) + "s");
}
}
private void initializeBoard() {
bombsPanel.setLayout(new GridLayout(row, column, 0, 0));
bombsPanel.removeAll();
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
cellButton[i][j] = new JToggleButton("");
cellButton[i][j].addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if (gameStatue) {
if (e.getButton() == MouseEvent.BUTTON1) {
if (!timer.isRunning())
timer.start();
showCell(e);
}
else if (e.getButton() == MouseEvent.BUTTON3) {
markCell(e);
}
}
}
});
bombsPanel.add(cellButton[i][j]);
}
}
}
private void initializeVariable() {
if (timer.isRunning())
timer.stop();
row = 10; column = 10; bombsNumber = 10;
try {
row = Integer.parseInt(jtfRowNumber.getText());
column = Integer.parseInt(jtfColumnNumber.getText());
bombsNumber = Integer.parseInt(jtfBombsNumber.getText());
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, "You must enter valid integer");
}
if (row <10 || column < 10 || bombsNumber < 10) {
JOptionPane.showMessageDialog(null, "Row, column and bombs number can't be smaller than 10");
row = 10; column = 10; bombsNumber = 10;
jtfRowNumber.setText(String.valueOf(row));
jtfColumnNumber.setText(String.valueOf(column));
jtfBombsNumber.setText(String.valueOf(bombsNumber));
}
bombs = new boolean[row][column];
isShow = new boolean[row][column];
showNumber = new int[row][column];
cellButton = new JToggleButton[row][column];
time = 0;
currentBombsNumber = bombsNumber;
jblBombsNumber.setText(String.valueOf(currentBombsNumber));
jblTime.setText("0s");
gameStatue = true;
}
/**
* This method initialize GUI Panel
*/
private void initializeGUI() {
jbtNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
initializeVariable();
bombsInitialize();
initializeShowInf();
initializeIsShow();
initializeBoard();
}
});
jPanel.setLayout(new GridLayout(0, 3, 10, 10));
jPanel.add(jblBombsNumber);
jPanel.add(jbtNewButton);
jPanel.add(jblTime);
jSetPanel.setLayout(new GridLayout(2, 3, 5, 5));
jSetPanel.add(new JLabel("Row number"));
jSetPanel.add(new JLabel("Column number"));
jSetPanel.add(new JLabel("Bomb number"));
jSetPanel.add(jtfRowNumber);
jSetPanel.add(jtfColumnNumber);
jSetPanel.add(jtfBombsNumber);
add(jPanel, BorderLayout.NORTH);
add(bombsPanel, BorderLayout.CENTER);
add(jSetPanel, BorderLayout.SOUTH);
setSize(480, 480);
setTitle("Java Mine Sweeper");
}
/**
* This method initialize bombs array
*/
private void bombsInitialize() {
if (bombsNumber <= row * column / 2) {
for (int i = 0; i < row; i++)
for (int j = 0; j < column; j++)
bombs[i][j] = false;
int n = 0;
do {
int x = (int)(Math.random() * row);
int y = (int)(Math.random() * column);
if (bombs[x][y] == false) {
bombs[x][y] = true;
n++;
}
} while (n < bombsNumber);
}
else {
for (int i = 0; i < row; i++)
for (int j = 0; j < column; j++)
bombs[i][j] = true;
int n = 0;
while (n < row * column - bombsNumber) {
int x = (int)(Math.random() * row);
int y = (int)(Math.random() * column);
if (bombs[x][y] == true) {
bombs[x][y] = false;
n++;
}
}
}
}
private void initializeIsShow() {
for (int i = 0; i < isShow.length; i++)
for (int j = 0; j < isShow[0].length; j++)
isShow[i][j] = false;
}
private void initializeShowInf() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
showNumber[i][j] = bombCount(i, j);
}
}
}
/**
* This method count bomb number surrounding a cell
* @param x: row index
* @param y: column index
* @return bomb number
*/
private int bombCount(int x, int y) {
int bombNumber = 0;
for (int r = -1; r <= 1; r++) {
for (int s = -1; s <=1 ;s++) {
int newX = x + r;
int newY = y + s;
if (isBounds(newX, newY))
if (bombs[newX][newY])
bombNumber++;
}
}
return bombNumber;
}
private boolean isBounds(int x, int y) {
// Check if position is within bounds
return x >= 0 && x < row && y >= 0 && y < column;
}
private void showCell(MouseEvent e) {
JToggleButton jButton = (JToggleButton)e.getSource();
jButton.setEnabled(false);
int currX = getRow(jButton);
int currY = getColumn(jButton);
if (bombs[currX][currY]) {
showAllBombs();
timer.stop();
gameStatue = false;
JOptionPane.showMessageDialog(null,"You lost!");
}
else {
if (showNumber[currX][currY] > 0) {
jButton.setText(String.valueOf(showNumber[currX][currY]));
isShow[currX][currY] = true;
}
else if (showNumber[currX][currY] == 0)
clearCells(currX, currY);
if (isWinned()) {
timer.stop();
gameStatue = false;
JOptionPane.showMessageDialog(null,"You win!");
}
}
}
// test player whether wins this game
private boolean isWinned() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (!isShow[i][j] && !bombs[i][j])
return false;
}
}
return true;
}
// Displays all cells marked as bombs
private void showAllBombs() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (bombs[i][j])
cellButton[i][j].setText("X");
cellButton[i][j].setSelected(true);
cellButton[i][j].setEnabled(false);
}
}
}
/**
* This method dispay all cells when clicked on an empty cell
* @param x: row of cell clicked
* @param y: column of cell clicked
*/
private void clearCells(int x, int y) {
if (isBounds(x, y)) {
if (!isShow[x][y] && !bombs[x][y]) {
if (showNumber[x][y] == 0)
cellButton[x][y].setText("");
else
cellButton[x][y].setText(String.valueOf(showNumber[x][y]));
cellButton[x][y].setSelected(true);
cellButton[x][y].setEnabled(false);
isShow[x][y] = true;
if (showNumber[x][y] == 0) {
for (int r = -1; r <= 1; r++)
for (int s = -1; s <= 1; s++)
clearCells(x + r, y + s);
}
}
}
}
// get row number of clicked button
private int getRow(JToggleButton jbt) {
for (int i =0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (jbt == cellButton[i][j])
return i;
}
}
return -1;
}
// get column number of clicked button
private int getColumn(JToggleButton jbt) {
for (int i =0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (jbt == cellButton[i][j])
return j;
}
}
return -1;
}
/**
* this method show mark on a button when player click right button
* @param e
*/
private void markCell(MouseEvent e) {
JToggleButton jButton = (JToggleButton)e.getSource();
if (jButton.isEnabled()) {
if (jButton.getText().equals("")) {
jButton.setText("!");
currentBombsNumber--;
if (currentBombsNumber <= bombsNumber && currentBombsNumber >= 0)
jblBombsNumber.setText(String.valueOf(currentBombsNumber));
else if (currentBombsNumber < 0)
jblBombsNumber.setText("0");
else
jblBombsNumber.setText(String.valueOf(bombsNumber));
}
else if (jButton.getText().equals("!")) {
jButton.setText("?");
currentBombsNumber++;
if (currentBombsNumber <= bombsNumber && currentBombsNumber >= 0)
jblBombsNumber.setText(String.valueOf(currentBombsNumber));
else if (currentBombsNumber < 0)
jblBombsNumber.setText("0");
else
jblBombsNumber.setText(String.valueOf(bombsNumber));
}
else
jButton.setText("");
}
}
}
扫雷的java程序
最新推荐文章于 2023-06-08 14:09:53 发布