gpt4 book ai didi

java - 打破听众的递归

转载 作者:行者123 更新时间:2023-11-30 02:48:35 25 4
gpt4 key购买 nike

我正在尝试打破使该代码递归的特殊情况。

我有一个 Javafx 游戏,其中有人类和计算机玩家,轮到他的时候玩,并且可以有很多轮。

计算机应该自动播放并立即移动到下一个播放器,并且不会向用户界面显示直接指示(但可以在之后查看它做了什么)。

问题是在只有电脑玩家的情况下,我们会在加载currentBoardPane的时候来到这里,输入条件,因为所有玩家都是电脑,设置下一个玩家的棋盘,然后在没有完成调用的情况下再次调用相同的函数:

    currentBoardPane.addListener((e) -> {  
if(gameManager.checkIfCurrentPlayerIsComputer()){

gameManager.playAutoMovesForCurrentPlayer();
gameManager.setNextPlayer(); // it does current player property = next player

//update board on scene
currentBoardPaneIndex = ((currentBoardPaneIndex + 1) % gameManager.getPlayers().size());
currentBoardPane.setValue(boardPanes.get((currentBoardPaneIndex))); //this is a recursive call
}
});

相反,如果我在 GameManager 中订阅 currentPlayer 属性的监听器,那么我仍然需要从中调用 setNextPlayer()再次递归的监听器。

如果所有玩家都是计算机,我可以做一个特例,然后从 while(true){} 运行游戏,而不是监听器和绑定(bind),但必须有更好的方法来打破这个递归。

有没有办法在仍然有监听器和绑定(bind)的情况下不进入递归?

注释:

currentBoardPane 表示屏幕上当前的游戏板,它是一个 ObjectProperty

最佳答案

对您的代码做出以下假设:

  1. 所有内容当前都在 FX 应用程序线程上运行
  2. currentBoardPane.setValue(...) 导致 UI 更新(因此每次移动都会更新 UI)

那么“快速而肮脏”的方法是:

currentBoardPane.addListener((e) -> {  
if(gameManager.checkIfCurrentPlayerIsComputer()){

gameManager.playAutoMovesForCurrentPlayer();

//update board on scene
Platform.runLater(() -> {
gameManager.setNextPlayer(); // it does current player property = next player
currentBoardPaneIndex = ((currentBoardPaneIndex + 1) % gameManager.getPlayers().size());
currentBoardPane.setValue(boardPanes.get((currentBoardPaneIndex))); //this is a recursive call
});
}
});

这会将更新委托(delegate)给新的Runnable,安排该runnable在FX应用程序线程上执行,并立即退出处理程序。因此,对 currentBoardPane.setValue(...) 的调用稍后执行,并且不再递归。

事实上,如果您多做一点工作:

private final Executor aiExecutor = Executors.newSingleThreadExecutor();

// ...

currentBoardPane.addListener((e) -> {
if(gameManager.checkIfCurrentPlayerIsComputer()){

Task<Void> makeMoveTask = new Task<Void>() {
@Override
protected Void call() {
gameManager.playAutoMovesForCurrentPlayer();
return null ;
}
};

makeMoveTask.setOnSucceeded(e -> {

//update board on scene
gameManager.setNextPlayer(); // it does current player property = next player
currentBoardPaneIndex = ((currentBoardPaneIndex + 1) % gameManager.getPlayers().size());
currentBoardPane.setValue(boardPanes.get((currentBoardPaneIndex))); //this is a recursive call
});

aiExecutor.execute(makeMoveTask);
}
});

如果计算移动花费了足够的时间,以至于在移动发生时阻止 UI 是 Not Acceptable ,那么这正是您将使用的代码。 (如果计算移动需要很少的时间,这仍然可以正常工作。)这假设 playAutoMovesForCurrentPlayer() 不更新 UI。

关于java - 打破听众的递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39395942/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com