Asmastas Maz
Asmastas Maz

Reputation: 397

Javascript probability

I am trying to make a realistic unbiased JavaScript dice using Math random object. I want a number from 2-12 to appear on the webpage when I click but it doesn't return. What is wrong with my code.

<html>
<head><title>DiceBoy</title>
</head>
<body>
<script>
function getRandom(){
  var num=Math.random();
  if(num < 0.0278) return 2; 
  else if(num < 0.0834) return 3;
  else if(num < 0.1667) return 4; 
    else if(num < 0.2778) return 5; 
      else if(num < 0.4167) return 6; 
        else if(num < 0.5834) return 7; 
          else if(num < 0.7223) return 8;
            else if(num < 0.8334) return 9; 
              else if(num < 0.9167) return 10; 
                else if(num < 0.9723) return 11;
                  else return 12;
                  var x=getRandom();
                  document.write(x);
}

</script>

<input type="button" value="Click Here" onClick="getRandom();">

</body>
</html>

Upvotes: 2

Views: 2690

Answers (6)

frenchie
frenchie

Reputation: 51947

Why not write it like this:

var RandomNumber1 = Math.floor(Math.random() * 6) + 1;
var RandomNumber2 = Math.floor(Math.random() * 6) + 1;

var DiceNumber = RandomNumber1 + RandomNumber2;

Upvotes: 4

user166390
user166390

Reputation:

The problem is that ..

var x=getRandom();
document.write(x);

is never called as the function "returns" before then. Move the code outside the function so that it can call the randomizing function and then use the result.

function getRandom () {
   // the long icky original code WITHOUT the following:
   // var x=getRandom();
   // document.write(x);
}
// later, OUTSIDE the function
var result = getRandom();
document.write(result);

However, a better way to get the same effect is to use:

function getDiceRole() {
   return Math.floor(Math.random() * 6) + Math.floor(Math.random() * 6) + 2
}

For readers: as for why two rolls are needed, see Statistics of Dice Roles - note how it is not an equal probability to get all the values. That is, a simple Math.floor(Math.random() * 11) + 2 is incorrect.

.. in the throw of two dice, the different possibilities for the total of the two dice are not equally probable because there are more ways to get some numbers than others.

Upvotes: 0

Daniel Li
Daniel Li

Reputation: 15389

Try this:

<html>
    <head>
        <title>DiceBoy</title>
    </head>
    <body>
        <script>
            function getRandom() {
                return (Math.floor(Math.random() * 6) + 1) * 2;
            }
        </script>
        <input type="button" value="Click Here" onClick="document.write(getRandom());">
    </body>
</html>

JSFiddle: http://jsfiddle.net/kvFE5/1/

You should ideally refactor this to be handled unobtrusively.

Although honestly - why aren't you using the Math.random...

Upvotes: 1

spy-killer
spy-killer

Reputation: 405

You can try something like his using the Math.floor which rounds a number downward to its nearest integer.

<html>
    <head>
        <title>DiceBoy</title>
    </head>
    <body>
        <script type="javascript/text">
            function getDieRoll() {
                return Math.floor(Math.random() * (12 - 1+ 1)) +1;
            }
        </script>
        <input type="button" value="Click Here" onClick="document.write(getDieRoll());">
    </body>
</html>  

Upvotes: 0

kiranvj
kiranvj

Reputation: 34127

Try something like this to generate random number between two numbers

/**
 * Returns a random integer between min and max
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

In your case call like

 getRandomInt (2, 12);

The full html will look like

<html>
<head>
<script type="text/javascript">
    /**
     * Returns a random integer between min and max
     * Using Math.round() will give you a non-uniform distribution!
     */
    function getRandomInt (min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    function generateNumber()
    {
       document.getElementById('generated-id').innerHTML = getRandomInt (2, 12);
    }

</script>
</head>
<body>
Generated number : <span id="generated-id"></span>
<input type="button" onclick="generateNumber();" value="Generate random number" />
</body>
</html>

Upvotes: 0

FloatingCoder
FloatingCoder

Reputation: 1724

Your return statments will exit the method when they are reached, and the rest of the code is not run. You also do not want to call your getRandom method from within the method, or you will have a never ending loop. Rather then returning the number (since no one is listening to the return value) store it in a variable and then use it in the last two lines.

function getRandom(){
  var num=Math.random();
  var result = 0;
  if(num < 0.0278) result = 2; 
  else if(num < 0.0834) result = 3;
    else if(num < 0.1667) result = 4; 
     .
     .
              else result =  12;
              document.write(result);
}

Upvotes: 0

Related Questions