【问题标题】:How to simulate rolling dice multiple times using PHP如何使用 PHP 多次模拟掷骰子
【发布时间】:2016-11-12 09:11:08
【问题描述】:

我想使用 PHP 模拟掷两个六面骰子 X 次,以查看每种可能的组合实际发生的频率(2、3、4、5、6、7、8、9、10、11 或12)。什么是一个好的起点?

【问题讨论】:

    标签: php probability dice


    【解决方案1】:

    这是一个完整的 PHP 脚本,它将模拟掷两个骰子的次数,然后显示每次掷骰结果的总和:

    <?php
    
    /**
     * If your machine is low on memory, try uncommenting the following line:
     */
    //ini_set('memory_limit', '512M');
    
    /**
     * If you still don't have enough memory, reduce the value of $number_of_rolls
     * Note: with memory_limit at 512M, the max number of times I can roll at a time
     * is about 325000
     */
    $number_of_rolls = 20000;
    print dice_roll_output($number_of_rolls);
    
    /**
     * Array of 6 sides in a single die
     */
    function die_render() {
      $die = array(1 => 1, 2, 3, 4, 5, 6);
      return $die;
    }
    
    /**
     * Roll a single die
     */
    function die_roll($die_sides) {
      // First function (less random)
      //$number_rolled = array_rand($die_sides);
    
      // Second function (more random)
      $number_rolled = mt_rand(1, count($die_sides));
    
      return $number_rolled;
    }
    
    /**
     * Roll both dice
     */
    function dice_roll() {
      // Create the first die
      $die1 = die_render();
      // Create the second die
      $die2 = die_render();
      // Roll the first die
      $die_roll_1 = die_roll($die1);
      // Roll the second die
      $die_roll_2 = die_roll($die2);
      // Add the two rolls up to get the total
      $total = $die_roll_1 + $die_roll_2;
      // Return the first die, second die, and the total of the two
      return array($die_roll_1, $die_roll_2, $total);
    }
    
    /**
     * Much of this function is not necessary unless the
     * area toward the bottom is un-commented out.
     */
    function dice_roll_output($numrolls) {
      $numrolls = (int) $numrolls;
      // Abort if $numrolls is less than 1
      if ($numrolls < 1) {
        return 'Number of rolls must be greater than zero';
      }
      $rolled_arr = array();
      $die1 = array();
      $die2 = array();
      $dice_sum = array();
      for ($i = 0; $i < $numrolls; $i++) {
        $dice_roll[$i] = dice_roll();
        $die1[$i] = $dice_roll[$i][0];
        $die2[$i] = $dice_roll[$i][1];
        $dice_sum[$i] = $dice_roll[$i][2];
        $rolled_arr[$i] = array($die1[$i], $die2[$i], $dice_sum[$i]);
      }
      // How many times each total (somewhere between 2 and 12) was rolled
      $frequencies = array_count_values($dice_sum);
      // Sort the displayed output from high to low
      arsort($frequencies);
      // For later use with calculating percentages
      $rolled_tot = array_sum($frequencies);
      // Begin actual display -- line 1
      $out = "<pre><b>Rolled\t\tFrequency\tPercent</b>\n";
      // Double-checking to make sure all percentages add up to 100%
      $freqency_total = 0;
      foreach ($frequencies as $dice_roll => $frequency) {
        // Don't round the numbers using number_format until after they've been used
        // for double-checking
        $percent_raw = ($frequency / $rolled_tot) * 100;
        // Add to the running total of the double-checked percentage
        $freqency_total += $percent_raw;
        // Now we can round the numbers up to two decimal places
        $percent_display = number_format($percent_raw, 2);
        // More display -- should be 11 lines maximum (lines 2 through 12)
        $out .= "{$dice_roll}\t\t{$frequency}\t\t{$percent_display}\n";
      }
      // Format the running total of the double-checked percentage (optional)
      $freqency_total = number_format($freqency_total, 2);
      // Aesthetic purposes only
      $out .= "\t\t\t\t-----\n";
      // Line 13 of the display
      $out .= "\t\t\t\t{$freqency_total}%\n";
    
      // The following is the above-referenced "area toward the bottom"
      // NB: displaying this part could cause a LOT of output to be displayed
    
      /*
      if (!empty($rolled_arr)) {
        // Uncomment the next line if you want to sort the output
        //array_multisort($dice_sum, SORT_DESC, $rolled_arr);
    
        // Aesthetic purposes only
        $out .= "---------------------------------------\n";
        // Line 14 of the display
        $out .= "<b>Die #1\t\tDie #2\t\tTotal</b>\n";
        foreach ($rolled_arr as $key => $arr) {
           // Lines 15 and up of the display -- quantity determined by $numrolls
           $out .= "{$arr[0]}\t\t{$arr[1]}\t\t{$arr[2]}\n";
        }
      }
      */
      // End actual display
      $out .= "</pre>";
      return $out;
    }
    

    【讨论】:

      【解决方案2】:

      这是一个简短的脚本,其中包含关于做什么的简单 cmets。

      <?php
      
      // this will be our final result
      $combinations = array();
      
      // for as many times as we want to run the experiment (1000 here)
      for ($i = 0; $i < 1000; $i++) {
        // mt_rand returns random whole number in the specified range 
        $die1roll = mt_rand(1, 6);
        $die2roll = mt_rand(1, 6);
      
        // add the sum of two dice
        $sum = $die1roll + $die2roll;
      
        // if this sum hasn't happened yet, mark it so - it's happened zero times
        if (!isset($combinations[$sum])) $combinations[$sum] = 0;
      
        // increase number of times this sum has happened
        $combinations[$sum] += 1;
      }
      
      // order the results array by keys (sums) ascending
      ksort($combinations);
      
      // print it out
      print_r($combinations);
      

      【讨论】:

        猜你喜欢
        • 2018-10-19
        • 2011-07-12
        • 2016-02-07
        • 2018-01-03
        • 2019-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多