2016-10-20 3 views
2

私はトーナメントのためのゲームプランを設定するアプリケーションをしようとしています。どのようにして分散でArrayListをランダム化できますか?

public List<Match> creerMatchsTousContreTous(List<Equipe> lEquipe) { 
     List<Match> lMatch = new ArrayList<>(); 
     for (int i = 0; i < lEquipe.size(); i++) { 
      for (int j = i + 1; j < lEquipe.size(); j++) { 
       Match match = new Match(); 
       match.setEquA(lEquipe.get(i)); 
       match.setEquB(lEquipe.get(j)); 
       lMatch.add(match); 
      } 
     } 
     return lMatch; 
    } 

この方法は、チームのリストをreceid:

は私が方法を持っています。それぞれが互いに遊ぶべきである。これは、プレイのリスト(Match)を返します。

私は今演劇をランダムにしたいです。最初のプレイをプレイするチームAが次のプレイをプレイしないことが必要です。そしてもっともっと。

私が使用します。演劇のリスト

Collections.shuffle(lMatch); 

しかし、それramdom、テマ、2つの連続したプレーを果たしている可能性があります。

どうすれば実現できますか? おかげ 敬具

EDIT:

例:

方法は、ゲームのリストを返す:

  1. TEAM 1:TEAM 2

  2. TEAM 2:TEAM 3

  3. TEAM 1:TEAM 3

  4. TEAM 4:TEAM 3

  5. TEAM 2:TEAM 4

  6. TEAM 4:この例ではTEAM 3

creerMatchsTousContreTous()リターン6つの値を持つリストしかしここでは、たとえば、第1ゲームでは、チーム2がプレーしています。第2ゲームでもプレーしていますが、そうであってはいけません。

答えて

0

私は、justPlayedやhasPlayedなどのブール変数をTeamクラスに追加することをお勧めします。この変数は、特定のチームがちょうどゲームでプレイしたかどうかを追跡します。

Collections.shuffle(lMatch); // get two random teams using shuffle 
while(Match.Team1.getHasPlayed() == True or Match.Team2.getHasPlayed() == True){ 
    Collections.shuffle(lMatch); // try to find different teams 
} 

lMatch.play(); // you've found two teams, so now you can call your play method 

for(Team t:lEquipe){    // go through the list of teams and 
    t.setHasPlayed(false);  // reset the rest each team's boolean 
} 
Match.Team1.setHasPlayed(true); 
Match.Team2.setHasPlayed(true); // set the boolean to true at the end of the turn 
// 

これは明らかに擬似コードです。これは、MatchとTeamの実装がわからないためです。それでも、ブール値のインスタンスフィールドを使用して、それが以前のターンで変更されているかどうかを確認することを検討してください。

+0

質問に例を追加しました。 lMatchはゲームのリストです。 – anubis

+0

基本的には、私が上記で提供した実装はまだ有効です。チームクラスにブール変数を作成する必要があります。この変数は、チームがゲームでプレイする資格があるかどうかを決定します。あなたは既にlMatchリストを作成する方法を知っているので、残っているのは、2つのランダムに選択されたチームのいずれかが前の試合でプレーしたかどうかを確認することだけです。 –

0

以下は再帰的アプローチです。私は、すべてのランダム化の後に制約が適用されるので、@Sonedringによって提案されたものよりも速い方法で解決策を提供できると思います。

4チーム未満のコーナーの場合は、より安全です。コーナーケースでは解決策が見つからず、無限ループを実行しないでください。

これが役に立ちます。

public static void randomize(List<Match> matches) { 
    List<Match> randomizedList = new ArrayList<>(); 
    int numberOfAttempts = 256; 

    // tmpSubList is a temporary list that contains all matches 
    // (excluding unwanted) after n-th iteration (randomization). 
    List<Match> tmpSubList = new ArrayList<Match>(matches); 
    while (matches.size() > 0) { 

     // if tmpSubList contains - it means there is no match that can be added. 
     // Need to restart randomization algorithm. 
     if (tmpSubList.size() == 0) { 
      System.out.println("Restarting algorithm."); 

      if (--numberOfAttempts == 0) { 
       throw new ArithmeticException("Could not find solution."); 
      } 
      // Need to restart: 
      matches.addAll(randomizedList); 
      tmpSubList.addAll(randomizedList); 
      randomizedList.clear(); 
     } 

     int randomIndex = (int) (tmpSubList.size() * Math.random()); 

     Match match = tmpSubList.remove(randomIndex); 
     matches.remove(match); // remove also from the main list; 
     randomizedList.add(match); 

     Equipe lastTeam1 = match.getEquA(); 
     Equipe lastTeam2 = match.getEquB(); 

     tmpSubList.clear(); 
     matches.stream() 
      .filter(x -> !x.getEquA().equals(lastTeam1) && !x.getEquB().equals(lastTeam1)) 
      .filter(x -> !x.getEquA().equals(lastTeam2) && !x.getEquB().equals(lastTeam2)) 
      .forEach(x -> tmpSubList.add(x)); 
    } 
    matches.addAll(randomizedList); 
} 
関連する問題