0

2人のプレイヤーが1〜3試合を次々と拾い上げ、山がなくなるまでシミュレートする簡単なゲームを書くタスクがありました。私はコンピューターがマッチのランダムな値を選択するためにそれを行うことができましたが、今はさらに進んで人間がゲームをプレイできるようにしたいと思います。これが私がすでに持っているものです:http://paste.pocoo.org/show/200660/

Class Playerはコンピュータープレーヤーであり、PlayerManは人間である必要があります。問題は、PlayerManのスレッドは、一致の適切な値が指定されるまで待機する必要があるということですが、このように機能させることはできません。値を入力すると、値がキャッチされて一致数が減少することがありますが、それは私が行っていたものとは異なります:)ロジックは:現在のプレーヤーの値をチェックします。現在アクティブなスレッドのこれに対応する場合は、スキャナーを使用して一致の量をキャッチします。それ以外の場合は、1秒待ちます(これはちょっと厳しい解決策だと思いますが、他に方法がわかりません)。
クラス共有は、現在のプレーヤーの価値と一致数を保持します。

ちなみに、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

リーダー/ライターロックと同期する必要があります。編集:考え直してみると、おそらく単純な条件で十分なはずです。次のようなものを使用できます。

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ここでの唯一の問題は、ここに到達したときに正しく初期化されていない場合、条件を待機している両方のスレッドをブロックする可能性があることです。スレッドを開始する前に、初期化されていることを確認する必要があります。

于 2010-04-12T01:50:43.120 に答える