0

私はJavaでチェスプログラムを書いています。これまでのところ順調に進んでいますが、UI の更新に問題があります。

以下は、JPanel を拡張するクラス ChessBoard のコード スニペットです。これは、ユーザーが移動しようとすると呼び出されます。

if ( isLegalMove( aMove ) ) { // If the move's legal
    makeMove( aMove ); // Make that move
    select = null; // Reset some info
    drag = null;
    toggleTurn(); // Change turns
    generateMoves( 0 ); // Get legal moves for CPU
    repaint(); // Redraw board
    thread.run(); // Run chess algorithm
}

スレッドは、ChessBoard のインスタンスで "run" を呼び出しています。動きを見つけるアルゴリズムは、動きを決定するのに数秒かかる場合があります。

ユーザーの動きを反映するように UI を更新してから、アルゴリズムを実行したいと考えています。そのため、別のスレッドでアルゴリズムを実行します。しかし、私の UI は、コンピューターも動き出すまで更新されません。

したがって、ユーザーがスペースをクリックしてそこにピースを送ると、画面がフリーズし、突然ピースが移動しましたが、コンピューターも移動し、再びプレーヤーの番になります。

どんな助けでも大歓迎です。

4

2 に答える 2

4

thread.run()現在のスレッドでスレッドの run メソッドのコードを実行します。あなたがしたいthread.start()

関連する JavaDoc

repaint メソッドは、実際にはすぐには再描画しません。基本的に、JPanel に、すぐに自分自身を再描画する必要があることを伝えます。次に、同じスレッドに進み、AI の動きを計算します。Swing はマルチスレッドではないため、ウィンドウがフリーズします。

于 2012-08-30T01:25:37.820 に答える
1

まず、スレッドは再入可能ではありません (これについては後で説明します)。

thread.run()スレッドを別のスレッドで実行させるのではなく、スレッドのrunメソッドを呼び出すだけです (現在Threadの s コンテキスト内)。

あなたがする必要があるのはThread、必要なロジックを実行するためにトリガーできる条件ループを設定することです。

public class ChessThread extends Thread { // I prefer Runnable, that's me
    protected static final Object NEXT_MOVE_LOCK = Object();

    public ChessThread() {
        setDaemon(true); // This will allow the JVM to exit without the need to terminate the thread...
    }

    public void doNextMove() {
        // Notify the "wait" that we want to continue calculating the next move
        synchronized (NEXT_MOVE_LOCK) {
            NEXT_MOVE_LOCK.notify();
        }
    }       

    public void run() { 
        while (true) {
            // Wait for the "next move" request
            synchronized (NEXT_MOVE_LOCK) {
                try {
                    NEXT_MOVE_LOCK.wait();
                } catch (InterruptedException exp) {
                }
            }
            // Calculate the next move...
        }
    }
}

現在、Threadは再入不可です。これは、run メソッドが完了すると、 のインスタンスをThread再起動できないことを意味します。

したがって、thread.start()複数回使用しても機能しません(例外がスローされるかどうかを思い出せません)(したがって、私が好む理由Runnable

そう。あなたがしたいことは、Threadプログラムがロードされたときに開始し、必要なときに呼び出して、必要なthread.doNextMove()ものを計算させることです。

さて、安全でSwingはないことも覚えておいてください。Threadつまり、イベント ディスパッチ スレッド(または EDT)Thread以外から UI を更新しないでください。

また、Swing での同時実行を読みたいと思うかもしれません。

ああ、Java の並行性

于 2012-08-30T01:33:50.517 に答える