ID:273060
 
mob
verb
RandomShiny()
var/randomcheck=1
while(randomcheck)
sCounter++
var/random=rand(1.8192)
if(random==8192)
alert(src, "OMFG")
winshow(usr, "shiny", 1)
winset(usr, "shiny.result", "text='It took [src.sCounter] times to retrieve a shiny.'")
sCounter=0
break
else
random=rand(1,8192)
sleep(0.1)

It's supposed to tell me how many times (each time it's set up) it'd take to get to 8192. The thing is, it takes AWHILE. I have never seen it get that far, anyway to make it go fast(er)?

I'd just like to see on average, how many times would it have to loop to get to that number.
Im not sure if you noticed, but you have var/random=rand(1.8192)

Shouldnt it be var/random=rand(1,8192)
sleep() does not take decimal arguments. sleep(0.1) is the same as sleep(1). Naturally, it's going to take a bit under 15 minutes on average.
Turn down tick_lag?
mob/verb/Random()
var/Counter=0
var/FoundCounter=0
var/X=0
for()
Counter++
X=rand(1,8192)
if(X==8192)
world<<"WINS"
FoundCounter++
if(Counter>10000)
sleep(1)
Counter=0
if(FoundCounter>20)
world<<"DUN!"
break


You should be able to raise the 1000 to 10,000 and not have a problem, if I was to guess. Just keep raising that until your CPU reaches near 100% of one core.

EDIT: Just ran this. You can throw 1,000 up to 10,000 with no problems at all. 1,000 used up 1% on my 2 GHZ processor.

With it running at 10k checks per tick it takes like three second to finish randoming that number over 20 times.

EDIT: Changed to the new code I actually compiled and ran.
In response to AJX
With it running at 10k checks per tick it takes like three second to finish randoming that number over 20 times

Hehe, without worrying about sleeping at all I can run it 1,000 times in 3.5 seconds.

Finished: 3.5 seconds (0.0035/trial)
In executing 1000 trials, it was found that an average of 7954.19 attempts were needed to randomly generate 8192.


However, more on topic, I'm just going to mention that when you run larger trials you are going to get closer and closer to one occurrence per 8192 trials.

For Example:

When testing a single trial, events can reach extremes.

From the low-end:
Finished: 0 seconds (0/trial)
In executing 1 trials, it was found that an average of 125 attempts were needed to randomly generate 8192.


To the high-end:
Finished: 0 seconds (0/trial)
In executing 1 trials, it was found that an average of 25508 attempts were needed to randomly generate 8192.


However,

when testing..
Finished: 0 seconds (0/trial)
In executing 10 trials, it was found that an average of 4764.9 attempts were needed to randomly generate 8192.


increasingly..
Finished: 0.3 seconds (0.003/trial)
In executing 100 trials, it was found that an average of 6914.24 attempts were needed to randomly generate 8192.


higher..
Finished: 3.8 seconds (0.0038/trial)
In executing 1000 trials, it was found that an average of 8452.2 attempts were needed to randomly generate 8192.


trial..
Finished: 35.9 seconds (0.00359/trial)
In executing 10000 trials, it was found that an average of 8098.11 attempts were needed to randomly generate 8192.


counts,
Finished: 384 seconds (0.00384/trial)
In executing 100000 trials, it was found that an average of 8153.92 attempts were needed to randomly generate 8192.


you get closer and closer to an average of 8192.

Moral of the story?
One player could find a shiny within a few hundred battles whereas another could take many more than 8192 to find one. The long run says that the average will be 8192 encounters.
In response to AJX
Instead of using an empty for() there it would be better to just have while(FoundCounter < 20).

Saves having to do the last if() there and having to manually break the loop. While internally both methods may end up pretty similar when compiled, it'll make your code less cluttered and easier to read since you'd know exactly what the loop relied on without having to look through the loop for your conditional.

You're also checking the break conditional AFTER the sleep() call, so when that call is reached it'll delay the final conditional instead of only delaying the loop.
The chance of not getting a shiny after n trials is (8191/8192)**n. At 10,000 trials, you've still got a ~29% chance to have not gotten a shiny - at 100,000, it's a >99% chance you've found a shiny. Break-even point is (log 0.5) / (log (8191/8192)) ~= 5678 trials (That is, when you've got a 50/50 chance of having found a shiny)
In response to Nadrew
Nadrew wrote:
Instead of using an empty for() there it would be better to just have while(FoundCounter < 20).

True

Saves having to do the last if() there and having to manually break the loop. While internally both methods may end up pretty similar when compiled, it'll make your code less cluttered and easier to read since you'd know exactly what the loop relied on without having to look through the loop for your conditional.

True

You're also checking the break conditional AFTER the sleep() call, so when that call is reached it'll delay the final conditional instead of only delaying the loop.

True

Meh. Was just an example. :P -.-'