javafx实现农夫过河问题
时间: 2023-11-07 11:04:47 浏览: 111
农夫过河问题是一道经典的人工智能问题,它可以通过图搜索算法来解决。在JavaFX中实现这个问题,可以通过以下步骤:
1. 创建一个界面,包含河岸、船和农夫、狼、羊、菜等元素。
2. 使用JavaFX的事件处理器,实现点击元素后的相应动作,例如点击农夫,可以让他移动到船上。
3. 设计状态类,记录当前状态下的元素位置和状态,使用图搜索算法寻找最优解。
4. 使用JavaFX的动画效果,实现元素的平移、旋转等动作,使界面更加生动。
参考代码如下:
```java
public class Main extends Application {
private Group root = new Group();
private ImageView farmer = new ImageView(new Image(getClass().getResourceAsStream("/images/farmer.png")));
private ImageView wolf = new ImageView(new Image(getClass().getResourceAsStream("/images/wolf.png")));
private ImageView sheep = new ImageView(new Image(getClass().getResourceAsStream("/images/sheep.png")));
private ImageView cabbage = new ImageView(new Image(getClass().getResourceAsStream("/images/cabbage.png")));
private ImageView boat = new ImageView(new Image(getClass().getResourceAsStream("/images/boat.png")));
private boolean farmerOnLeftBank = true;
private boolean wolfOnLeftBank = true;
private boolean sheepOnLeftBank = true;
private boolean cabbageOnLeftBank = true;
private boolean isMoving = false;
private List<State> path = new ArrayList<>();
private int currentIndex = 0;
@Override
public void start(Stage primaryStage) throws Exception{
root.getChildren().addAll(
new ImageView(new Image(getClass().getResourceAsStream("/images/left_bank.png"))),
new ImageView(new Image(getClass().getResourceAsStream("/images/right_bank.png"))),
farmer,
wolf,
sheep,
cabbage,
boat
);
farmer.setTranslateX(70);
farmer.setTranslateY(250);
wolf.setTranslateX(170);
wolf.setTranslateY(250);
sheep.setTranslateX(270);
sheep.setTranslateY(250);
cabbage.setTranslateX(370);
cabbage.setTranslateY(250);
boat.setTranslateX(530);
boat.setTranslateY(250);
primaryStage.setTitle("Farmer Crossing River");
primaryStage.setScene(new Scene(root, 700, 400));
primaryStage.show();
root.setOnMouseClicked(event -> {
if (isMoving) {
return;
}
double x = event.getX();
double y = event.getY();
if (x >= 530 && x <= 630 && y >= 250 && y <= 320) {
// 点击船
if (farmerOnLeftBank && !wolfOnLeftBank && !sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着狼过河
move(farmer, 570, 200, 570, 250);
move(wolf, 670, 200, 670, 250);
wolfOnLeftBank = false;
} else if (farmerOnLeftBank && wolfOnLeftBank && !sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着狼回到左岸
move(farmer, 570, 200, 70, 250);
move(wolf, 670, 200, 170, 250);
farmerOnLeftBank = true;
wolfOnLeftBank = true;
} else if (farmerOnLeftBank && !wolfOnLeftBank && sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着羊过河
move(farmer, 570, 200, 570, 250);
move(sheep, 470, 200, 470, 250);
sheepOnLeftBank = false;
} else if (!farmerOnLeftBank && !wolfOnLeftBank && sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着空船回到左岸
move(farmer, 570, 300, 70, 250);
farmerOnLeftBank = true;
} else if (!farmerOnLeftBank && !wolfOnLeftBank && !sheepOnLeftBank && cabbageOnLeftBank) {
// 农夫带着菜过河
move(farmer, 570, 300, 570, 250);
move(cabbage, 370, 200, 370, 250);
cabbageOnLeftBank = false;
} else if (!farmerOnLeftBank && wolfOnLeftBank && !sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着狼和菜过河
move(farmer, 570, 300, 570, 250);
move(wolf, 470, 200, 470, 250);
move(cabbage, 270, 200, 270, 250);
wolfOnLeftBank = false;
cabbageOnLeftBank = false;
} else if (!farmerOnLeftBank && !wolfOnLeftBank && sheepOnLeftBank && cabbageOnLeftBank) {
// 农夫带着羊和菜回到左岸
move(farmer, 570, 300, 70, 250);
move(sheep, 370, 200, 370, 250);
move(cabbage, 270, 200, 270, 250);
farmerOnLeftBank = true;
sheepOnLeftBank = true;
cabbageOnLeftBank = true;
} else if (!farmerOnLeftBank && wolfOnLeftBank && sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着狼回到左岸
move(farmer, 570, 300, 70, 250);
move(wolf, 470, 200, 170, 250);
farmerOnLeftBank = true;
wolfOnLeftBank = true;
}
}
});
}
private void move(ImageView imageView, double fromX, double fromY, double toX, double toY) {
isMoving = true;
Path path = new Path();
path.getElements().add(new MoveTo(fromX, fromY));
path.getElements().add(new LineTo(toX, toY));
PathTransition pathTransition = new PathTransition(Duration.millis(1000), path, imageView);
pathTransition.setCycleCount(1);
pathTransition.setAutoReverse(false);
pathTransition.setOnFinished(event -> isMoving = false);
pathTransition.play();
}
private void findPath() {
State initialState = new State(farmerOnLeftBank, wolfOnLeftBank, sheepOnLeftBank, cabbageOnLeftBank, true, null);
List<State> visited = new ArrayList<>();
Queue<State> queue = new LinkedList<>();
queue.offer(initialState);
while (!queue.isEmpty()) {
State currentState = queue.poll();
visited.add(currentState);
if (currentState.isGoalState()) {
// 找到了解
path.clear();
while (currentState != null) {
path.add(currentState);
currentState = currentState.getPreviousState();
}
currentIndex = path.size() - 1;
break;
}
for (State nextState : currentState.getNextStates()) {
if (!visited.contains(nextState) && !queue.contains(nextState)) {
queue.offer(nextState);
}
}
}
}
public static void main(String[] args) {
launch(args);
}
}
class State {
private boolean farmerOnLeftBank;
private boolean wolfOnLeftBank;
private boolean sheepOnLeftBank;
private boolean cabbageOnLeftBank;
private boolean boatOnLeftBank;
private State previousState;
public State(boolean farmerOnLeftBank, boolean wolfOnLeftBank, boolean sheepOnLeftBank, boolean cabbageOnLeftBank, boolean boatOnLeftBank, State previousState) {
this.farmerOnLeftBank = farmerOnLeftBank;
this.wolfOnLeftBank = wolfOnLeftBank;
this.sheepOnLeftBank = sheepOnLeftBank;
this.cabbageOnLeftBank = cabbageOnLeftBank;
this.boatOnLeftBank = boatOnLeftBank;
this.previousState = previousState;
}
public boolean isGoalState() {
return !farmerOnLeftBank && !wolfOnLeftBank && !sheepOnLeftBank && !cabbageOnLeftBank;
}
public List<State> getNextStates() {
List<State> nextStates = new ArrayList<>();
if (farmerOnLeftBank && !wolfOnLeftBank && !sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着狼过河
nextStates.add(new State(false, false, sheepOnLeftBank, cabbageOnLeftBank, false, this));
} else if (farmerOnLeftBank && wolfOnLeftBank && !sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着狼回到左岸
nextStates.add(new State(false, true, sheepOnLeftBank, cabbageOnLeftBank, false, this));
} else if (farmerOnLeftBank && !wolfOnLeftBank && sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着羊过河
nextStates.add(new State(false, wolfOnLeftBank, false, cabbageOnLeftBank, false, this));
} else if (!farmerOnLeftBank && !wolfOnLeftBank && sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着空船回到左岸
nextStates.add(new State(true, wolfOnLeftBank, sheepOnLeftBank, cabbageOnLeftBank, true, this));
} else if (!farmerOnLeftBank && !wolfOnLeftBank && !sheepOnLeftBank && cabbageOnLeftBank) {
// 农夫带着菜过河
nextStates.add(new State(true, wolfOnLeftBank, sheepOnLeftBank, false, false, this));
} else if (!farmerOnLeftBank && wolfOnLeftBank && !sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着狼和菜过河
nextStates.add(new State(true, false, sheepOnLeftBank, false, false, this));
} else if (!farmerOnLeftBank && !wolfOnLeftBank && sheepOnLeftBank && cabbageOnLeftBank) {
// 农夫带着羊和菜回到左岸
nextStates.add(new State(true, wolfOnLeftBank, false, false, true, this));
} else if (!farmerOnLeftBank && wolfOnLeftBank && sheepOnLeftBank && !cabbageOnLeftBank) {
// 农夫带着狼回到左岸
nextStates.add(new State(true, true, sheepOnLeftBank, cabbageOnLeftBank, true, this));
}
return nextStates;
}
public State getPreviousState() {
return previousState;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
State state = (State) obj;
return farmerOnLeftBank == state.farmerOnLeftBank &&
wolfOnLeftBank == state.wolfOnLeftBank &&
sheepOnLeftBank == state.sheepOnLeftBank &&
cabbageOnLeftBank == state.cabbageOnLeftBank &&
boatOnLeftBank == state.boatOnLeftBank;
}
@Override
public int hashCode() {
return Objects.hash(farmerOnLeftBank, wolfOnLeftBank, sheepOnLeftBank, cabbageOnLeftBank, boatOnLeftBank);
}
}
```
上述代码实现了农夫过河问题的界面和状态类,使用了JavaFX的动画效果和图搜索算法。需要注意的是,农夫过河问题有多种解法,上述代码只实现了其中一种解法,可以根据实际需要进行修改。
阅读全文