sorting tournament seeds

前端 未结 6 1232
夕颜
夕颜 2021-02-09 17:40

I\'m making a HTML/JS powered single/double elimination bracket web app. I am struggling to figure out how to assign the first round matches from a list of seeded teams/players.

6条回答
  •  囚心锁ツ
    2021-02-09 18:20

    I wrote a solution in PHP (see https://stackoverflow.com/a/45566890/760777). Here is the javascript version.

    It returns all seeds in the correct positions. The matches are the same as in his example, but in a prettier order, seed 1 and seed number 8 are on the outside of the schema (as you see in tennis tournaments).

    If there are no upsets (meaning a higher seeded player always wins from a lower seeded player), you will end up with seed 1 vs seed 2 in the final.

    It actually does two things more:

    1. It shows the correct order (which is a requirement for putting byes in the correct positions)

    2. It fills in byes in the correct positions (if required)

    A perfect explanation about what a single elimination bracket should look like: http://blog.playdriven.com/2011/articles/the-not-so-simple-single-elimination-advantage-seeding/

    Code example for 8 participants:

    var NUMBER_OF_PARTICIPANTS = 8; // Set the number of participants
    
    if (!String.prototype.format) {
      String.prototype.format = function() {
        var args = arguments;
        return this.replace(/{(\d+)}/g, function(match, number) { 
          return typeof args[number] != 'undefined' ? args[number] : match;
        });
      };
    }
    
    var participants = Array.from({length: NUMBER_OF_PARTICIPANTS}, (v, k) => k + 1) ;
    var bracket = getBracket(participants);
    
    console.log(bracket);
    
    function getBracket(participants)
    {
      var participantsCount = participants.length;	
      var rounds = Math.ceil(Math.log(participantsCount)/Math.log(2));
      var bracketSize = Math.pow(2, rounds);
      var requiredByes = bracketSize - participantsCount;
    	
      console.log("Number of participants: {0}".format(participantsCount));
      console.log("Number of rounds: {0}".format(rounds));
      console.log("Bracket size: {0}".format(bracketSize));
      console.log("Required number of byes: {0}".format(requiredByes));    
        
      if(participantsCount < 2) {
        return [];
      }
        
      var matches = [[1,2]];
      
      for(var round = 1; round < rounds; round++) {
        var roundMatches = [];
        var sum = Math.pow(2, round + 1) + 1;
        
        for(var i = 0; i < matches.length; i++) {
          var home = changeIntoBye(matches[i][0], participantsCount);
          var away = changeIntoBye(sum - matches[i][0], participantsCount);
          roundMatches.push([home, away]);
          home = changeIntoBye(sum - matches[i][1], participantsCount);
          away = changeIntoBye(matches[i][1], participantsCount);
          roundMatches.push([home, away]);
        }
        matches = roundMatches;   
        
      }   
      
      return matches;    
    }
    
    function changeIntoBye(seed, participantsCount)
    {
        //return seed <= participantsCount ?  seed : '{0} (= bye)'.format(seed);  
        return seed <= participantsCount ?  seed : null;
    }

    Change NUMBER_OF_PARTICIPANTS from 8 to 6 to get two byes.

    Good luck. RWC

提交回复
热议问题