package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
import java.net.URL;
import java.util.Random;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
private ChoiceBox<String> choiceBox;
@FXML
private GridPane pane;
@FXML
private Label label;
@FXML
private HBox hBox;
Button[][] btns; //按钮存储
boolean[][] pressed; //对应得是否按下存储
boolean[][] genLei; //对应是否为雷存储
int [][] nums; //按钮上显示的数,如1,说明周围有1个雷
boolean[][] flags; //用户标记存储
int width;
int height;
int leiNum; //雷数
int flagNum; //标记数
int pressedNum; //已被打开的按钮数
boolean isEnd;
@Override
public void initialize(URL location, ResourceBundle resources) {
choiceBox.setOnAction(e -> {
System.out.println("changed");
String value = choiceBox.getValue();
String[] ss = value.split("\\*");
String[] split = ss[1].split("\\|");
height = Integer.parseInt(ss[0]);
width = Integer.parseInt(split[0]);
leiNum = Integer.parseInt(split[1]);
play();
});
choiceBox.getSelectionModel().select(1);
}
public void play(){
System.out.println("play");
genLei = new boolean[height][width];
pressed = new boolean[height][width];
btns = new Button[height][width];
nums = new int[height][width];
flags = new boolean[height][width];
pane.getChildren().clear();
flagNum = 0;
pressedNum = 0;
label.setText(String.valueOf(leiNum));
int rest = leiNum;
Random r = new Random(System.nanoTime());
while (rest > 0) {
int n = r.nextInt(height * width);
if(!genLei[n / width][n % width]){
genLei[n / width][n % width] = true;
rest--;
}
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
Button btn = getBtn(j, i);
btns[i][j] = btn;
nums[i][j] = countLeisAround(j, i);
pane.add(btn, j, i);
}
}
}
public int countLeisAround(int x, int y){
int res = 0;
for (int i = Math.max(0, y - 1); i <= Math.min(y + 1, height - 1); i++) {
for (int j = Math.max(0, x - 1); j <= Math.min(x + 1, width - 1); j++) {
if((y != i || x != j) && genLei[i][j])
res++;
}
}
return res;
}
public Button getBtn(int x, int y){
Button button = new Button();
button.setPrefSize(30, 30);
button.setMinSize(30, 30);
button.setStyle("-fx-background-color: darkcyan;");
button.setOnMouseClicked(e -> {
if(e.getClickCount() == 2 && pressed[y][x]){
int count = 0;
for (int i = Math.max(0, y - 1); i <= Math.min(y + 1, height - 1); i++) {
for (int j = Math.max(0, x - 1); j <= Math.min(x + 1, width - 1); j++) {
if(flags[i][j])
count++;
}
}
if (count != nums[y][x]) return;
for (int i = Math.max(0, y - 1); i <= Math.min(y + 1, height - 1); i++) {
for (int j = Math.max(0, x - 1); j <= Math.min(x + 1, width - 1); j++) {
if (isEnd){
isEnd = false;
return;
}
if(!flags[i][j])
open(j, i);
}
}
return;
}
if (MouseButton.SECONDARY == e.getButton()) {
if(!flags[y][x]) {
flagNum++;
flags[y][x] = true;
Shape shape = new Circle(4, Color.AQUA);
button.setGraphic(shape);
}else {
flagNum--;
flags[y][x] = false;
button.setGraphic(null);
}
} else {
if(flags[y][x]) {
flagNum--;
button.setGraphic(null);
}
open(x, y);
}
updateRemain();
});
return button;
}
public void updateRemain(){
label.setText(String.valueOf(leiNum - flagNum));
}
public void open(int x, int y){
if (pressed[y][x])
return;
pressed[y][x] = true;
Button button = btns[y][x];
if (genLei[y][x]) {
isEnd = true;
button.setText("*");
button.setStyle("-fx-background-color: crimson");
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("what`s a pity!\nplease retry ...");
alert.setTitle("Information");
alert.showAndWait();
play();
}else {
button.setStyle("-fx-background-color: dimgrey");
pressedNum++;
if (pressedNum == height * width - leiNum){
isEnd = true;
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("you win!");
alert.setTitle("Information");
alert.showAndWait();
play();
return;
}
int count = nums[y][x];
if (count > 0)
button.setText(String.valueOf(count));
else {
for (int i = Math.max(0, y - 1); i <= Math.min(y + 1, height - 1); i++) {
for (int j = Math.max(0, x - 1); j <= Math.min(x + 1, width - 1); j++) {
if(!flags[i][j])
open(j, i);
}
}
}
}
}
public void fullScreen(ActionEvent e){
Stage window = (Stage) pane.getScene().getWindow();
window.setFullScreen(!window.isFullScreen());
}
}