我正在开发一个基于Java的小型游戏,我正在尝试通过玩家1发射导弹,直到玩家1不会错过目标,一旦玩家1错过了目标,那么火燕将移至玩家2,玩家-2将开始射击,直到他错过目标为止,反之亦然。
Player-1和Player-2都是Java Runnable
任务,请找到以下代码:
public class GameRender implements IGame {
private Game game;
private Player player1, player2;
private Lock lock = new ReentrantLock();
Condition notPlayer1TernCondition = lock.newCondition();
Condition notPlayer2TernCondition = lock.newCondition();
public GameRender(Game game, Player player1, Player player2) {
this.game = game;
this.player1 = player1;
this.player2 = player2;
}
@Override
public void create() {
}
@Override
public void render() {
//ExecutorService executorService = Executors.newFixedThreadPool(2);
Player1Task plater1 = new Player1Task(player1.getTargetLocations(), true);
Player2Task plater2 = new Player2Task(player2.getTargetLocations(), false);
Thread t1 = new Thread(plater1);
Thread t2 = new Thread(plater2);
t1.start();
t2.start();
}
@Override
public void over() {
}
class Player1Task implements Runnable {
private List<TargetLocation> playerOnesTargetLocationList;
private boolean isHitTarget = false;
private int fireCount = 0;
private boolean yourTern;
Player1Task(List<TargetLocation> playerOnesTargetLocationList, boolean yourTern) {
this.playerOnesTargetLocationList = playerOnesTargetLocationList;
this.yourTern = yourTern;
}
@Override
public void run() {
try {
lock.lock();
fire();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
private void fire() throws InterruptedException {
while (fireCount != playerOnesTargetLocationList.size()) {
if (!yourTern) {
notPlayer1TernCondition.await();
}
TargetLocation location = playerOnesTargetLocationList.get(fireCount);
if (player2.getOwnField().hasShip(location.getxPos(), location.getyPos())) {
} else {
System.out.println("Player-1 else");
yourTern = false;
notPlayer2TernCondition.signalAll();
}
fireCount++;
}
}
}
class Player2Task implements Runnable {
private List<TargetLocation> playerTwosTargetLocationList;
private boolean isHitTarget = false;
private int fireCount = 0;
private boolean yourTern;
Player2Task(List<TargetLocation> playerTwosTargetLocationList, boolean youTern) {
this.playerTwosTargetLocationList = playerTwosTargetLocationList;
this.yourTern = youTern;
}
@Override
public void run() {
lock.lock();
try {
fire();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
private void fire() throws InterruptedException {
while (fireCount != playerTwosTargetLocationList.size()) {
if (!yourTern) {
notPlayer2TernCondition.await();
}
TargetLocation location = playerTwosTargetLocationList.get(fireCount);
if (player1.getOwnField().hasShip(location.getxPos(), location.getyPos())) {
} else {
System.out.println("p2 else");
yourTern = false;
notPlayer1TernCondition.signalAll();
}
fireCount++;
}
}
}
}
上面的代码没有按预期运行,第一次Player-1执行并且代码卡住之后。
任何解释都值得赞赏。
答案 0 :(得分:1)
您永远不会将您的燕鸥设置回true。 (可以使用表示哪个球员转牌的共享变量)
说明:
假定最初Player1具有锁定并在Player1的yourTern为true时触发。假设它未命中,那么您将向Player2(尚未等待)发出信号,并将yourTern设置为false并释放锁(通过在下一次迭代中调用notPlayer1TernCondition.await()
方法) )。
Player2将获得此锁定,并且由于yourTern为false,因此它将调用notPlayer2TernCondition.await()
。
两个线程现在都将永远进入等待状态。