八皇后问题JavaFX版


问题描述

提示:随机92种,按钮式输出

修改Java黑皮书程序清单22-11的代码,利用按钮遍历92种结果


难点分析:

提示:建议准备好Java基础篇这本书,现学现卖,问题不大。还有其他思路,我是先储存好92种结果之后按钮遍历就好,也可以将事件驱动改一下,每次点击按钮都进行一次计算,前者速度快,消耗少,后者更好操作。

首先是按钮的添加,这个在Java黑皮书(11版)上486页中GridPane示例代码中有讲到,直接套用,先创建一个button对象,之后把这个组件加到面板上就好。

 //Create a new button and it's handles
Button nextButton = new Button("Next");
nextButton.setPrefSize(55, 30);
chessBoard.add(nextButton, 2, 8);

Button beforeButton = new Button("Before");
beforeButton.setPrefSize(55, 30);
chessBoard.add(beforeButton, 6, 8);

之后是对原来算法的改进与改造,首先是要理解为什么他只有一种结果,其次是他怎么会有多种结果,对于第一个问题,可能都知道,首先他找值的时候只返回一个结果,结果固定,一次遍历完了就没有第二次遍历了;如果要让他有多个结果并储存好,那么就需要修改代码,这里我们先修改算法:

        对于isValid这个方法,书上的方法可以精简,其实用一维数组来做你只需要考虑是否在同一列,和是否在同一斜线上就好了,这里再同一斜线上可以用数学中求斜率的思想Y1 - Y2 / X1 - X2

加上绝对值就好。

  public boolean isValid(int n) {
        for (int i = 0; i < n; i++) {
            if (queens[n] == queens[i] || Math.abs(queens[n] - queens[i]) == Math.abs(n - i)) {
                return false;
            }
        }
        return true;
    }

        对于这里要找到所有的结果,只需要递归就好了,让计算机遍历所有情况然后返回合理的结果:

 public void search(int n) {
        if (n == 8) {
            m++;
            record();
            return;
        }

        for (int i = 0; i < 8; i++) {
            queens[n] = i;
            if (isValid(n)) {
                search(n + 1);
            }
        }
    }

最后便是事件的编写,这里建议看一下黑皮书的第15章的事件驱动编程:

 nextButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                for (int i = 0; i < SIZE; i++)
                    labels[i][queenAll[w][i]].setText("");

                w++;

                if (w > 92){
                    w = 0;
                }

                for (int i = 0; i < SIZE; i++)
                    labels[i][queenAll[w][i]].setText("♛");

                System.out.println("第"+w+"种方法");
            }

        });


        beforeButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                for (int i = 0; i < SIZE; i++)
                    labels[i][queenAll[w][i]].setText("");

                w--;

                if (w < 0){
                    w = 92;
                }
                for (int i = 0; i < SIZE; i++)
                    labels[i][queenAll[w][i]].setText("♛");

                System.out.println("第"+w+"种方法");
            }
        });

代码:

提示:其中中文可能乱码,改成英文就好

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class EightQueens extends Application {
    public static final int SIZE = 8; // The size of the chess board
    // queens are placed at (i, queens[i])
    // -1 indicates that no queen is currently placed in the ith row
    // Initially, place a queen at (0, 0) in the 0th row
    private int[] queens = {-1, -1, -1, -1, -1, -1, -1, -1};
    private int[][] queenAll = new int[92][8];
    private int m = -1;
    private int w = 0;


    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        search(0); // Search for a solution

        // Display chess board
        GridPane chessBoard = new GridPane();
        chessBoard.setAlignment(Pos.CENTER);
        Label[][] labels = new Label[SIZE][SIZE];
        for (int i = 0; i < SIZE; i++)
            for (int j = 0; j < SIZE; j++) {
                chessBoard.add(labels[i][j] = new Label(), j, i);
                labels[i][j].setStyle("-fx-border-color: black");
                labels[i][j].setPrefSize(55, 55);
            }


        //Create a new button and it's handles
        Button nextButton = new Button("Next");
        nextButton.setPrefSize(55, 30);
        chessBoard.add(nextButton, 2, 8);

        Button beforeButton = new Button("Before");
        beforeButton.setPrefSize(55, 30);
        chessBoard.add(beforeButton, 6, 8);

        nextButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                for (int i = 0; i < SIZE; i++)
                    labels[i][queenAll[w][i]].setText("");

                w++;

                if (w > 92){
                    w = 0;
                }

                for (int i = 0; i < SIZE; i++)
                    labels[i][queenAll[w][i]].setText("♛");

                System.out.println("第"+w+"种方法");
            }

        });


        beforeButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                for (int i = 0; i < SIZE; i++)
                    labels[i][queenAll[w][i]].setText("");

                w--;

                if (w < 0){
                    w = 92;
                }
                for (int i = 0; i < SIZE; i++)
                    labels[i][queenAll[w][i]].setText("♛");

                System.out.println("第"+w+"种方法");
            }
        });

        // Display queens
//        Image image = new Image("image/queen.jpg");
        for (int i = 0; i < SIZE; i++)
            labels[i][queenAll[w][i]].setText("♛");


        // Create a scene and place it in the stage
        Scene scene = new Scene(chessBoard, 55 * SIZE, 55 * SIZE);
        primaryStage.setTitle("EightQueens"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage
    }

    public void search(int n) {
        if (n == 8) {
            m++;
            record();
            return;
        }

        for (int i = 0; i < 8; i++) {
            queens[n] = i;
            if (isValid(n)) {
                search(n + 1);
            }
        }
    }

    public boolean isValid(int n) {
        for (int i = 0; i < n; i++) {
            if (queens[n] == queens[i] || Math.abs(queens[n] - queens[i]) == Math.abs(n - i)) {
                return false;
            }
        }
        return true;
    }

    public void record() {
        for (int i = 0; i < queens.length; i++) {
            queenAll[m][i] = queens[i];

        }
        System.out.println();
    }

    /**
     * The main method is only needed for the IDE with limited
     * JavaFX support. Not needed for running from the command line.
     */
    public static void main(String[] args) {
        launch(args);
    }
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值