java - 我应该如何让我的 getMove() 方法与我的国际象棋应用程序中的 GUI 交互?
问题描述
我正在用 Java 开发一个应用程序,以帮助我找到作为初级开发人员的第一份工作。这是一个带有图形用户界面的国际象棋游戏,两个人类玩家都可以从同一台机器上点击。
例如,当轮到白方移动时,应用程序调用白方的getMove(Interface interaction)
方法,直到返回有效值MoveAttempt
。getMove(Interface interaction)
方法如下HumanPlayer
:
public MoveAttempt getMove(Interface interaction) {
while(!interaction.selectionMade()) {
}
byte pieceFile = interaction.getPenultimateFile();
byte pieceRank = interaction.getPenultimateRank();
byte toFile = interaction.getUltimateFile();
byte toRank = interaction.getUltimateRank();
return new MoveAttempt(pieceFile, pieceRank, toFile, toRank, getIsWhite());
}
penultimateFile
, penultimateRank
,ultimateFile
并且ultimateRank
应该存储最后点击的两个棋子的文件(列)和排名(行)。这是通过 this actionPerformed(ActionEvent event)
which Interface
has 实现的,因为它实现了ActionListener
public void actionPerformed(ActionEvent event) {
LocalizedButton button = (LocalizedButton) event.getSource();
if(penultimateFile == -1) {
penultimateFile = button.getFile();
penultimateRank = button.getRank();
}
else {
ultimateFile = button.getFile();
ultimateRank = button.getRank();
}
}
并在每次调用之前调用此方法getMove(Interface interaction)
public void resetClicks() {
penultimateFile = -1;
penultimateRank = -1;
ultimateFile = -1;
ultimateRank = -1;
}
所以这个想法是,直到有人点击了两个国际象棋方格才进行移动尝试,这就是为什么我有一个 while 循环无限期地调用selectionMade()
:
public boolean selectionMade() {
return penultimateFile != -1 && penultimateRank != -1 && ultimateFile != -1 && ultimateRank != -1;
}
这不起作用——碎片没有移动——所以为了看看发生了什么,我把这个打印声明
System.out.println(interaction.getPenultimateFile() + ", " +
interaction.getPenultimateRank() + ", " +
interaction.getUltimateFile() + ", " +
interaction.getUltimateRank());
进入while循环以查看发生了什么,现在它可以工作了——碎片移动——除了我可能遇到过它不起作用的时候,但我最后一次尝试我无法让它失败。
我不想在控制台上打印任何东西;我应该做什么来代替这个while循环?
编辑:放在boolean lol = 0
循环上方和lol = !lol
循环中不允许代码工作。调用也不行doNothing()
。
编辑:这是源代码:https ://github.com/JosephBGriffith/Chess 现在只有棋子可以工作,因为我还有其他需要修复的错误。En passant 作品,除了对手的棋子没有被淘汰。
解决方案
我会反转控件,以便 UI 将动作推送到游戏,而不是游戏试图从 UI 中提取动作。
所以你的游戏课可能有:
class Game {
boolean move(int fromFile, int fromRank, int toFile, int toRank) { ... }
...
}
如果移动不合法(例如,如果轮到其他玩家)则move
返回 false 并且移动不会发生。也就是说,游戏的内部状态是不变的。
你的actionPerformed
方法变成:
public void actionPerformed(ActionEvent event) {
LocalizedButton button = (LocalizedButton) event.getSource();
if(penultimateFile == -1) {
penultimateFile = button.getFile();
penultimateRank = button.getRank();
}
else {
game.move(penultimateFile, penultimateRank, button.getFile(), button.getRank());
penultimateFile = -1;
}
}
如果移动是非法的,您可以使用的返回值move
向用户提供一些反馈。
关于这个建议需要注意的是,它move
是在 Swing 事件线程上执行的。从理论上讲,这是不好的做法,尽管除非您的move
方法非常慢,否则这无关紧要。
阅读https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html并考虑是否要使用invokeLater
.
推荐阅读
- javascript - 如何将“string[]”类型的数组分配给“[string, ...string[]]”类型的非空数组
- javascript - 当其中一个更改时匹配两个 textarea 元素的大小
- java - 我有 Java 地图
> 和 String var,如何在不使用 For 循环的情况下返回其值(列表)包含 String var 的键 - cordova - 在 Cordova 中加载之前预渲染 html 文件
- java - 如何在 Android Java ListView 中使用 Viewbinding
- xpath - XPath:获取父元素包含文本的下一个元素
- laravel - PM2 如何在一个目录中启动多个进程 artisan laravel?
- python - 使用 panda 批量处理数据后 Excel 文件损坏
- digital-ocean - Digital Ocean:抱歉,我们在您的仓库中找不到应用
- php - 带有 fwrite 的 CRLF