0

我的任务是编写一个简单的游戏,模拟两名玩家接连进行 1-3 场比赛,直到牌堆消失。我设法让计算机选择随机匹配的值,但现在我想更进一步,让人类玩游戏。这是我已经拥有的:http: //paste.pocoo.org/show/200660/

类 Player 是一个电脑玩家,而 PlayerMan 应该是人类。问题是,PlayerMan 的线程应该等到给出正确的匹配值,但我不能让它以这种方式工作。当我输入值时,它有时会捕获它们并减少匹配的数量,但这并不是我所要做的:) 逻辑是:我检查当前玩家的价值。如果它对应于当前活动的线程,我使用扫描仪来捕捉匹配的数量。否则我等待一秒钟(我知道这有点苛刻,但我不知道该怎么做)。
共享类保留当前玩家的价值,以及匹配的数量。

顺便说一句,有什么方法可以让 Player 和 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();
        }
    }
}
4

1 回答 1

1

You should synchronize with reader/writer locks. EDIT: On a second thought, perhaps a simple condition should be enough. You could use something like this:

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();
}

The only problem here is that you may block both threads waiting for their conditions if data.which is not properly initialized when they get here. You should make sure it is initialized before starting their threads.

于 2010-04-12T01:50:43.120 回答