i have teams which i want to distribute in a schedule , each team play with the others one time and each team play once a day .
i got teams' names and its number from the database.

Q: i want to make daily schedule for matches (like the daily schedule of world cup)
and to enter each date in the database with the schedule of this date.

please follow this link to see what i need:
http://www.teamopolis.com/tools/round-robin-generator.aspx

    ragy, you are free to modify my code to suit your needs, subject to the license. If you need help for the modification, please ask in another forum, e.g., Coding.

      a year later

      This is my version.

      I tried to implement what wikipedia says on http://en.wikipedia.org/wiki/Round-robin_tournament#Scheduling_algorithm

      I've attached a image with the explanation of the algorithm for 8 players.

        function round_robin($num_teams = 8)
        {
          $num_rounds = $num_teams - 1;
      
      $rounds = array();
      
      for($round = 0; $round < $num_rounds; $round++) {      
        for ($index = 0; $index < $num_teams / 2; $index++)
        {
          $local_key = ($index != 0) * ($index - $round) + 
            (($index != 0) && (($index != 0) * ($index - $round) <= 0)) * $num_rounds;
      
          $away_key = $num_rounds - $index - $round + 
            (($index != 0) && ($num_rounds - $index - $round <= 0)) * $num_rounds;
      
          $rounds[$round][] = array($local_key, $away_key);
        }
      }
      
      return $rounds;
        }
      
        5 months later

        Hi,

        I created a roundrobin function from scratch as i thought it might be easier to get the same results and also allowing me to use arrays filled with strings directly instead of numbers.

        Because i pull a list of names from a database and add into an array i can now schedule this directly with below function. No extra step needed to link numbers to names etc.

        Please feel free to try it and if it works then leave a comment.
        I also have a version which allows for 2 way (home & return) schedule and or shuffle option. If somone is interested in that one then leave a coment as well.

        <?php
        
        /**
         * @author D.D.M. van Zelst
         * @copyright 2012
         */
        
        function scheduler($teams){
        // Check for even number or add a bye
            if (count($teams)%2 != 0){
                array_push($teams,"bye");
            }
        // Splitting the teams array into two arrays
            $away = array_splice($teams,(count($teams)/2));
            $home = $teams;
        // The actual scheduling based on round robin
            for ($i=0; $i < count($home)+count($away)-1; $i++){
                for ($j=0; $j<count($home); $j++){
                    $round[$i][$j]["Home"]=$home[$j];
                    $round[$i][$j]["Away"]=$away[$j];
                }
        // Check if total numbers of teams is > 2 otherwise shifting the arrays is not neccesary
                if(count($home)+count($away)-1 > 2){
                    array_unshift($away,array_shift(array_splice($home,1,1)));
                    array_push($home,array_pop($away));
                }
            }
            return $round;
        }
        ?>

        How to use, for example create an array like:

        <?php $members = array(1,2,3,4); ?>

        or

        <?php $members = array("name1","name2","name3","name4"); ?>

        then call the function to create your schedule based on above array:

        <?php $schedule = scheduler($members); ?>

        To display the resulted array schedule simply do like below or anyway you like:
        This little code displays the schedule in a nice format but use it anyway you like.

        <?php
        foreach($schedule AS $round => $games){
            echo "Round: ".($round+1)."<BR>";
            foreach($games AS $play){
                echo $play["Home"]." - ".$play["Away"]."<BR>";
            }
            echo "<BR>";
        }
        ?>

        Leave a note if it worked for you or if you are interested in the 2-way version with shuffle.

        Dave

          davaze wrote:

          Please feel free to try it and if it works then leave a comment.

          Even without running it I can leave a comment/critique; you didn't read the rules....

            Sorry,

            I guess you mean the indention for the code. Forgot to do.
            Can i still edit the post to update the indention?

            Thanks

              7 days later

              This works fine, with one exception. The script does not account for team playing home AND away. You have Team 1 home EVERY week.

              Can you adjust it so each week a team is home, then away, then back home again, etc; ?

              davaze;11002923 wrote:

              Hi,

              I created a roundrobin function from scratch as i thought it might be easier to get the same results and also allowing me to use arrays filled with strings directly instead of numbers.

              Because i pull a list of names from a database and add into an array i can now schedule this directly with below function. No extra step needed to link numbers to names etc.

              Please feel free to try it and if it works then leave a comment.
              I also have a version which allows for 2 way (home & return) schedule and or shuffle option. If somone is interested in that one then leave a coment as well.

              <?php
              
              /**
               * @author D.D.M. van Zelst
               * @copyright 2012
               */
              
              function scheduler($teams){
              // Check for even number or add a bye
                  if (count($teams)%2 != 0){
                      array_push($teams,"bye");
                  }
              // Splitting the teams array into two arrays
                  $away = array_splice($teams,(count($teams)/2));
                  $home = $teams;
              // The actual scheduling based on round robin
                  for ($i=0; $i < count($home)+count($away)-1; $i++){
                      for ($j=0; $j<count($home); $j++){
                          $round[$i][$j]["Home"]=$home[$j];
                          $round[$i][$j]["Away"]=$away[$j];
                      }
              // Check if total numbers of teams is > 2 otherwise shifting the arrays is not neccesary
                      if(count($home)+count($away)-1 > 2){
                          array_unshift($away,array_shift(array_splice($home,1,1)));
                          array_push($home,array_pop($away));
                      }
                  }
                  return $round;
              }
              ?>

              How to use, for example create an array like:

              <?php $members = array(1,2,3,4); ?>

              or

              <?php $members = array("name1","name2","name3","name4"); ?>

              then call the function to create your schedule based on above array:

              <?php $schedule = scheduler($members); ?>

              To display the resulted array schedule simply do like below or anyway you like:
              This little code displays the schedule in a nice format but use it anyway you like.

              <?php
              foreach($schedule AS $round => $games){
                  echo "Round: ".($round+1)."<BR>";
                  foreach($games AS $play){
                      echo $play["Home"]." - ".$play["Away"]."<BR>";
                  }
                  echo "<BR>";
              }
              ?>

              Leave a note if it worked for you or if you are interested in the 2-way version with shuffle.

              Dave

                Also what if two teams face each other that were both home teams the previous round? This is why the higher ranked team (aka team 1) would keep home field advantage.

                  Hi Bastadon,

                  I changed the function code a little so that at least team 1 is shifting from home to away, however it can not avoid that sometimes a team plays home or away twice. To be honest i play competition myself and also from time to time have 2 home or away games after another but you were right about team one, which i corrected with the below code.

                  I also have a version in which you can send an extra parameter to the function to be able to shuffle the schedule and or create a Home & Return schedule (2-way).
                  If anyone is interested then let me know and i'll post it as well.

                  Hope it will suit everones needs!

                  function scheduler($teams){
                      if (count($teams)%2 != 0){
                          array_push($teams,"bye");
                      }
                      $away = array_splice($teams,(count($teams)/2));
                      $home = $teams;
                      for ($i=0; $i < count($home)+count($away)-1; $i++){
                          if ($i%2 !=0){
                              for ($j=0; $j<count($home); $j++){
                                  $schedule[$i][$j]["Home"]=$away[$j];
                                  $schedule[$i][$j]["Away"]=$home[$j];
                              }
                          }else {
                              for ($j=0; $j<count($home); $j++){
                                  $schedule[$i][$j]["Home"]=$home[$j];
                                  $schedule[$i][$j]["Away"]=$away[$j];
                              }
                          }
                          if(count($home)+count($away)-1 > 2){
                              array_unshift($away,array_shift(array_splice($home,1,1)));
                              array_push($home,array_pop($away));
                          }
                      }
                      return $schedule;
                  }
                  

                    Please ignore the last post and use this one instead. in the last code it still didn't work completely. This one should be a bit better.
                    However if somebody can extend this code to suit their own needs then feel free to do.

                    function scheduler($teams){
                        if (count($teams)%2 != 0){
                            array_push($teams,"bye");
                        }
                        $away = array_splice($teams,(count($teams)/2));
                        $home = $teams;
                        for ($i=0; $i < count($home)+count($away)-1; $i++){
                            for ($j=0; $j<count($home); $j++){
                                if (($i%2 !=0) && ($j%2 ==0)){
                                    $schedule[$i][$j]["Home"]=$away[$j];
                                    $schedule[$i][$j]["Away"]=$home[$j];
                                } else {
                                    $schedule[$i][$j]["Home"]=$home[$j];
                                    $schedule[$i][$j]["Away"]=$away[$j]; 
                                }
                            }
                            if(count($home)+count($away)-1 > 2){
                                array_unshift($away,array_shift(array_splice($home,1,1)));
                                array_push($home,array_pop($away));
                            }
                        }
                        return $schedule;
                    }
                    
                      9 months later

                      Hi Davaze,

                      I have looked at your code and was trying to change it to allow for teams to play each other both at home and away.

                      I have managed to get it working but I always have one fixture from week 1 which repeats in week 8.

                      Would appreciate any help you can give

                      cheers

                        Hi DKman,

                        I'm not sure if i follow you but below is the finished function that i use. It allows to set some extra parameters to the function like shuffle and or reverse (home and away) enabled.

                        [INDENT]

                        
                        function scheduler($teams,$shuffle=0,$reverse=0){
                            if (count($teams)%2 != 0){
                                array_push($teams,"bye");
                            }
                            if ($shuffle == 1){
                                shuffle($teams);
                            }
                            $away = array_splice($teams,(count($teams)/2));
                            $home = $teams;
                            for ($i=0; $i < count($home)+count($away)-1; $i++){
                                for ($j=0; $j<count($home); $j++){
                                    if (($i%2 !=0) && ($j%2 ==0)){
                                        $schedule[$i][$j]["Home"]=$away[$j];
                                        $schedule[$i][$j]["Away"]=$home[$j];
                                    } else {
                                        $schedule[$i][$j]["Home"]=$home[$j];
                                        $schedule[$i][$j]["Away"]=$away[$j]; 
                                    }
                                }
                                if(count($home)+count($away)-1 > 2){
                                    array_unshift($away,array_shift(array_splice($home,1,1)));
                                    array_push($home,array_pop($away));
                                }
                            }
                            if ($reverse == 1){
                                for ($k=0; $k < count($home)+count($away)-1; $k++){
                                    for ($j=0; $j<count($home); $j++){
                                        if (($k%2 !=0) && ($j%2 ==0)){
                                            $schedule[$i][$j]["Home"]=$home[$j];
                                            $schedule[$i][$j]["Away"]=$away[$j];
                                        } else {
                                            $schedule[$i][$j]["Home"]=$away[$j];
                                            $schedule[$i][$j]["Away"]=$home[$j]; 
                                        }
                                    }
                                if(count($home)+count($away)-1 > 2){
                                    array_unshift($away,array_shift(array_splice($home,1,1)));
                                    array_push($home,array_pop($away));
                                }
                                $i++;
                                }
                            }
                            return $schedule;
                        }
                        
                        

                        [/INDENT]

                        Then call the function with whatever array of data you have and set the extra parameters if needed. You can leave them out as well but then they will default to 0 and just a single results with no shuffle will return.
                        Below is an example array with numbers and to echo the results back.

                        [INDENT]

                        // example array
                        $members = array(1,2,3,4);
                        // call the function with reverse enabled (home & away)
                        $schedule = scheduler($members,0,1);
                        // print the results back example
                        foreach($schedule AS $round => $games){
                            echo "Round: ".($round+1)."<BR>";
                            foreach($games AS $play){
                                echo implode("-",$play)."<BR>";
                            }
                            echo "<BR>";
                        }
                        

                        [/INDENT]

                        I hope this helps, let me know if it worked. If not then give me an example of how you used it and the results you got.

                        Dave

                          Oh my, I have not looked at this thread carefully for a long time.

                          DKman1990 wrote:

                          I have looked at your code and was trying to change it to allow for teams to play each other both at home and away.

                          A simple solution in such a case is to repeat the pairings, but with colours reversed (in other words, home and away swapped).

                          davaze wrote:

                          It allows to set some extra parameters to the function like shuffle and or reverse (home and away) enabled.

                          Unless you have some special reason to use integers, use boolean values for the shuffle and reverse flags instead. Actually, you should not have a shuffle flag: functions should do one thing and do it well, and here the input array can be shuffled before calling this function.

                            Hi Laserlight,

                            Thanks for your comments however i think a boolean value can be specified several ways like: 'true' or 'false', 'yes' or 'no' and also 0 or 1. All have the same boolean function in my opinion. Just sending over 0 or 1 is more easy then sending over string values but that's just a personal preference and can be easily changed if you want.

                            Using the shuffle flag and or reverse flag are just options to have it all go in one call instead of having to do them seperate, also this is a personal preference and for some this way might be as easy as the other way.
                            If left out the function will just do one job and that's creating a one way schedule from the input array, nomather what's in the array, either integers or strings or whatever. That's where this one differs from previous version i saw on the net where the calculation was done just with integers and therefor you still needed to pair the resulting integers with the data you used.
                            In this case it works with the arrays itself nomather what's inside.

                            Anyway use it to your own adventage and or change it the way you like. I just posted it as a starting point for people to use if they needed something like this, like me :-)

                            Dave

                              davaze wrote:

                              Thanks for your comments however i think a boolean value can be specified several ways like: 'true' or 'false', 'yes' or 'no' and also 0 or 1. All have the same boolean function in my opinion. Just sending over 0 or 1 is more easy then sending over string values but that's just a personal preference and can be easily changed if you want.

                              Certainly. However, PHP has a boolean type with literals true and false, thus it makes sense to use it when you really do want a boolean type. Furthermore, instead of doing a typical boolean check, your code checks for the integer value, e.g.,

                              if ($reverse == 1){

                              instead of:

                              if ($reverse){

                              This can be an advantage if you intend the flag to be a numeric flag instead, e.g., for different shuffling options, but then 0 and 1 become magic numbers, which is a Bad Thing.

                              davaze wrote:

                              Using the shuffle flag and or reverse flag are just options to have it all go in one call instead of having to do them seperate, also this is a personal preference and for some this way might be as easy as the other way.

                              What I am saying is that your shuffle option clutters the interface. Instead of writing:

                              $schedule = scheduler($members, 1);

                              you can write:

                              shuffle($members);
                              $schedule = scheduler($members);

                              If there was a version of shuffle that returned the array shuffled instead, then even better, e.g.,

                              $schedule = scheduler(shuffle_return($members));
                              davaze wrote:

                              In this case it works with the arrays itself nomather what's inside.

                              Indeed, which is why I think that the shuffle option clutters the interface. You have provided a good way to get input, so take advantage of it.

                              davaze wrote:

                              Anyway use it to your own adventage and or change it the way you like. I just posted it as a starting point for people to use if they needed something like this, like me :-)

                              This is the Code Critique forum, so you should expect a code critique 😉

                              If I wanted to do something like your version, I would just modify my version to allow for similiar input and output 🙂

                                Hi Laserlight,

                                Guess i misunderstood your comment. In that case you are correct! Thanks for your feedback and support to update the code to become a good function to use for everyone.
                                Like i said for me it was a starting point to help out the people who needed this as i could not find many usefull options on the net that time. Critique is always welcome otherwise i would not post it here :-)

                                Dave

                                  Hi guys,

                                  Basically the algorithm I have at the moment takes in an array of teams, a competition start date and an array of referees. It then generates a set of fixtures (multidimensional array) with dates, times and a referee (venue is added later) which seemed to be both home and away until I double checked and saw that a couple of the fixtures were wrong. I know the way I have written or done things may not be the best but I am quite new to php.

                                  From what you have said I take it that I would need to reverse the fixtures to get something resembling a double round robin style fixture set were each team plays each other twice (Home and Away).

                                  I would greatly appreciate any help you are willing to give.

                                  I have been feeding in 7 random teams, any start date and a big array of referees.

                                  The code I have been using is below:

                                  <?php
                                  
                                  //Algorithm which is a function for scheduling fixtures,taking in arrays of teams and referees and a league start date.
                                  
                                  function getFixtures($teamslist,$startDate,$referees){ 
                                  
                                  
                                  //if odd number of teams add a BYE team!
                                  if (count($teamslist)%2 != 0){ 
                                      array_push($teamslist,"IGNORE"); 
                                  } 
                                  
                                  //shuffle the list of teams, so we don't get same fixtures each time!
                                  shuffle($teamslist);
                                  
                                  //split teamslist into two arrays
                                  $away = array_splice($teamslist,(count($teamslist)/2)); 
                                  $home = $teamslist; 
                                  
                                  //iterate through for every game in every round for teams
                                  for ($a=0; $a < ((count($teamslist)+count($away))-1)*2; $a++){ 
                                  
                                  //assign the full list of referees each round or week so we get full list again
                                  	$refs=$referees;
                                  
                                  	//shuffle the list so its random
                                  	shuffle($refs);
                                      for ($z=0; $z<count($home); $z++){ 
                                  
                                  	//pick a ref for a game basically!
                                  		$picked=array_shift($refs);
                                  
                                  
                                  		//assign the relevant teams, dates, times and referee to fixtures
                                  
                                  
                                  
                                  
                                  
                                          if (($a%2 !=0) && ($z%2 ==0)){ 
                                  
                                  		if ($z%2==0)
                                  		{
                                  		$startDate=date('Y-m-d',strtotime($startDate."+1 days"));
                                  		}
                                  
                                  
                                  
                                              $match[$a][$z]["Home"]=$away[$z]; 
                                              $match[$a][$z]["Away"]=$home[$z]; 
                                  			$match[$a][$z]["Date"]=$startDate;
                                  			$match[$a][$z]["Time"]="19:00:00";
                                  			$match[$a][$z]["Ref"]=$picked;
                                  
                                  
                                          } else { 
                                  		if ($z%2==0)
                                  		{
                                  		$startDate=date('Y-m-d',strtotime($startDate."+1 days"));
                                  		}
                                  
                                  
                                              $match[$a][$z]["Home"]=$home[$z]; 
                                              $match[$a][$z]["Away"]=$away[$z]; 
                                  			$match[$a][$z]["Date"]=$startDate;
                                  			$match[$a][$z]["Time"]="19:00:00";
                                  			$match[$a][$z]["Ref"]=$picked;
                                  
                                          } 
                                  
                                  
                                      } 
                                  
                                      //If there
                                      if(count($home)+count($away)-1 > 2){ 
                                  	$splice=array_splice($home,1,1);
                                  	$shift=array_shift($splice);
                                          array_unshift($away,$shift); 
                                          array_push($home,array_pop($away)); 
                                      } 
                                  
                                  
                                  	$startDate=date('Y-m-d',strtotime($startDate."+7 days"));
                                  } 
                                  
                                  
                                  
                                  
                                  
                                  
                                   //go through the whole array storing everything and go to each round, then game and check whether our bye team is present, if so ignore and remove the fixture,else keep it
                                  	foreach($match AS $matchkey => $matchval)
                                  	{
                                  
                                    foreach($matchval AS $gamekey=>$game){
                                    if($game["Home"]!= "IGNORE" && $game["Away"]!="IGNORE"){
                                  
                                  	//store it all in a new multidimensional array 
                                    $allmatches[$matchkey][$gamekey]=$game;
                                  
                                  }
                                  
                                  }   
                                  
                                  }
                                  
                                  //return it all
                                  return $allmatches;
                                  }
                                  
                                  ?>

                                  Dan 🙂
                                  danielrknowles@hotmail.com

                                    5 years later

                                    Ey guys..need your help with the same problem

                                    Jara

                                    What problem? Does it have anything to do with this (old) thread? What have you tried so far? Etc., etc., and so forth.

                                    14 days later

                                    i have an attached code.but i need the games to be played on two days every round..
                                    like round1 games to be played on saturday and sunday...