我有一个任务是编写简单的游戏,模拟两个玩家一个接一个地拿起1-3个匹配,直到堆消失。我设法为计算机选择匹配的随机值,但现在我想进一步让人类玩游戏。这是我已经拥有的:http://paste.pocoo.org/show/200660/
Class Player是一个电脑玩家,而PlayerMan应该是人类。问题是,PlayerMan的线程应该等到匹配的正确值,但我不能让它以这种方式工作。当我键入值时,它有时会捕获它们并减少匹配量但这不完全是我的目标:)逻辑是:我检查当前播放器的值。如果它对应于当前活动的线程,我使用scanner来捕获匹配的数量。否则我等一秒钟(我知道这是一种苛刻的解决方案,但我不知道该怎么做)。
Class Shared保留当前玩家的值以及匹配数量。
顺便说一下,有什么方法可以让播放器和共享属性变为私有而不是公开,并且仍能使代码工作?
CONSOLE和INPUT-DIALOG仅用于选择插入值的方式。
class PlayerMan extends Player{
static final int CONSOLE=0;
static final int INPUT_DIALOG=1;
private int input;
public PlayerMan(String name, Shared data, int c){
super(name, data);
input = c;
}
@Override
public void run(){
Scanner scanner = new Scanner(System.in);
int n = 0;
System.out.println("Matches on table: "+data.matchesAmount);
System.out.println("which: "+data.which);
System.out.println("number: "+number);
while(data.matchesAmount != 0){
if(number == data.which){
System.out.println("Choose amount of matches (from 1 to 3): ");
n = scanner.nextInt();
if(data.matchesAmount == 1){
System.out.println("There's only 1 match left !");
while(n != 1){
n = scanner.nextInt();
}
}
else{
do{
n = scanner.nextInt();
}
while(n <= 1 && n >= 3);
}
data.matchesAmount = data.matchesAmount - n;
System.out.println(" "+
name+" takes "+n+" matches.");
if(number != 0){
data.which = 0;
}
else{
data.which = 1;
}
}
else{
try {
Thread.sleep(1000);
} catch(InterruptedException exc) {
System.out.println("End of thread.");
return;
}
}
System.out.println("Matches on table: "+data.matchesAmount);
}
if(data.matchesAmount == 0){
System.out.println("Winner is player: "+name);
stop();
}
}
}
答案 0 :(得分:1)
您应该与读取器/写入器锁同步。 编辑:再想一想,也许一个简单的条件就足够了。你可以使用这样的东西:
private Lock playerLock = new ReentrantLock();
private Condition[] playerConditions = { playerLock.newCondition(), playerLock.newCondition() };
// Later on:
while (data.matchesAmount != 0) {
while (number != data.which) {
playerConditions[number].await();
}
// do work here
// now release the other player -- this assumes there are only 2
data.which = 1 - number;
playerConditions[1 - number].signalAll();
}
这里唯一的问题是,如果data.which
在到达时未正确初始化,则可以阻止两个线程等待其条件。你应该确保在开始他们的线程之前初始化它。