目录
题目:**18.34 (游戏:八皇后问题)
代码示例
代码解析
输出结果
使用文件
题目:**18.34 (游戏:八皇后问题)
八皇后问题是要找到一个解决方案,将一个皇后棋子放到棋盘上的每行中,并且两个皇后棋子之间不能相互攻击。编写个程序,使用递归来解决八皇后问题,并如图18-17显示结果
-
代码示例
编程练习题18_34EightQueens.java
package chapter_18;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class 编程练习题18_34EightQueens extends Application{
private static final int SIZE = 8;
private int[] queens = new int[SIZE];
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
search(0);
ChessBoard board = new ChessBoard();
Scene scene = new Scene(board,250,250);
primaryStage.setTitle("编程练习题18_34EightQueens");
primaryStage.setScene(scene);
primaryStage.show();
board.paint();
}
private boolean isValid(int row,int col){
for(int i = 1;i <= row;i++) {
if(queens[row-i] == col
||queens[row-i] == col-i
||queens[row-i] == col+i)
return false;
}
return true;
}
private boolean search(int row) {
if(row == SIZE)
return true;
for(int col = 0;col < SIZE;col++) {
queens[row] = col;
if(isValid(row, col)&&search(row+1))
return true;
}
return false;
}
private class ChessBoard extends Pane{
Image queenImage = new Image("src/Image/queen03.png");
public void paint() {
this.getChildren().clear();
for(int i = 0;i < SIZE ;i++) {
ImageView imageView = new ImageView(queenImage);
this.getChildren() .add(imageView);
int j = queens[i];
imageView.setX(j*getWidth()/SIZE);
imageView.setY(i*getHeight()/SIZE);
imageView.setFitWidth(getWidth()/SIZE);
imageView.setFitHeight(getHeight()/SIZE);
}
for(int i =1;i <= SIZE;i++) {
this.getChildren().add(new Line(
0,i*getHeight()/SIZE,getWidth(),i*getHeight()/SIZE));
this.getChildren().add(new Line(
i*getWidth()/SIZE,0,i*getWidth()/SIZE,getHeight()));
}
}
}
}
-
代码解析
- 类定义与初始化:
编程练习题18_34EightQueens
类继承自Application
,是JavaFX应用程序的入口。- 定义了一个静态常量
SIZE
表示棋盘大小(8x8)。 - 定义了一个整型数组
queens
用于存储每一行皇后的列位置。
main
方法:- 调用
Application.launch(args);
启动JavaFX应用程序。
- 调用
start
方法:- 首先调用
search(0);
方法尝试找到一个解决方案(但不直接处理结果,因为此调用只是为了触发搜索)。 - 创建
ChessBoard
类的实例,该实例将用于绘制棋盘和皇后。 - 设置JavaFX场景并展示舞台。
- 调用
board.paint();
方法绘制棋盘和皇后。
- 首先调用
search
方法:- 使用回溯算法尝试在每一行放置一个皇后,直到所有行都被填满或无法继续放置。
- 通过
isValid
方法检查放置皇后的位置是否合法。 - 如果成功找到解决方案(即所有行都被填满),则返回
true
。
isValid
方法:- 检查当前位置
(row, col)
是否与之前的任何皇后冲突。 - 冲突条件包括:同一列、主对角线和副对角线。
- 检查当前位置
ChessBoard
类:- 继承自
Pane
,用于绘制棋盘和皇后。 - 在
paint
方法中,首先清除之前的子节点(如果有的话)。 - 然后,根据
queens
数组中的位置,在棋盘上绘制皇后。 - 绘制棋盘线,包括横线和竖线,以分隔棋盘格子。
- 继承自
-
输出结果
-
使用文件