简体   繁体   中英

Javascript - Math.random improvements

I'm currently working on a small game that needs to return either 1,2 or 3.

The idea is that I then compare two numbers and the greater wins.

The code i'm using is this:

var isMultipleOf, number1, number2, random;

random = function(number) {
  return isMultipleOf(Math.floor((Math.random() * number) + 1));
};

isMultipleOf = function(number) {
  if (number % 2 === 0) {
    return 1;
  }
  if (number % 3 === 0) {
    return 2;
  } else {
    return 3;
  }
};

number1 = random((Math.random() * 100) + 1);
number2 = random((Math.random() * 100) + 1);

console.log("number 1 is " + number1 + " and number2 is " + number2);

This code works, but i'd like to improve it a bit if possible.

With my game, a draw is possible, but with my current logic it happens quite often and I don't like it. Can you suggest a better way to improve this making it less possible to get a draw (same numbers)?

thanks

The reason why your code has so many ties is your distribution is really messed up.

 isMultipleOf = function(number) { if (number % 2 === 0) { return 1; } if (number % 3 === 0) { return 2; } else { return 3; } }; var results = [0,0,0]; for (var i=1; i<=100; i ++ ){ results[isMultipleOf(i)-1] += 1 } console.log(results) 

Chance of 1: 50
Chance of 2: 17
Chance of 3: 33

If you want better results, than just use random and divide it into 3 parts.

 getNum = function(number) { if (number < .33) { return 1; } if (number < .67) { return 2; } else { return 3; } }; var results = [0,0,0]; for (var i=1; i<=100; i ++ ){ var rn = Math.random() results[getNum(rn)-1] += 1 } console.log(results) 

Currently you select a random number from 1 to 100, select another random number less than or equal to the first, and then if the second number is a multiple of 2 return 1, multiple of 3 but not 2 return 2, else return 3.

Why not just pick two random numbers between 1 and 3?

var rnd = Math.floor(Math.random() * 3) + 1;  // 1 2 or 3, with 1/3 probability

Another option is for each of the numbers to be drawn from a known pool (like a lottery), guaranteeing there are no ties.

 //start with an ordered array var nums = [1,2,3]; // fisher-yates shuffle for (var i=nums.length - 1; i > 0; i--) { var r = Math.floor(Math.random() * (i + 1)); var tmp = nums[r]; nums[r] = nums[i]; nums[i] = tmp; } // any two elements can be our drawn numbers alert("first: " + nums[0] + ", second: " + nums[1]); 

First of all, do you want to have a draw or maybe it's better just to make another randomization when you have it until there will be winning side or just make it another time to lower chances for a draw? The easiest way would be of course adding more number so statistically there would be fewer chances for a draw.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM