【问题标题】:PHP randomly assign people to a teamPHP 随机分配人员到一个团队
【发布时间】:2020-06-01 09:32:43
【问题描述】:

我目前正在构建一个小游戏,需要将用户随机分配到团队中。

我得到的是数据库中的一个表,其中列出了登录的用户。此外,每个用户都有一个团队列。

现在在 PHP 中,我将所有用户存储在一个变量中,如下所示(var_export 的输出)

array ( 0 => array ( 'ID' => '3', 'name' => 'olaf', 'team' => NULL, ), 1 => array ( 'ID' => '4', 'name' => 'Peter', 'team' => NULL, ), 2 => array ( 'ID' => '5', 'name' => 'chris', 'team' => NULL, ), 3 => array ( 'ID' => '6', 'name' => 'günther', 'team' => NULL, ), )

现在我有两支队伍,红队和蓝队。我的目标是,每个人都被随机分配到两个团队中的一个,但是,两个团队应该有相似数量的团队成员(或者如果登录的用户数量为奇数,一个团队可以多一个玩家) .

分配后,我会将信息写入数据库。但是,我希望始终能够对球队进行洗牌,然后组建新球队。

登录用户的数量可以在 2 到 50 人之间变化。

到目前为止,我考虑了多种方法,例如在 1 和 sizeof(用户数组)之间随机选择一个数字,然后为他分配一个团队,但是,我无法让它发挥作用......

此外,我在this Stackoverflow 发帖,但是,使用此代码,我的红队总是有球员 1 和 3 或 1 和 4,而我的蓝队总是有球员 2 和 3 或 2 和 4。从来没有发生过玩家 1 是红队。但是,如上所述,混合应该是完全随机的。

谁能帮我解决这个问题或有一个想法,我怎么能做到这一点?

【问题讨论】:

    标签: php random shuffle


    【解决方案1】:

    这是一个例子:

    <?php
    
    // just preparing the set of players for the demonstration
    $numberOfPLayers = 6;
    $players = [];
    for ($i = 0; $i < $numberOfPLayers; $i++) {
        $players[] = [
            'id' => $i,
            'name' => sprintf("Player %d", $i + 1),
            'team' => null 
        ];
    }
    
    // here starts the actual assignment
    shuffle($players);
    
    array_walk($players, function(&$player, $index) {
        $player['team'] = $index % 2 ? "Red" : "Blue";
    });
    
    usort($players, function($a, $b) {
        return $a['id'] <=> $b['id'];
    });
    
    // just a test output of the set of players
    print_r($players);
    

    代码sn-p创建一个玩家列表,你可以玩弄玩家的数量。它首先对球员进行洗牌,然后交替分配球队,如此均匀,最后再次对球员集进行排序。

    一个可能的输出是(当然取决于随机洗牌):

    Array
    (
        [0] => Array
            (
                [id] => 0
                [name] => Player 1
                [team] => Blue
            )
    
        [1] => Array
            (
                [id] => 1
                [name] => Player 2
                [team] => Red
            )
    
        [2] => Array
            (
                [id] => 2
                [name] => Player 3
                [team] => Red
            )
    
        [3] => Array
            (
                [id] => 3
                [name] => Player 4
                [team] => Blue
            )
    
        [4] => Array
            (
                [id] => 4
                [name] => Player 5
                [team] => Red
            )
    
        [5] => Array
            (
                [id] => 5
                [name] => Player 6
                [team] => Blue
            )
    
    )
    

    【讨论】:

      【解决方案2】:

      我已经设法解决了您的问题。您现在可以通过调用createTeams($playerArray); 轻松重置团队。该函数首先检查是否有均匀数量的玩家。如果是这样的话,那么每支球队都会得到一半的球员。否则,通过向上或向下舍入 $playersPerTeam,一个团队随机获得或多或少 1 名玩家。接下来它将播放器数组洗牌 4 次以创建随机播放器列表。

      之后,您有两个返回值选项。第一个从$players 数组中选择指定数量的玩家。然后它返回一个包含团队的数组。

      最后一种方法涉及与第一种方法相同的方法,但现在它也设置了播放器对象的[team] 变量。然后它返回 $players 数组,但带有指定的团队名称。

      function createTeams($players) {
        $totalPlayers = count($players);
      
        if($totalPlayers % 2 == 0) { //even amount of players
          $playersRed = $playersBlue = $totalPlayers / 2;
        } else { //odd amount of players
          $randInt = rand(1,100);
          $playersPerTeam = $totalPlayers / 2;
          if($randInt <= 50) { //team red has an advantage of 1 extra player
            $playersRed = round($playersPerTeam, 0, PHP_ROUND_HALF_UP);
            $playersBlue = round($playersPerTeam, 0, PHP_ROUND_HALF_DOWN);
          } else { //team blue has an advantage of 1 extra player
            $playersRed = round($playersPerTeam, 0, PHP_ROUND_HALF_DOWN);
            $playersBlue = round($playersPerTeam, 0, PHP_ROUND_HALF_UP);
          }
        }
      
        //This should be random enough for this purpose
        for ($i=0; $i < 4; $i++) {
          shuffle($players);
        }
      
      
        //One way to return the teams.
        // $teamRed  = array_slice($players, 0, $playersRed);
        // $teamBlue = array_slice($players, $playersRed, $playersBlue);
        // return array('red' => $teamRed , 'blue' => $teamBlue);
      
        //Other way to return the createTeams
        for ($i=0; $i < $totalPlayers; $i++) {
          if ($i < $playersRed) { //player is gonna be in team red
            $players[$i]['team'] = 'red';
          } else { //player is gonna be in team blue
            $players[$i]['team'] = 'blue';
          }
        }
        return $players;
      }
      
      

      用这个播放器数组测试它:

      $players = array ( 0 => array ( 'ID' => '3', 'name' => 'olaf', 'team' => NULL), 1 => array ( 'ID' => '4', 'name' => 'Peter', 'team' => NULL), 2 => array ( 'ID' => '5', 'name' => 'chris', 'team' => NULL), 3 => array ( 'ID' => '6', 'name' => 'günther', 'team' => NULL), 4 => array ( 'ID' => '7', 'name' => 'Max', 'team' => NULL));
      
      for ($i=0; $i < 5; $i++) {
        print_r(createTeams($players));
        echo "<br><br>";
      }
      
      

      给出以下输出:

      Array ( [0] => Array ( [ID] => 4 [name] => Peter [team] => red ) [1] => Array ( [ID] => 6 [name] => günther [team] => red ) [2] => Array ( [ID] => 5 [name] => chris [team] => blue ) [3] => Array ( [ID] => 7 [name] = > Max [team] => blue ) [4] => Array ([ID] => 3 [name] => olaf [team] => blue ))

      Array ([0] => Array ([ID] => 3 [name] => olaf [team] => red) [1] => Array ([ID] => 5 [name] => chris [team] => red ) [2] => Array ( [ID] => 6 [name] => günther [team] => red ) [3] => Array ( [ID] => 4 [name] = > Peter [team] => blue ) [4] => Array ([ID] => 7 [name] => Max [team] => blue ))

      Array ( [0] => Array ( [ID] => 3 [name] => olaf [team] => red ) [1] => Array ( [ID] => 6 [name] => günther [team] => red ) [2] => Array ( [ID] => 5 [name] => chris [team] => blue ) [3] => Array ( [ID] => 4 [name] = > Peter [team] => blue ) [4] => Array ([ID] => 7 [name] => Max [team] => blue ))

      Array ( [0] => Array ( [ID] => 6 [name] => günther [team] => red ) [1] => Array ( [ID] => 7 [name] => Max [team] => red ) [2] => Array ( [ID] => 3 [name] => olaf [team] => blue ) [3] => Array ( [ID] => 5 [name] = > chris [team] => blue ) [4] => Array ([ID] => 4 [name] => Peter [team] => blue ))

      Array ( [0] => Array ( [ID] => 5 [name] => chris [team] => red ) [1] => Array ( [ID] => 6 [name] => günther [team] => red ) [2] => Array ( [ID] => 3 [name] => olaf [team] => red ) [3] => Array ( [ID] => 4 [name] = > Peter [team] => blue ) [4] => Array ([ID] => 7 [name] => Max [team] => blue ))

      希望这会有所帮助!如果没有,请发表评论。

      【讨论】:

        【解决方案3】:

        我看到有一个可接受的答案,但我想我会发布我的答案,因为我昨晚开始研究这个问题,今天早上想通了......

        在在线解析器上查看 3v4lhttps://3v4l.org/O8hOh

        使用颜色来设置表格样式: https://3v4l.org/ZUl5p

        获取数组并使用foreach()进行迭代,然后使用rand()创建一个新数组$checks,然后检查值!in_array() &amp;&amp; !array_key_exists()是否存在于该新数组中,如果不存在,则我们迭代计数器并将新值和玩家姓名推送到新数组中。我们将这一切包装在 while 循环中,检查计数器是否等于 count($arr) --> 游戏玩家的数量,从数组 count() 动态提取。

        我们使用第二个条件来确保新数组count($check) === count($arr) 是相同的数字,然后将团队推进到key=NULLteam=NULL 的原始数组中。 foreach() 循环构造$gamers 数组。将原始值推回新数组,然后有条件地检查是否可被 2 整除,因为每次调用时,$checks 数组将始终为玩家数量随机分配一个新数字,if($check[$value['name']] % 2 == 0) 分配团队 2 --> $gamers[$key]['team'] = 2;。 或$gamers[$key]['team'] = 'blue';else{ $gamers[$key]['team'] = 1 }else{ $gamers[$key]['team'] = 'Red' };

        原来保存有NULL 键值team 的玩家的旧数组现在保存新分配的团队。

        基本代码在代码 cmets 中有解释:

        $arr = array ( 0 => array ( 'ID' => '3', 'name' => 'olaf', 'team' => NULL, ), 1 => array ( 'ID' => '4', 'name' => 'Peter', 'team' => NULL, ), 2 => array ( 'ID' => '5', 'name' => 'chris', 'team' => NULL, ), 3 => array ( 'ID' => '6', 'name' => 'günther', 'team' => NULL, ), );
        // count the number of player in the array and assign to variable
        $numOfPlayers = count($arr);
        
        // initiate an empty array to hold the values of the players random unique numbers
        $check = array();
        
          $i = 0; // use a counter to evaluate whether number of players set in array is met
          while($i < count($arr)){ // iterate through foreach loop until we have met the number of players using while loop
            // iterate through each time the while loop fires to get the $value 
            foreach($arr as $key => $value){
              // create a random number between 0 and the number of players present in array 
              // to check and pass into new array if is not set yet
              $random = rand(1,$numOfPlayers);
              // conditional that check if the random number is in the new array, if not we push that as a value into the new array
              // we also check if the persons name is set as a key, if not, we push that as a key into the new aray
              if(!in_array($random, $check) && !array_key_exists($value['name'], $check)){
                // set the new key/value pairs and iterate the counter for the while loop
                $check[$value['name']] = $random;
                $i++;
              }
            }
          }
          // Now see if the two arrays $check and $arr are equal in count
          if(count($check) === count($arr)){
            // now assign teams using modulus
            foreach($arr as $key => $value){ 
              // construct the old array with original values
              $gamers[$key] = $value; 
              // if value is divisible by 2, assign to specific team change operator here 
              // if you want to swap what team get the odd numbered players   
              if($check[$value['name']] % 2 == 0){       
                $gamers[$key]['team'] = 2;
              // else if not divisible by two assign to other team     
              }else{
                $gamers[$key]['team'] = 1;
              }
            }     
          }
        

        作为一个函数:

        function constTeams($arr){
          $numOfPlayers = count($arr);
        
          $check = array();
        
          $i = 0;
          while($i < count($arr)){
            foreach($arr as $key => $value){
              $random = rand(1,$numOfPlayers); 
              if(!in_array($random, $check) && !array_key_exists($value['name'], $check)){
                $check[$value['name']] = $random;
                $i++;
              }
            }
          }
          if(count($check) === count($arr)){
            foreach($arr as $key => $value){ 
              $gamers[$key] = $value;     
              if($check[$value['name']] % 2 == 0){        
                $gamers[$key]['team'] = 'Blue';
              }else{
                $gamers[$key]['team'] = 'Red';
              }
            }     
          }
          return $gamers;
        }
        
        

        var_dump(constTeams($arr)); 使用上述函数的输出,每次调用都会改变:

        array(4) {
          [0]=>
          array(3) {
            ["ID"]=>
            string(1) "3"
            ["name"]=>
            string(4) "olaf"
            ["team"]=>
            string(3) "Red"
          }
          [1]=>
          array(3) {
            ["ID"]=>
            string(1) "4"
            ["name"]=>
            string(5) "Peter"
            ["team"]=>
            string(4) "Blue"
          }
          [2]=>
          array(3) {
            ["ID"]=>
            string(1) "5"
            ["name"]=>
            string(5) "chris"
            ["team"]=>
            string(4) "Blue"
          }
          [3]=>
          array(3) {
            ["ID"]=>
            string(1) "6"
            ["name"]=>
            string(8) "günther"
            ["team"]=>
            string(3) "Red"
          }
        }
        
        

        与奇数玩家数组一起使用:

        $players = array ( 
          0 => array ( 'ID' => '3', 'name' => 'olaf', 'team' => NULL, ), 
          1 => array ( 'ID' => '4', 'name' => 'Peter', 'team' => NULL, ), 
          2 => array ( 'ID' => '5', 'name' => 'chris', 'team' => NULL, ), 
          3 => array ( 'ID' => '6', 'name' => 'günther', 'team' => NULL, ), 
          4 => array ( 'ID' => '7', 'name' => 'John', 'team' => NULL, ), 
          5 => array ( 'ID' => '8', 'name' => 'Jack', 'team' => NULL, ), 
          6 => array ( 'ID' => '9', 'name' => 'Bob', 'team' => NULL, ), 
          7 => array ( 'ID' => '10', 'name' => 'Jake', 'team' => NULL, ), 
          8 => array ( 'ID' => '11', 'name' => 'Bill', 'team' => NULL, ) 
        ) ;
        
        $output = '
          <table>
            ';
          foreach(constTeams($players) as $key => $value){
              $output .= '
              <tr border="1">
                <td>'.$value['name'].'</td>
                <td>Team: '.$value['team'].'</td>
              </tr>';    
          }
          $output .= '
          </table>';
        
        

        输出:每次调用函数时随机变化。 注意:奇数球员将由操作员在模数方程条件下确定,更改它以更改哪支球队获得过强的球员人数。 ==!= --> 这里:if($check[$value['name']] % 2 == 0)

        【讨论】:

          猜你喜欢
          • 2016-10-11
          • 2015-03-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-23
          • 2017-05-30
          • 1970-01-01
          • 2016-01-21
          相关资源
          最近更新 更多