如何使用PHP多次模拟滚动骰子

时间:2016-07-10 07:33:33

标签: php probability dice

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

2 个答案:

答案 0 :(得分:0)

这是一个完整的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;
}

答案 1 :(得分:0)

这是一个简短的脚本,简单评论了什么。

<?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);