-2

We are talking about CSS and Javascript.

I want 10 CSS div's (a yellow square, a green square and a red square...) to appear randomly on the screen after a time period of 1-3sec.

Problem:

  • Choosing one out of 10 (or N in general) objects to appear at random: Must I build on the Math.random() method by using if between 0 and 0,1 choose the first object, if between 0,1 and 0,2 choose the second object etc., or is there a more scalable way?

edit: it seems that I communicated the problem in a wrong way. I know that Math.random() is a scalable solution, but to write if this than that 10 (or N) times is not. So how can I ask the computer to take one out of 10 (or N) elements. I've got the best answer from dystroy - take an array and shuffle it, and then take the first element. Thank you !

Gy Tis
  • 57
  • 2
  • 7
  • scramble an array, then choose the first N elements. – Denys Séguret May 05 '15 at 09:21
  • 1
    What do you mean by more scalable? Rephrasing your your proposed solution, for any N, you can use `Math.floor(Math.random()*N)` as the random index. – doldt May 05 '15 at 09:24
  • Try method to generate random number in specific range from this question http://stackoverflow.com/questions/1527803/generating-random-numbers-in-javascript-in-a-specific-range – user3272018 May 05 '15 at 09:25
  • i meant solving for N, not just for 10 – Gy Tis May 05 '15 at 10:21

3 Answers3

3

Date.now() % 10. Replace 10 with the number of divs. The now function supplies the number of epoch milliseconds.

Note that this solution does not produce truly random choices in the sense that the generated sequence of numbers passes statistical tests for randomness (at least nit at the same level as dedicated generators). However, for practical purposes, it will suffice (meaning unless you call now every few ms and/or clock the call to now to the timer; both of which i don't think is possible at all in a reliable way).

collapsar
  • 17,010
  • 4
  • 35
  • 61
  • Just to point out the obvious: This isn't random. But good luck to the user if they want to somehow try to do something at the *precise* millisecond to get the div they want. :-) (E.g., it may be random *enough*.) – T.J. Crowder May 05 '15 at 09:44
  • @T.J.Crowder Thanks for pointing out the (not so ;-)) obvious. Answer complemented – collapsar May 05 '15 at 09:58
1

Math.random is perfectly scalable. :-)

var index = Math.floor(Math.random() * 10);

...will give you an index that's 0 through 9. The general formula is:

value = Math.floor(Math.random() * (max - min)) + min;

...to get a value in the range min <= value < max, but when min is 0 (as it is when choosing things from a typical array), obviously we can simplify that a bit.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Math.random might sometime return 0.00718739, i just checked. So multiplying with 10 might not always work – wallop May 05 '15 at 09:36
  • 1
    @wishy The factor `10` just scales the output range from `[0,1[` to `[0, 10[`. Note that `0` is a valid array index! – collapsar May 05 '15 at 09:40
  • @Wishy: If you have 10 items in an array, the indexes are 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. So `Math.floor(Math.random() * 10)` works, it gives you one of those indexes, at random. – T.J. Crowder May 05 '15 at 09:43
  • @TJCrowder, ah yes i missed the (+ min) while analysing. good one though : ) – wallop May 05 '15 at 09:49
-2

This should help you. Note: Math.random might sometime get you 0.0071 or 0.071 etc meaning multiple 0 after decimal point so to be on safer side you 10000.

function getRandomNumber(curNumber) {
    var limit = 10;
    var minDecConv = 10000;
    var randomNumberWithinLimit = (Math.random() * minDecConv) % limit;
    if(randomNumberWithinLimit == curNumber) {
        return getRandomNumber(curNumber);
    }
    else {
        return randomNumberWithinLimit; //for better understanding, you can return directly
    }

}

var curNumber = 0;
var randomNo = getRandomNumber(curNumber);
wallop
  • 2,510
  • 1
  • 22
  • 39
  • That is no improvement over @TJCrowder's answer - `Math.random()`emulates a uniform distribution over the interval `[0, 1[`, there is no need to correct for distortions – collapsar May 05 '15 at 09:36
  • Both var index = Math.floor(Math.random() * 10); and value = Math.floor(Math.random() * (max - min)) + min; will not help in this particular scenario! It is not distortions, it wont even give out the required value between 0 and 10! – wallop May 05 '15 at 09:39
  • 1
    of course it does - just test it in the browser's js console. If you want `10` included, use `11` as the factor. And btw, why do you guard against identical consecutive results? Throwing a dice, you may end upwith a run of 6, too ... – collapsar May 05 '15 at 09:41
  • @collapsar - you can downvote if the answer is not right! Not when the approach is not optimal. Also the approach is not same as Crowders – wallop May 05 '15 at 09:44
  • 1
    The answer as it stands is wrong: The OP wanted a random choice among a number of divs, based on a uniform distribution (evidenced by his use of `Math.random`. He did not rule out identical results in consecutive choices (in fact, these will occur rather frequently in his previous setup). Note that the OP wasn't concerned about the statistical properties of his solution but wary of performance issues. – collapsar May 05 '15 at 09:48
  • Wrt downvote policy: No offence intended, but hover over the downvote arrow and read the text. Imho this covers wrong answers as well as sub-optimal ones and incidentally a lot of other criteria, too. – collapsar May 05 '15 at 10:03
  • i did hover over it before commentingm it says "This answer is not useful"! "The OP wanted a random choice among a number of divs," - thats what the solution gives "He did not rule out identical results in consecutive choices" - here is where i made a wrong decision! "but wary of performance issues" - right, shud ve seen properly! – wallop May 05 '15 at 10:05