【问题标题】:Create 3 random int params with sum of 100创建 3 个随机 int 参数,总和为 100
【发布时间】:2021-08-31 12:25:24
【问题描述】:

我需要创建一个具有 3 个属性的播放器:

  • 寿命(必须是 1 到 100 之间的随机整数);
  • 攻击(必须是 1 到 100 之间的随机整数);
  • 防御(必须是从 1 到 100 的随机整数); 但是所有属性的总和必须是 200(生命 + 攻击 + 防御 = 200)。不多也不少。 我试着做这样的事情:
public function initPlayer(){
        $life = random_int(1, 100);
        $attack = random_int(1, 100);
        $lifeAttack = $life + $attack;
        if($lifeAttack >= 100) {
            $defense = 200 - $lifeAttack;
        } else {
            $defense = random_int(1, 100);
        }
        echo $life . '-' . $attack . '-' . $defense;
    }

但只有当两个参数之和等于或大于 100 时它才能正常工作。

【问题讨论】:

标签: php


【解决方案1】:

如果生命+攻击+防御这三个值是1..100范围内的实随机数,那么总数只有200的概率很低。 当计算第三个值时,它不再是随机的了。

正确的解决方案是:3个值必须反复确定,直到总数等于200。

for($sum = 0;$sum !== 200;){
   $life = random_int(1, 100);
   $attack = random_int(1, 100);  
   $defense = random_int(1, 100);
   $sum = $life + $attack + $defense;
}

var_dump($life,$attack,$defense,$life + $attack + $defense);

输出示例:

int(65) int(77) int(58) int(200)

【讨论】:

  • 我明白,但这是任务的条件。
【解决方案2】:

这基本上是因为$lifeAttack 必须大于 100 才能满足您的所有条件。如果不是,您可以递归,如下所示:

public function initPlayer()
{
    $life = random_int(1, 100);
    $attack = random_int(1, 100);
    $lifeAttack = $life + $attack;
    if($lifeAttack >= 100) {
        $defense = 200 - $lifeAttack;
    } else {
       $this->initPlayer();
       return;
    }
    echo $life . '-' . $attack . '-' . $defense;
}

当然,你也可以不用递归来做同样的事情。也许从函数中返回这些值会很好?

【讨论】:

  • 它可以工作,但有时会显示“致命错误:未捕获的错误:调用未定义的函数 initPlayer()”。
  • @SlimBoyFat:那是因为它是类中的一个方法。您应该使用$this->initPlayer(); 而不是initPlayer();。我没有注意到这是一种方法。我改变了答案。
  • 我已经完成了,谢谢,它有效:)
【解决方案3】:

检查这个算法,它会在定义的范围内产生一个具有定义总和的值数组:

function generate_values($total, $range_min, $range_max, $nb_values) {
    // impossible conditions
    if($total < $range_min*$nb_values || $total > $range_max*$nb_values) {
        return null;
    }

    $values = [];
    
    for($i=0; $i<$nb_values; $i++) {
        $current_total = $total - array_sum($values);
        
        // the last value is the remaining total
        $value = $current_total;
        if( $i < ($nb_values-1) ) {
            $current_range_min = max($range_min, $current_total - ($nb_values-$i-1)*$range_max);
            $current_range_max = min($range_max, $current_total - ($nb_values-$i-1)*$range_min);
            $value = rand($current_range_min, $current_range_max);
        }
        
        array_push($values, $value);
    }
    
    shuffle($values);
    return $values;
}

// test with your needs
for($i=0; $i<10; $i++) {
    $values = generate_values(200, 1, 100, 3);
    var_dump($values, array_sum($values));
}

【讨论】:

  • 写得不是很好,但逻辑在那里。
【解决方案4】:

这将是我天生随机的只有 2 个数字的情况。我建议首先将生命从 1 随机化到 100,并将攻击上限设置为 100 -$life (I.e. 1 to 100 - $life) 。最后,防御将被预先确定为 100 - lifeAttack。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-23
    • 2011-11-09
    • 2014-01-16
    • 2012-03-16
    • 2013-12-11
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多