PHP 随机分配人员到一个团队

PHP randomly assign people to a team

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

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

现在在 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(用户数组)之间的数字,然后给他分配一个团队,但是,我无法让它工作.. .

我也 Whosebug post,但是,使用此代码,我的团队红色总是有玩家 1 和 3 或 1 和 4,而我的团队蓝色总是有玩家 2 和 3 或 2和 4. 从来没有发生过,玩家 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);

该代码片段创建了一个玩家列表,您可以随意调整玩家数量。它首先洗牌球员,然后交替分配球队,如此均匀,最后再次对球员组进行排序。

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

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
        )

)

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

之后,您有两个 return 值选项。第一个从 $players 数组中选择分配的玩家数量。然后它 return 是一个包含团队的数组。

最后一种方法涉及与第一种方法相同的方法,但现在它还设置玩家对象的 [team] 变量。然后它 return 是 $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 ) )

希望这对您有所帮助!如果没有,请评论。

我看到有一个被接受的答案,但我想我会 post 我的答案以及我昨晚开始研究这个问题并在今天早上想出来...

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

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

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

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

原来包含键 team 具有 NULL 值的玩家的旧数组现在包含新分配的 team/s。

基本代码,代码注释中有解释:

$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)