title: 4-Player Tournament Scheduling, Python
body: <p>I am trying to develop an algorithm to generate a schedule for a game tournament my family hosts every year. I have written a solution that only partially works; it seems that it works for 2^x players, but not in between.</p>
  
  <p>Parcheesi is a game played with 4 people at a time, no more, no less, thus we schedule the tournament such that there is a multiple of 4 people (16, 28, 32, etc.) In round 1, there are n/4 games being played at once. Then in round 2, everybody gets shuffled up and plays new people. And in round 3, the same thing happens. Ideally, nobody plays any other person twice. That is the crux of my dilema, trying to code the property that nobody plays anybody else again. </p>
  
  <p>Here is my method for doing so. I'm sure there are inefficiencies in the code, so feel free to make suggestions (I'm not worried about efficiency, though). I just want it to work for 3+ rounds and for any multiple-of-4 number of people.</p>
  
  <pre><code>import numpy as np
  import itertools
  import sys
  
  num_players = 32
  players = np.arange(1,num_players+1)
  
  num_games = 3
  games = np.arange(1,num_games+1)
  game_matchups = {}
  
  matchups = {}
  for player in players:
      matchups[player] = []
  
  for game in games:
      tables = [ [] for i in range(int(num_players/4)) ]
      for player in players:
          for i,table in enumerate(tables):
              if player in list(itertools.chain(*tables)):
                  break
              if len(table) == 0:
                  table.append(player)
                  break
              if len(table) == 4:
                  continue             
              else:
                  for j,opp in enumerate(table):
                      if player in matchups[opp]:
                          break
                      else:
                          if j == len(table)-1:
                              table.append(player)
                              break
                          else:
                              continue
  
      game_matchups[game] = tables           
      for table in tables:
          if len(table) != 4:
              sys.exit((str(num_players)+' players with '+str(num_games)+' games doesnt work!'))
          for i,p in enumerate(table):
              matchups[p] = matchups[p] + (table[:i]+table[i+1:])
      order = order*-1
  </code></pre>
  
  <p>If the number of players is 32, I can schedule up to 5 rounds of play. But if I go up to 36 players, it breaks. It sort of "runs out" of tables in round 2, and it can't add player 33 to a table where he hasn't played someone already.</p>
  
  <p>I have tried iterating through the list of players backwards, forwards/backwards, alternating, randomizing the players that are put into tables, and others, but nothing seems to work.</p>
  
  <p>In practice, we've manually made this schedule and it has worked well. I want to write this program as a challenge to myself, but have gotten stuck.</p>