Ejemplo n.º 1
0
        public override void PairPlayers()
        {
            pairings.Clear();                                          //Clear pairings from prev round
            List <Player> playerPool     = new List <Player>(players); //Pool to pull players from
            List <Player> validOpponents = new List <Player>();        //Opponents who are valid for the current player
            List <Player> currentPool    = new List <Player>();        //Pool to hold temporary values
            //while (playerPool.Count > 0) //Commented out to avoid infinite loop since pairing NYI
            {
                if (currentPool.Count > 0)
                {
                    currentPool.Clear();
                }                                                              //Clear the temporary pool of any values it contains
                #region byePairing
                while (playerPool.Count % numPlayersInPairs != 0)              //Assign byes until playerPool contains a number divisible into pairs;
                {
                    uint?minValue = null;                                      //Minimum number of byes in the pool
                    playerPool = playerPool.OrderBy(o => o.byeCount).ToList(); //Order players by number of byes
                    minValue   = playerPool[0].byeCount;                       //First player has min number
                    foreach (var player in playerPool)
                    {
                        if (player.byeCount == minValue)
                        {
                            currentPool.Add(player); //Add each player with min value to a pool
                        }
                    }
                    int           playerIndex = r.Next() % currentPool.Count; //Choose random in pool
                    PlayerPairing byePair     = new PlayerPairing();          //PlayerPairing for the bye
                    byePair.pairedPlayers = new List <Player>();
                    byePair.pairedPlayers.Add(currentPool[playerIndex]);
                    byePair.pairedPlayers[0].byeCount += 1; //Increment byeCount of the player who recieved the bye
                    for (int i = 1; i < numPlayersInPairs; i++)
                    {
                        byePair.pairedPlayers.Add(new Player("bye")); //Add n-1 players named bye to pair where n is equal to numPlayersInPair
                    }
                    playerPool.Remove(currentPool[playerIndex]);      //RemoveAt(Player.getPlayerIndexByName(byePair.pairedPlayers[0].name, playerPool)); //Remove the player who recieved a bye from the pool
                    currentPool.Clear();
                    pairings.Add(byePair);
                } //END BYE PAIRING
                #endregion byePairing
                #region MyNormalPairing

                /*playerPool = playerPool.OrderByDescending(o => o.points).ToList();
                 * PlayerPairing pair = new PlayerPairing();
                 * pair.pairedPlayers = new List<Player>();
                 * pair.pairedPlayers.Add(playerPool[0]);
                 * playerPool.RemoveAt(0);
                 * foreach (Player player in playerPool)
                 * {
                 *  if (!(pair.pairedPlayers[0].prevOpponents.Contains(player))) //Player has not matched with player yet
                 *  {
                 *      validOpponents.Add(player); //Add to valid opponents
                 *  }
                 * }
                 * validOpponents = validOpponents.OrderBy(o => o.points).ToList();
                 * while(pair.pairedPlayers.Count < numPlayersInPairs)
                 * {
                 *  currentPool.Clear(); //Clear the currentPool before building a new one
                 *  while(validOpponents.Count > 0)
                 *  {
                 *      currentPool.Add(validOpponents[0]);
                 *      validOpponents.RemoveAt(0);
                 *      if(validOpponents.Count == 0){ break; }else
                 *      if (validOpponents.Count == 1) //Break before checking next item if no next item
                 *      {
                 *          currentPool.Add(validOpponents[0]);
                 *          validOpponents.RemoveAt(0);
                 *          break;
                 *      }else if(validOpponents[0].points > validOpponents[1].points) //break out if next item is different pool
                 *      {
                 *          break;
                 *      }
                 *  }
                 *  int opponentIndex = r.Next() % currentPool.Count;
                 *  pair.pairedPlayers[0].prevOpponents.Add(currentPool[opponentIndex]);
                 *  pair.pairedPlayers.Add(currentPool[opponentIndex]);
                 *  playerPool.Remove(currentPool[opponentIndex]);
                 *  currentPool.RemoveAt(opponentIndex);
                 * }
                 * pairings.Add(pair);*/
                #endregion
                #region MyAttemptAtMinimumCostPairs

                /*
                 * //BUILD COSTS
                 * Dictionary<List<Player>, int> CostLookup = new Dictionary<List<Player>, int>();
                 * var allCombinations = Global.Combinations(playerPool, numPlayersInPairs).ToList();
                 * foreach (var item in allCombinations)
                 * {
                 *  int pairCost = 0;
                 *  if (prevPairs.Contains(item.ToList())){
                 *      pairCost += 1000; //Add large cost if pair has already been made
                 *  }
                 *  float sumDifference = 0;
                 *  int i = 0; //num subcombination
                 *  foreach (var subCombination in item.Combinations(2).ToList())
                 *  {
                 *      List<Player> playerList = subCombination.ToList();
                 *      i += 1;
                 *      sumDifference += Math.Abs(playerList[1].wins - playerList[0].wins);
                 *  }
                 *  pairCost += (int)(sumDifference / i);
                 *  CostLookup.Add(item.ToList(), pairCost);
                 * } //Costs should be added
                 *
                 * //List<Players> = Pairing
                 * //List<List<Players>> = List of Pairings
                 * //List<List<List<Players>>> = List of Possible Pairings
                 *
                 * List<possPairs> validPairs = new List<possPairs>();
                 *
                 * var PossiblePairings = allCombinations.Combinations(playerPool.Count / numPlayersInPairs).ToList();
                 * foreach (IEnumerable<IEnumerable<Player>> pairingEnum in PossiblePairings)
                 * {
                 *  List<Player> usedPlayers = new List<Player>();
                 *  bool invalidPairing = false;
                 *  foreach(IEnumerable<Player> pair in pairingEnum)
                 *  {
                 *      foreach (Player p in pair)
                 *      {
                 *          if (usedPlayers.Contains(p)) invalidPairing = true;
                 *          if (invalidPairing) break;
                 *      }
                 *      if (invalidPairing) break;
                 *  }
                 *  if (invalidPairing) { PossiblePairings.Remove(pairingEnum); }
                 *  else
                 *  {
                 *      int PairingCost = 0;
                 *      List<List<Player>> pairs = new List<List<Player>>();
                 *      foreach (var pair in pairingEnum.ToList())
                 *      {
                 *          List<Player> pairList = pair.ToList();
                 *          pairs.Add(pairList);
                 *          PairingCost += CostLookup[pairList]; //Throws error due to equivalence not working?!?!?!?!
                 *      }
                 *      possPairs p = new possPairs();
                 *      p.pairs = pairs;
                 *      p.totalCost = PairingCost;
                 *      validPairs.Add(p);
                 *  }
                 * }
                 *
                 * int minCost = -1;
                 * possPairs minCostPairings = new possPairs();
                 * foreach (possPairs pair in validPairs)
                 * {
                 *  if(minCost == -1 || pair.totalCost < minCost)
                 *  {
                 *      minCost = pair.totalCost;
                 *      minCostPairings = pair;
                 *  }
                 * }
                 *
                 * foreach (List<Player> pair in minCostPairings.pairs)
                 * {
                 *  PlayerPairing p = new PlayerPairing();
                 *  p.pairedPlayers = pair;
                 *  p.isBye = false;
                 *  pairings.Add(p);
                 * }
                 */
                #endregion
                #region CommentedNotesOnNYI

                /*
                 *
                 * OK, so standard swiss rounds are made a whole lot harder
                 * due to the fact that two players cannot be paired at the same time.
                 *
                 * My attempt for normal pairing found elligible "enemies" for player 1
                 * and then matched him. This continued for each other player, until
                 * every player was in a pair.
                 *
                 * This works perfectly, until you get to generating the final pair.
                 * After round 1, It is possible to generate pairs such that the
                 * first n/n+1 pairs are created without any pairs being the same,
                 * yet the last pair was already in round 1.
                 *
                 * Due to this, I have found that the solution is to use
                 * minimum cost-maximum matching, A concept in discrete mathematics and
                 * graph theory.
                 *
                 * I have saved my attempt at it, but it is horribly ineffecient to the point
                 * of uselessness.
                 *
                 * I hope to revisit this when I have the time, but for now
                 * this will not be implemented.
                 *
                 * Since this has been put off, I will work on making semiswiss more traditional
                 * with tiebreakers.
                 *
                 */
                #endregion
                #region AttemptAtGeneratingOnTheFlyPairings
                foreach (var p in players)
                {
                    var otherPlayers = players.Where(x => x != p);
                    foreach (var o in otherPlayers)
                    {
                        p.AddOpponent(o);
                    }
                }
                getPairings();
                #endregion
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create player pairings for next round
        /// </summary>
        public override void PairPlayers()
        {
            List <Player> playerPool  = new List <Player>(players); //Players who have not been paired
            List <Player> currentPool = new List <Player>();        //Players currently being paired

            pairings.Clear();                                       //Clear Pairings to generate new pairings
            #region byePairing
            if (playerPool.Count % 2 == 1)                          //Odd number of players
            {
                uint?minValue = null;                               //Minimum number of byes in the pool
                foreach (var player in playerPool)
                {
                    if (player.byeCount < minValue || minValue == null) //If current player has fewer byes than minimum, or minimum is unset
                    {
                        minValue = player.byeCount;
                    }
                }
                foreach (var player in playerPool)
                {
                    if (player.byeCount == minValue)
                    {
                        currentPool.Add(player); //Add each player with min value to a pool
                    }
                }
                int           playerIndex = r.Next() % currentPool.Count; //Choose random in pool
                PlayerPairing byePair     = new PlayerPairing();          //PlayerPairing for the bye
                byePair.pairedPlayers = new List <Player>();
                byePair.pairedPlayers.Add(currentPool[playerIndex]);
                byePair.pairedPlayers[0].byeCount += 1;                                                      //Increment byeCount of the player who recieved the bye
                byePair.pairedPlayers.Add(new Player("bye"));
                playerPool.RemoveAt(Player.getPlayerIndexByName(byePair.pairedPlayers[0].name, playerPool)); //Remove the player who recieved a bye from the pool
                currentPool.Clear();
                pairings.Add(byePair);
            }
            #endregion
            #region NormalPairing
            Player holdover = null;      //Hold player in case a pool of players is odd
            while (playerPool.Count > 0) //While there are more players to assign
            {
                currentPool.Clear();     //Ensure currentPool is empty at start

                int maxWinsInPool = 0;   //Value to hold max wins.
                foreach (var player in playerPool)
                {
                    if (player.wins > maxWinsInPool)       //Player has more wins than previous max
                    {
                        currentPool.Clear();               //Empty previous pool
                        maxWinsInPool = (int)player.wins;  //Increase max wins
                        currentPool.Add(player);           //Add player to it.
                    }
                    else if (player.wins == maxWinsInPool) //Player has same number as max wins
                    {
                        currentPool.Add(player);           //Add to pool
                    }
                    else
                    {
                        //Future use
                    }
                }
                if (holdover != null)                                                  //Previous player pool was odd, need to deal with extra player
                {
                    currentPool.Add(holdover);                                         //Add this player to the current pool
                    holdover = null;                                                   //Holdover is now empty
                }
                if (currentPool.Count % 2 == 1)                                        //Current Pool is odd.
                {
                    holdover = currentPool[0];                                         //Add first player to holdover.
                    playerPool.Remove(currentPool[0]);                                 //Remove them from the playerPool.
                    currentPool.RemoveAt(0);                                           //Remove them from the currentPool
                }
                while (currentPool.Count > 0)                                          //Players in current pool to deal with, will always run an even number of times.
                {
                    PlayerPairing pair = new PlayerPairing();                          //New Pair
                    pair.pairedPlayers = new List <Player>();
                    pair.pairedPlayers.Add(currentPool[r.Next() % currentPool.Count]); //Pick first player
                    currentPool.Remove(pair.pairedPlayers[0]);                         //Remove from currentPool
                    pair.pairedPlayers.Add(currentPool[r.Next() % currentPool.Count]); //Pick Second Player
                    currentPool.Remove(pair.pairedPlayers[1]);                         //Remove from currentPool
                    pairings.Add(pair);                                                //Add pairing to list of pairings
                    playerPool.Remove(pair.pairedPlayers[0]);                          //Remove both players from playerPool.
                    playerPool.Remove(pair.pairedPlayers[1]);
                }
            }
            #endregion
        }