title: Finding all combinations for players in a tournament without duplicates
body: <p>For a table soccer tournament I have the following request:</p>
  
  <ul>
  <li>There are two types of players A (Students) and B (Teachers). (For simplicity we assume the same number of A and B players). eg. 16 students and 16 teachers.</li>
  <li>The table soccer tournament should have as many rounds as possible</li>
  <li>A round means: Every player plays one game together with a teammate against two other players.</li>
  <li>For each round a player need a teammate he never played with before. A "new" player.</li>
  <li>The teammate must be of a different type (a student always plays with a teacher).</li>
  <li>Each player from the opposing team must be "new" as well (neither be a previous opponent nor a previous teammate). </li>
  </ul>
  
  <p>Example: 
  I am a student (player type A) and have a game with teacher T_John (player type B) as teammate. We play against a student S_Mike and a teacher T_James. After the game finished a new round starts. In this new round (and all upcomming rounds) I should not play with (or against) T_John, T_James or S-Mike anymore, neither as teammate nor as an opponent.</p>
  
  <p>The idea is to meet as many new people during the tournament as possible.</p>
  
  <p>I've created a first prototype where each player has a list of all players he never played with (or against) before. For each game, I now start with a list of all players and for each player select the next fitting player as teammate and the 2 opponents. While this works, the combinations are very limited. I don't know a way to get better and consistent results.</p>
  
  <p>Here is this main routine in the Player class:</p>
  
  <pre><code>for (var i = 0; i &lt; availablePlayers.length; i++) {
      var player = availablePlayers[i];
      if (player == this || player.hasPlayedWith(this))
          continue;
  
      if (!teamMate &amp;&amp; player.type != this.type &amp;&amp;
            (!opponent1 || !player.hasPlayedWith(opponent1))) {
          teamMate = player;
          count++;
      }
      else if (!opponent1 &amp;&amp; (!teamMate || !player.hasPlayedWith(teamMate))) {
          opponent1 = player;
          count++;
      }
      else if (opponent1 &amp;&amp; !opponent2 &amp;&amp;
           player.type != opponent1.type &amp;&amp;
           !player.hasPlayedWith(opponent1)) {
         opponent2 = player;
         count++;
      }
      if (count == 3) {
          return [
            new Team(this, teamMate),
            new Team(opponent1, opponent2)
          ];
      }
  }
  </code></pre>
  
  <p>Here is a fiddle with the whole prototype which visualizes the players, teams, games and rounds.
  <a href="http://jsfiddle.net/q6e2pymL/" rel="nofollow noreferrer">http://jsfiddle.net/q6e2pymL/</a></p>
  
  <p>I'm pretty sure that there must be some kind of pattern or algorithm to calculate the best combinations. Ideas or suggestions?</p>
  
  <p>Any help is highly appreciated.</p>