【问题标题】:Percentage chances on winning multiple prizes赢得多个奖项的机会百分比
【发布时间】:2016-02-24 07:11:34
【问题描述】:

我正在编写一个脚本来处理用户单击按钮时获胜的百分比。 在此主题php - Chance of winning 的帮助下。我使用了以下代码:

function winningChance($percentage) {
    if($percentage < 1 || $percentage > 100) throw new Exception('Invalid percentage');
    global $result;
    if(rand(1, 100) <= $percentage) {
        $result = 'won';
    } else {
        $result = 'lost';
    }
    return $result;
}

echo "you have ".winningChance(50).'!'; 

此脚本运行后,它会在 SQL 数据库中注册用户名/姓氏/电子邮件和名为 winner 的字段和 $result

这很好用,但是我想处理具有不同中奖机会百分比的多个奖项。

假设第 1 奖有 20% 的机会中奖, 奖品2 30% 的机会 和奖品3 50% 的机会。 如果我使用winningChance(20)winningChance(30)winningChance(50),用户将有更多获胜的机会。我该如何处理呢,多个奖品的赢/输过程发生在同一个函数中?

【问题讨论】:

  • 您要同时还是随机检查 20%、30% 和 50%?
  • 为什么是global $result;
  • 我不确定我是否关注过你。是否有 100% 的总机会获胜?或者是 1% 的中奖几率,如果你中奖了,就有 x0% 的几率中奖?
  • @YatinTrivedi 基本上我想同时检查 3 个价格,一个有 20% 的机会,另一个 30% 和最后一个 50%
  • @jackflash 我将 $result 设为全局变量,因为我需要它在函数之外将结果注册到数据库中

标签: php


【解决方案1】:

如果我理解正确的话,中奖的机会取决于价格。

function getChanceOfWinning($price)
{
  $chances = array(
    10 => 20,
    20 => 30,
    30 => 50
  );
  if (isset($chances[$price])) {
    return $chances[$price];
  }
  return 0; // <-- default chance
}

function calculateWinningChance($price)
{
  $chance = getChanceOfWinning($price);
  $calc   = rand(1, 100);

  if ($calc <= $chance) {
    return true;
  }
  return false;
}

function calculateWinningChances(array $prices)
{
  $results = array();
  foreach($prices as $price) {
    $results[$price] = calculateWinningChance($price);
  }
  return $results;
}

var_dump(calculateWinningChances(array(10,20, 30,40,700)));

【讨论】:

    【解决方案2】:

    这个解决方案怎么样?

    function roll( $iChance ) {
            $iCursor = rand( 0,99 );
            $aModel = array();
            while ( count( $aModel ) != $iChance ) {
                $iRandValue = rand( 0,99 );
                if ( !in_array( $iRandValue, $aModel ) ) {
                    $aModel[] = $iRandValue;
                }
            }
            return in_array( $iCursor, $aModel );
        }
    

    编辑:更多性能:

    function roll( $iChance ) {
        $iChance = ceil( ( $iChance > 100 ) ? 100 : (int)$iChance);
        $iCursor = rand( 0, 99 );
        $aModel = range( 0, 99 );
        shuffle( $aModel );
        return in_array( $iCursor, array_slice( $aModel, 0, $iChance ) );
    }
    

    【讨论】:

    • 您好,感谢您花时间提供答案,它是否比嵌套 if 语句更准确?你能解释一下代码吗?谢谢
    • 我更改了函数以获得更好的性能和更高的可读性逻辑。
    【解决方案3】:

    如果我理解正确,您希望同时为每个用户进行多次获胜计算,彼此独立。有很多方法可以做到这一点。例如,修改您的函数,以便您可以将关联数组作为参数传递。

    该数组将是价格=>百分比值的映射,然后您对每一对进行计算。 您还需要修改数组中的结果变量,并且在每次传递时只需将计算结果推入其中。您还可以在此处使用关联数组来显示价格=>赢/输。遍历所有对并用结果填充结果变量后,只需返回变量即可。

    根据您的上一条评论,这是您需要的:

    function winningChance($percentage) {
        foreach($percentage as $p) {
            if($p < 1 || $p > 100) 
                throw new Exception('Invalid percentage');
        }
        if (count($percentage) != 3)
            throw new Exception('Three prizes need to be defined');
    
        $rand = rand(1, 100); // generate the random chance only once!
    
        if ($rand <= $percentage[0])
            $result = 'won first prize';
        elseif ($rand <= $percentage[1])
            $result = 'won second prize';
        elseif ($rand <= $percentage[2])
            $result = 'won third prize';
        else
            $result = 'lost';
    
        return $result;
    }
    

    然后像这样调用函数:

    //the array contains probability percentages for the first, second and third place respectively
    $res = winningChance( array(20, 30, 50) );
    echo "You have $res!";
    // write $res to the db here
    

    【讨论】:

    • 这很难正确解释,因为英语不是我的妈妈丁字裤。但基本上计算应该同时附加(当用户提交他的姓名/姓氏/邮件时)并且应该只赢得 3 个价格中的一个,每个价格都有自己的百分比机会。
    • 继续尝试,给我们一个示例场景。
    • @LorenzoPirondini 试试这个。
    • @shmoz 效果很好,谢谢,我只需要添加 return $result;在最后一个 else if 之后,以便在 echo 上输出结果。
    • @shmoz 实际上,“返回”问题来自您较早的回复,我的评论与您的​​编辑交叉。我刚刚使用了您所做的最后一次编辑,它非常适合仅抛出一次随机机会,在另一种情况下,胜利似乎经常发生。感谢您的帮助。
    【解决方案4】:

    调整你的函数代码,例如,

    instead of,
    
    if(rand(1, 100) <= $percentage) {
        $result = 'won';
    } else {
        $result = 'lost';
    }
    

    到,

    if(rand(1, 100) >= 50) {
        $result = 'won third price';
    } else if(rand(1, 100) >= 30) {
        $result = 'won second price';
    }
    else if(rand(1, 100) >= 20) {
        $result = 'won first price';
    }
    else
    {
        $result='lost';
    }
    

    【讨论】:

    • 是的,这很不错,但就确切的机会而言,usre 首先有 50% 的机会赢得第三个价格,然后是 30% 赢得第二个价格,然后是 20% 赢得第一个价格,这让我赢得第一名的机会不到 20%,这是正确的还是我错过了什么?
    • 用例子在这里写下你确切需要的案例
    猜你喜欢
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 2021-04-02
    相关资源
    最近更新 更多