首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PHP将人员随机分配给一个团队

PHP将人员随机分配给一个团队
EN

Stack Overflow用户
提问于 2020-06-01 09:32:43
回答 3查看 693关注 0票数 0

我目前正在建立一个小游戏,用户需要被随机分配给团队。

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

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

代码语言:javascript
运行
复制
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和多少(用户数组)之间随机选择一个数字,然后给他分配一个团队,但是,我无法让它工作……

此外,我的this堆栈溢出帖子,然而,使用这段代码,我的队红总是有球员1和3或1和4,而我的蓝队总是有球员2和3或2和4。这是从来没有发生的,那个球员1是队红色。然而,如前所述,混合应该是完全随机的。

有人能帮我解决这个问题吗?或者有一个想法,我怎么能做到呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-01 11:15:03

这将是一个例子:

代码语言:javascript
运行
复制
<?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);

代码片段创建了一个播放器列表,您可以在其中使用玩家的数量。它首先洗牌球员,然后交替分配球队,如此均匀,最后再次排序的球员。

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

代码语言:javascript
运行
复制
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
        )

)
票数 1
EN

Stack Overflow用户

发布于 2020-06-01 11:24:51

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

之后,您有两个返回值的选项。第一个从$players数组中选择有符号的玩家数。然后,它返回一个数组与团队。

最后,另一种方式涉及与第一种方法相同的方法,但现在它也设置player对象的[team]变量。然后返回$players数组,但使用指定的团队名称。

代码语言:javascript
运行
复制
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;
}

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

代码语言:javascript
运行
复制
$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>";
}

给出以下输出:

阵列( ID => 4 name => Peter team => red )1 =>阵列( ID => 6名称=>ünther team => red )2 =>阵列( ID => 5名称=> chris team => blue )3 =>数组( ID => 7名称=> Max team => => )4 =>阵列( ID => 3名称olaf team #en20 20#蓝色)

数组( ID =>数组( ID => 3 name => olaf team => => )1 => Array ( ID => 5 => => 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 ))

数组( ID =>数组( ID => 3 name => olaf team => => )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 ))

数组( ID =>数组( ID => 6 name => günther team => => )1 => Array ( ID => 7 name => Max team => red )2 => Array ( ID => 3 name => olaf team => blue )3 => Array ( ID => 5 name => chris => blue )4 => Array (ID => 4 name => => team blue ))

数组( ID =>数组( 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 ))

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

票数 1
EN

Stack Overflow用户

发布于 2020-06-01 20:05:11

我知道有一个被接受的答案,但是我想我会把我的答案发出来,就像我昨晚开始研究这个问题一样,今天早上我就想出了答案……

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

使用颜色为表的样式: https://3v4l.org/ZUl5p

获取数组并使用foreach()进行迭代,然后使用rand()创建一个新的数组$checks,然后检查该新数组中是否存在值!in_array() && !array_key_exists(),如果没有,则迭代计数器并将新值和玩家名称推入新数组。我们将所有这些都封装在We循环中,检查计数器是否等于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值的球员的旧数组现在持有新分配的团队/s。

带有代码注释说明的基本代码:

代码语言:javascript
运行
复制
$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;
      }
    }     
  }

作为一个函数:

代码语言:javascript
运行
复制
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)); 是的一个输出,它使用上面的函数,每次调用时都会改变:

代码语言:javascript
运行
复制
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"
  }
}

与奇数播放器数组一起使用:

代码语言:javascript
运行
复制
$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)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62129357

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档