2017-01-29 6 views
-1

乱数を生成するrunメソッドを実装し、getchoiceメソッドと生成された数値を返して実行を通知するgetchoiceメソッドを待機するPlayerクラス(runnableを実装する)を作成するように求められます。それぞれのプレーヤーオブジェクトを含む2つのスレッドを含むメソッド実行を含むRockPaperScissorsクラス(Runnableを実装する)は、これらの2つのスレッドを互いに1000回再生する必要があります。次に、それらを中断し、各プレーヤー勝った 。 。私の問題は、私のコードが実行を開始するときに、それは完璧ですが、ランダムなラウンドでは、ゲームの目的を敗北させるプレーヤー2に行く前に何度もプレーヤー1を再生し始めます:2つのスレッドを定期的に実行するには?

public class RockPaperScissors implements Runnable { 
int result1 ; 
int result2 ; 
int result3 ; 

private final Object lock = new Object(); 

public void run(){ 


    synchronized(lock){ 
     Player a = new Player() ; 
     Player b = new Player() ; 
    Thread a1 = new Thread(a) ; 
    Thread b1= new Thread (b) ; 
     a1.start(); 
     b1.start(); 
     int choice1 = -100 ; 
    int choice2 = -1066 ; 
    for (int i = 0 ; i < 1000 ; i++){ 



    try { 

     choice1 = a.getChoice();  
    } catch (InterruptedException e1) { 

    } 


    try { 

     choice2 = b.getChoice(); 

    } catch (InterruptedException e) { 

    } 
    if (choice1 == 1 && choice2==0) 
     result2++; 
    else if (choice2 == 1 && choice1==0) 
     result1++; 
    else if (choice1 == 1 && choice2==1) 
     result3++ ; 
    else if (choice1 == 1 && choice2==2) 
     result1++ ; 
    else if (choice1 == 2 && choice2==1) 
     result2++ ; 
    else if (choice1 == 0 && choice2==2) 
     result1++ ; 
    else if (choice1 == 2 && choice2==0) 
     result2++ ; 
    else if (choice1 == 2 && choice2==2) 
     result3++ ; 
    else if (choice1 == 0 && choice2==0) 
     result3++ ; 


    } 

と、このクラスのプレーヤーである:

public class Player implements Runnable { 
private final Object lockvalue = new Object(); 
private int a; 

public void run() { 
    synchronized (lockvalue) { 
     for (int counter = 0; counter < 1000; counter++) { 

      java.util.Random b = new java.util.Random(); 
      a = b.nextInt(3); 
      System.out.println(counter); 
      try { 
       lockvalue.wait(); 
      } catch (InterruptedException e) { 
       System.out.println("Thread player was interrupted"); 

      } 

     } 

    } 
} 

public int getChoice() throws InterruptedException { 
    synchronized (lockvalue) { 
     lockvalue.notify(); 
     return a; 

    } 

} 

}

私のプログラムの開発は完全にカウンター表示は常に1000に0から始まる番号を持つ必要があります実行されている場合

が次々に重複しますが、ここでそれはそのように始まりますが、その後、それは1000に達することは決してありません。時には700時には800時に停止することもあります。私が使用することが許されているのは、notify()、notifyAll()、wait()、start()、interrupt()そしてjoin()です。

あなたのご協力が大変ありがとうございます。おかげ

+0

のRunnableは唯一のゲームに勝利し、ないそれが演奏される何回かについての情報を持っている必要があります。 – duffymo

+0

RockPaperScissorsの実行可能ファイルを意味しますか? – Domarius

+1

はい。もし私があなただったら、2人のプレーヤーが完璧に働いているというゲームのロジックが出てくるまで、スレッドを忘れるだろう。一度それを持って、それをマルチスレッドにしてください。 – duffymo

答えて

1

あなたの実装とアプローチは、それがどのように機能するか、あなたは同時実行性を理解していないことを示して検討しますいつ適用されるべきか。 )(あなたがPlayer.getChoiseで復帰する前の待機は、通知1以上を追加する必要があなたのコードを動作させるためにhttp://www.mindview.net/Books/TIJ/

-

は、私はあなたがブルースEckel氏の「Javaで考える」の対応する章(並行処理)を読むことをお勧めします

RockPaperScissors.java

package game; 

public class RockPaperScissors 
{ 
    static int player1wins = 0; 
    static int player2wins = 0; 
    static int draw = 0; 

    public static void main(String[] args) throws InterruptedException 
    { 
    int cycles = 1000; 
    Player player1 = new Player("Player-1", cycles); 
    Player player2 = new Player("Player-2", cycles); 

    new Thread(player1).start(); 
    new Thread(player2).start(); 


    for (int i = 0; i < cycles; i++) 
    { 
     Choice choice1; 
     Choice choice2; 

     choice1 = player1.getChoice(); 
     System.out.println("Value 1 is definitely generated"); 

     choice2 = player2.getChoice(); 
     System.out.println("Value 2 is definitely generated"); 

     System.out.printf("\n%3d\nPlayer1 - %8s\nPlayer2 - %8s\n", i, choice1.name(), choice2.name()); 

     if (choice1 == choice2) 
     { 
     draw++; 
     System.out.println("Draw!"); 
     } 
     else if (choice1 == Choice.ROCK) 
     { 
     if (choice2 == Choice.PAPER) 
     { 
      player2wins++; 
      System.out.println("2 wins!"); 
     } 
     else 
     { 
      player1wins++; 
      System.out.println("1 wins!"); 
     } 
     } 
     else if (choice1 == Choice.PAPER) 
     { 
     if (choice2 == Choice.SCISSORS) 
     { 
      player2wins++; 
      System.out.println("2 wins!"); 
     } 
     else 
     { 
      player1wins++; 
      System.out.println("1 wins!"); 
     } 
     } 
     else if (choice1 == Choice.SCISSORS) 
     { 
     if (choice2 == Choice.ROCK) 
     { 
      player2wins++; 
      System.out.println("2 wins!"); 
     } 
     else 
     { 
      player1wins++; 
      System.out.println("1 wins!"); 
     } 
     } 
    } 
    System.out.printf("Player 1 wins - %3d times;\n" + 
     "Player 2 wins - %3d times;\n" + 
     "Draw result - %3d times\n\n", player1wins, player2wins, draw); 

    System.out.printf("Player-1 cycles left = %d\n" + 
     "Player-2 cycles left = %d\n", player1.getCounter(), player2.getCounter()); 
    } 
} 
:ここ

は固定バージョンです

Player.java

package game; 

import java.util.Random; 

public class Player implements Runnable 
{ 
    private Random random = new Random(); 
    private int value; 
    private int counter; 
    private String name; 

    public Player(String name, int cycles) 
    { 
    this.name = name; 
    this.counter = cycles; 
    } 

    public synchronized void run() 
    { 
    while (true) 
    { 
     try 
     { 
     wait(); 
     } 
     catch (InterruptedException e) 
     { 
     e.printStackTrace(); 
     } 

     value = random.nextInt(3); 
     System.out.println(name + " ... Value was generated = " + value); 
     notify(); 

     // Otherwise your thread will never stop! 
     counter--; 
     if (counter <= 0) 
     { 
     System.out.println(name + " ... Limit of operations is exceeded."); 
     break; 
     } 
    } 
    } 

    public synchronized Choice getChoice() throws InterruptedException 
    { 
    System.out.println(name + " ... now can generate value"); 
    notify(); 
    System.out.println(name + " ... wait until value is generated"); 
    wait(); 
    Choice choice = Choice.values()[value]; 
    System.out.println(name + " ... returning generated value: " + value); 
    return choice; 
    } 

    public int getCounter() 
    { 
    return counter; 
    } 
} 

Choise.java

package game; 

public enum Choice 
{ 
    ROCK, 
    PAPER, 
    SCISSORS; 
} 
+0

ありがとう、ありがとう。正確に私が探していたもの。 実行時にwhile(true)wait()ループを実行する必要があるのはなぜですか?なぜ私はゲッチョーで待たなければならないのですか? – Domarius

+0

whileループは(カウンタのために)あなたのforループと同じ仕事をしますが、私の視点から見るとより論理的です。 wait()はモニタを解放し、getChoiceを停止してrun()を実行させるため、次のランダム値の生成にはgetChoiceで待機する必要があります。あなたはそれをコメントアウトして何が起こるかを見ることができるので、簡単なログメッセージを追加しました。 – sergpank

関連する問題