首页 > 解决方案 > 我应该如何让我的 getMove() 方法与我的国际象棋应用程序中的 GUI 交互?

问题描述

我正在用 Java 开发一个应用程序,以帮助我找到作为初级开发人员的第一份工作。这是一个带有图形用户界面的国际象棋游戏,两个人类玩家都可以从同一台机器上点击。

例如,当轮到白方移动时,应用程序调用白方的getMove(Interface interaction)方法,直到返回有效值MoveAttemptgetMove(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 Interfacehas 实现的,因为它实现了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 作品,除了对手的棋子没有被淘汰。

标签: javamultithreadingswing

解决方案


我会反转控件,以便 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.


推荐阅读