gpt4 book ai didi

java - 线程等待用户单击某些内容

转载 作者:行者123 更新时间:2023-12-01 18:56:35 26 4
gpt4 key购买 nike

我正在准备玩五子棋的应用程序。

我已经创建了漂亮的 GUI,现在我正在与核心引擎战斗。

有一个类GameEngine,它具有同步方法来进行移动。还有一些实现 IClient 接口(interface)的类,它们是“玩家”。首先要做的是实现 PlayerClient,它连接到 BoardPanel,并在 BoardPanel 中的 MouseListener 时移动(代表五子棋盘)说。我希望我的应用程序能够开放以实现计算机播放器。这就是为什么它如此复杂。

所以...问题:我的 GameEngine 类如下所示:

public class GameEngine {
private IClient blackPlayer;
private IClient whitePlayer;
private GameState gameState;

...

public void play() {
blackPlayer.run();
whitePlayer.run();
}

public synchronized void move(Move move) throws IllegalMoveException {
gameState.move(move);
if (move.isBlackMove()){
whitePlayer.notify();
}else{
blackPlayer.notify();
}
}

public synchronized void waitForYourTurn(boolean color){
try {
while (gameState.isBlackToMove()!=color) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

我的 Client 类有 run() 方法:

@Override
public void run() {
while (gameState.getWinner() == 0) {
move = null;
boolean moved = false;
while (!moved) {
gameEngine.waitForYourTurn(black);
try {
//waitForPickedMove();
gameEngine.move(move);
moved = true;
} catch (IllegalMoveException e) {
e.printStackTrace();
}
}
}
}

在我写“//waitForPickedMove()”的地方,客户端应该等待用户单击板上的正确位置。所以...我的 Board 类中有一个 MouseListener:

private class MoveMouseListener implements MouseListener {
@Override
public synchronized void mouseReleased(MouseEvent e) {
if (gameState == null) {
return;
}

if (currentMove != null) {
movePicked();
repaint();
}
}
}

currentMove 当然是用户通过点击棋盘选择的移动。虽然 movePicked() 看起来像这样:

private synchronized void movePicked() {
if (gameState.isBlackToMove() && blackClient != null) {
blackClient.notify();
clearCurrentMove();
}
if (!gameState.isBlackToMove() && whiteClient != null) {
whiteClient.notify();
clearCurrentMove();
}
}

我尝试在很多地方放置wait()。我尝试反向控制并将其放入 Board 类中,因此它调用了 Client 类中的方法(setCurrentMove(Move move))。不幸的是我无法达到我想要的。我总是收到 IllegalMonitorStateException 或我的 GUI block 。

我希望我已经充分解释了我的问题。如果有任何帮助,我将不胜感激。

编辑:

public class MockComputerClient implements IClient {
private GameState gameState;
private GameEngine gameEngine;
private boolean black;
private ExecutorService executorService;
private boolean myTurn = false;
private int i = 3;

public MockComputerClient(GameEngine gameEngine, GameState gameState,
boolean black) {
this.gameEngine = gameEngine;
this.gameState = gameState;
this.black = black;
executorService = new ExecutorService();
executorService.run();
}

@Override
public void enemyMoved() {
myTurn = true;
executorService.notify();
}

private class ExecutorService implements Runnable {

@Override
public void run() {
while (gameState.getWinner() == 0) {
try {
while (!myTurn) {
wait();
}
// Hardcoded Moves
gameEngine.move(new Move(black, 3, i++));
myTurn = false;
} catch (InterruptedException | IllegalMoveException e) {
e.printStackTrace();
}
}
}
}

}

我很确定我应该同步某件事,但我真的不知道同步什么。

编辑2:

@Override
public void enemyMoved() {
myTurn = true;
executorService.move();
}

private class ExecutorService implements Runnable {

@Override
public void run() {
while (gameState.getWinner() == 0) {
System.out.println("Calculating: j= " + j);
if (j == 3)
j = 4;
else
j = 3;

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}

public void move() {
while (myTurn) {
try {
gameEngine.move(new Move(black, j, i++));
myTurn = false;
} catch (IllegalMoveException e) {
e.printStackTrace();
}
}
}

}

最佳答案

游戏引擎不需要一直占用一个线程,在无事可做时阻塞它。您应该将其重新设计为响应式:当事件处理程序正在执行的线程中有事件时,代码就会执行。那么您将不需要任何wait-notify机制。

如果您希望让 Player 实现在不占用调用线程的情况下慢慢来,请在设计 API 时考虑异步性:IClient 将有一个表示“其他玩家已移动”的方法,该方法表示“其他玩家已移动”。不会立即返回玩家的移动。 IClient 将通过其移动来调用游戏引擎上的方法。

关于java - 线程等待用户单击某些内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13759437/

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