EZ Server

General Category => Quest and Guides => Topic started by: Drajor on July 29, 2015, 06:04:16 am



Title: Rainbow Crystals: When should you gamble?
Post by: Drajor on July 29, 2015, 06:04:16 am
TLDR; Always gamble.

A few days ago someone asked in ooc whether or not you should gamble your rainbow crystals. Zexan answered with some (basically correct) math as why you should always gamble, his answer was;
Quote
If it's as I think it is, which is turn in 2 4000 AA crystals, 33% of time you get a 20k crystal otherwise you get 1 back, then (.33*20000)+(.67*4000)=9280 average return on 8000 investment

Zexan is correct, the theoretical return on every AA gambled is 1.16. But this is only true if you don't re-gamble your return on losses! The math to calculate that is beyond my knowledge, so I wrote a small program to basically brute force a result which is closer to the truth than 1.16. The answer I came up with is 1.23.

So the program I wrote simulates a player starting with 100 minor crystals and 20 lesser crystals. They gamble their minor crystals until they have 0 or 1 left and do the same for the lesser. The simulation does this 1 million times and spits out some really basic statistics about what occurred. The results;
Quote
Total Trials: 1,000,000
Average Initial AA: 280,000
Average Final AA: 346,249
Worst Final AA: 146,000
Best Final AA: 550,000
Total Increase: 947,193 (94.72%)
Total Decrease: 52,807 (5.28%)

--- Minor Gambles ---
Total: 74,621,484
Average: 74
Min: 60
Max: 89
--- Minor Gambles (Win) ---
Total: 24,627,128 (33.00%)
Average: 24
Min: 10
Max: 39
--- Minor Gambles (Lose) ---
Total: 49,994,356 (67.00%)
Average: 49
Min: 21
Max: 79

--- Lesser Gambles ---
Total: 14,474,683
Average: 14
Min: 10
Max: 19
--- Lesser Gambles (Win) ---
Total: 4,773,367 (32.98%)
Average: 4
Min: 0
Max: 10
--- Lesser Gambles (Lose) ---
Total: 9,701,316 (67.02%)
Average: 9
Min: 0
Max: 19

In summary, out of 1 million trials;
  • The average ROI was ~1.23
  • You have a ~95% chance to increase your value
  • 947,193 increased their total AA value
  • 52,807 decreased their total AA value
  • The most lucky trial gained 270,000 AA (ROI ~1.96)
  • The least lucky trial lost 134,000 AA (ROI ~0.52)

I did this fairly hastily this evening so please point out any mistakes and I can run the trials again. I will post the source code (python) in a reply.


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Drajor on July 29, 2015, 06:08:17 am
Code:
import random
import sys

# The number of crystals trials start with.
StartMinor = 100
StartLesser = 20
StartGreater = 0
StartMajor = 0

# The chance a gamble succeeds.
Chance = 33

class Trial:
    mInitialValue = 0

    mMinor = 0
    mTotalMinorGambles = 0
    mMinorWin = 0
    mTotalMinorLose = 0
   
    mLesser = 0
    mTotalLesserGambles = 0
    mLesserWin = 0
    mLesserLose = 0
   
    mGreater = 0
    mMajor = 0

    mGain = 0
   
    def __init__(self, pMinor, pLesser, pGreater, pMajor) :
        self.mMinor = pMinor
        self.mLesser = pLesser
        self.mGreater = pGreater
        self.mMajor = pMajor
        self.mInitialValue = self.getTotalValue()

    def getMinorValue(self):
        return self.mMinor * 2000

    def getLesserValue(self):
        return self.mLesser * 4000

    def getGreaterValue(self):
        return self.mGreater * 10000

    def getMajorValue(self):
        return self.mMajor * 20000

    def getTotalValue(self):
        return self.getMinorValue() + self.getLesserValue() + self.getGreaterValue() + self.getMajorValue()

    def getInitialValue(self):
        return self.mInitialValue

    def roll(self):
        return random.randint(0, 99) < Chance
   
    def run(self):
            # Gamble minor crystals.
        while self.mMinor > 1:
            self.mTotalMinorGambles += 1
            # we lose 2 minor and gain a greater.
            if self.roll():
                self.mMinor -= 2
                self.mGreater += 1
                self.mMinorWin += 1
            # we lose 1 minor.
            else:
                self.mMinor -= 1
                self.mTotalMinorLose += 1

        # Gamble lesser crystals.
        while self.mLesser > 1:
            self.mTotalLesserGambles += 1
            # we lose 2 lesser and gain a major
            if self.roll():
                self.mLesser -= 2
                self.mMajor += 1
                self.mLesserWin += 1
            # we lose 1 lesser.
            else:
                self.mLesser -= 1
                self.mLesserLose += 1
        self.mGain = self.getTotalValue() - self.mInitialValue

    def printResults(self):
        print("Initial Value: " + str(self.mInitialValue))
        print("Final Value: " + str(self.getTotalValue()))
        print("Value Difference: " + str(self.getTotalValue() - self.mInitialValue))
        print("Minor Attempts: " + str(self.mTotalMinorGambles))
        print("Minor Win: " + str(self.mMinorWin) + " (%.2f%%)" % (self.mMinorWin / self.mTotalMinorGambles * 100))
        print("Minor Lose: " + str(self.mTotalMinorLose) + " (%.2f%%)" % (self.mTotalMinorLose / self.mTotalMinorGambles * 100))
        print("Lesser Attempts: " + str(self.mTotalLesserGambles))
        print("Lesser Win: " + str(self.mLesserWin) + " (%.2f%%)" % (self.mLesserWin / self.mTotalLesserGambles * 100))
        print("Lesser Lose: " + str(self.mLesserLose) + " (%.2f%%)" % (self.mLesserLose / self.mTotalLesserGambles * 100))

class MultiTrial:
    mNumTrials = 0
   
    mTotalMinorGambles = 0
    mMinMinorGambles = sys.maxsize
    mMaxMinorGambles = -sys.maxsize

    mTotalMinorWin = 0
    mMinMinorWin = sys.maxsize
    mMaxMinorWin = -sys.maxsize
   
    mTotalMinorLose = 0
    mMinMinorLose = sys.maxsize
    mMaxMinorLose = -sys.maxsize
   
    mTotalLesserGambles = 0
    mMinLesserGambles = sys.maxsize
    mMaxLesserGambles = -sys.maxsize
   
    mTotalLesserWin = 0
    mMinLesserWin = sys.maxsize
    mMaxLesserWin = -sys.maxsize
   
    mTotalLesserLose = 0
    mMinLesserLose = sys.maxsize
    mMaxLesserLose = -sys.maxsize

    mIncreased = 0
    mDecreased = 0

    mInitialValue = 0
    mFinalValue = 0

    mMinFinalValue = sys.maxsize
    mMaxFinalValue = 0
   
    def __init__(self, pNumTrials):
        self.mNumTrials = pNumTrials

    def addResults(self, pTrial):

        ##
        ## Minor Gambles
        ##
       
        self.mTotalMinorGambles += pTrial.mTotalMinorGambles

        # Record min minor gambles.
        if self.mMinMinorGambles > pTrial.mTotalMinorGambles:
            self.mMinMinorGambles = pTrial.mTotalMinorGambles

        # Record max minor gambles.
        if self.mMaxMinorGambles < pTrial.mTotalMinorGambles:
            self.mMaxMinorGambles = pTrial.mTotalMinorGambles

        self.mTotalMinorWin += pTrial.mMinorWin

        # Record min minor win.
        if self.mMinMinorWin > pTrial.mMinorWin:
            self.mMinMinorWin = pTrial.mMinorWin

        # Record max minor win.
        if self.mMaxMinorWin < pTrial.mMinorWin:
            self.mMaxMinorWin = pTrial.mMinorWin
       
        self.mTotalMinorLose += pTrial.mTotalMinorLose

        # Record min minor lose.
        if self.mMinMinorLose > pTrial.mTotalMinorLose:
            self.mMinMinorLose = pTrial.mTotalMinorLose

        # Record max minor lose.
        if self.mMaxMinorLose < pTrial.mTotalMinorLose:
            self.mMaxMinorLose = pTrial.mTotalMinorLose

        ##
        ## Lesser Gambles
        ##

        self.mTotalLesserGambles += pTrial.mTotalLesserGambles

        # Record min lesser gambles.
        if self.mMinLesserGambles > pTrial.mTotalLesserGambles:
            self.mMinLesserGambles = pTrial.mTotalLesserGambles

        # Record max lesser gambles.
        if self.mMaxLesserGambles <  pTrial.mTotalLesserGambles:
            self.mMaxLesserGambles = pTrial.mTotalLesserGambles

        self.mTotalLesserWin += pTrial.mLesserWin

        # Record min lesser win.
        if self.mMinLesserWin > pTrial.mLesserWin:
            self.mMinLesserWin = pTrial.mLesserWin

        # Record max lesser win.
        if self.mMaxLesserWin < pTrial.mLesserWin:
            self.mMaxLesserWin = pTrial.mLesserWin

        self.mTotalLesserLose += pTrial.mLesserLose

        # Record min lesser lose.
        if self.mMinLesserLose > pTrial.mLesserLose:
            self.mMinLesserLose = pTrial.mLesserLose

        # Record max lesser lose.
        if self.mMaxLesserLose < pTrial.mLesserLose:
            self.mMaxLesserLose = pTrial.mLesserLose

        self.mInitialValue += pTrial.mInitialValue
        self.mFinalValue += pTrial.getTotalValue()

        # Record number of trials that resulted in an increase. (or even)
        if pTrial.getTotalValue() >= pTrial.getInitialValue():
            self.mIncreased += 1

        # Record trials that resulted in a decrease.
        if pTrial.getTotalValue() < pTrial.getInitialValue():
            self.mDecreased += 1

        if pTrial.getTotalValue() < self.mMinFinalValue:
            self.mMinFinalValue = pTrial.getTotalValue()

        if pTrial.getTotalValue() > self.mMaxFinalValue:
            self.mMaxFinalValue = pTrial.getTotalValue()

    def run(self):
        for i in range(0, self.mNumTrials):
            t = Trial(StartMinor, StartLesser, StartGreater, StartMajor)
            t.run()
            self.addResults(t)

    def printResults(self):
        print("Total Trials: " + format(self.mNumTrials, ",d"));
        print("Average Initial AA: " + format(int(self.mInitialValue / self.mNumTrials), ",d"))
        print("Average Final AA: " + format(int(self.mFinalValue / self.mNumTrials), ",d"))
        print("Worst Final AA: "  + format(int(self.mMinFinalValue), ",d"))
        print("Best Final AA: "  + format(int(self.mMaxFinalValue), ",d"))
        print("Total Increase: "  + format(int(self.mIncreased), ",d") + " (%.2f%%)" % (self.mIncreased / self.mNumTrials * 100))
        print("Total Decrease: "  + format(int(self.mDecreased), ",d") + " (%.2f%%)" % (self.mDecreased / self.mNumTrials * 100))

        print("")
        print("--- Minor Gambles ---")
        print("Total: " + format(int(self.mTotalMinorGambles), ",d"))
        print("Average: " + format(int(self.mTotalMinorGambles / self.mNumTrials), ",d"))
        print("Min: " + format(int(self.mMinMinorGambles), ",d"))
        print("Max: " + format(int(self.mMaxMinorGambles), ",d"))
        print("--- Minor Gambles (Win) ---")
        print("Total: " + format(int(self.mTotalMinorWin), ",d") + " (%.2f%%)" % (self.mTotalMinorWin / self.mTotalMinorGambles * 100))
        print("Average: " + format(int(self.mTotalMinorWin / self.mNumTrials), ",d"))
        print("Min: " + format(int(self.mMinMinorWin), ",d"))
        print("Max: " + format(int(self.mMaxMinorWin), ",d"))
        print("--- Minor Gambles (Lose) ---")
        print("Total: " + format(int(self.mTotalMinorLose), ",d") + " (%.2f%%)" % (self.mTotalMinorLose / self.mTotalMinorGambles * 100))
        print("Average: " + format(int(self.mTotalMinorLose / self.mNumTrials), ",d"))
        print("Min: " + format(int(self.mMinMinorLose), ",d"))
        print("Max: " + format(int(self.mMaxMinorLose), ",d"))

        print("")
        print("--- Lesser Gambles ---")
        print("Total: " + format(int(self.mTotalLesserGambles), ",d"))
        print("Average: " + format(int(self.mTotalLesserGambles / self.mNumTrials), ",d"))
        print("Min: " + format(int(self.mMinLesserGambles), ",d"))
        print("Max: " + format(int(self.mMaxLesserGambles), ",d"))
        print("--- Lesser Gambles (Win) ---")
        print("Total: " + format(int(self.mTotalLesserWin), ",d") + " (%.2f%%)" % (self.mTotalLesserWin / self.mTotalLesserGambles * 100))
        print("Average: " + format(int(self.mTotalLesserWin / self.mNumTrials), ",d"))
        print("Min: " + format(int(self.mMinLesserWin), ",d"))
        print("Max: " + format(int(self.mMaxLesserWin), ",d"))
        print("--- Lesser Gambles (Lose) ---")
        print("Total: " + format(int(self.mTotalLesserLose), ",d") + " (%.2f%%)" % (self.mTotalLesserLose / self.mTotalLesserGambles * 100))
        print("Average: " + format(int(self.mTotalLesserLose / self.mNumTrials), ",d"))
        print("Min: " + format(int(self.mMinLesserLose), ",d"))
        print("Max: " + format(int(self.mMaxLesserLose), ",d"))           

mt = MultiTrial(1000000)
mt.run()
mt.printResults()



Title: Re: Rainbow Crystals: When should you gamble?
Post by: Darpey on July 29, 2015, 09:34:05 am
Good stuff - interesting program results.

I agree - however, the only time I could recommend possibly not gambling is with your first 1-2 crystals. If your toon only has 200 AA's, I would go ahead and take the 2,000 guaranteed, rather than gamble on 10,000.


Title: Re: Rainbow Crystals: When should you gamble?
Post by: slaughterhaus on July 29, 2015, 10:05:55 am
Great stuff - now to figure out how to get 100 crystals to put it to the test :P


Deadend


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Phah on July 29, 2015, 07:50:55 pm
has it ever been confirmed that .33 is the gamble 'victory' rate? or is that just player guess? from personal experience that sounds a little high, but i've only gambled maybe 20 crystals /shrug. nice work :)

It would be neat to see the basic results for other values, maybe going down to .25? ...I suppose I could run those, but that would involve opening my python interpreter...


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Drajor on July 30, 2015, 01:52:11 am
has it ever been confirmed that .33 is the gamble 'victory' rate? or is that just player guess? from personal experience that sounds a little high, but i've only gambled maybe 20 crystals /shrug. nice work :)

It would be neat to see the basic results for other values, maybe going down to .25? ...I suppose I could run those, but that would involve opening my python interpreter...

I could not find any official word on the win chance, only what has been said by other players and what is on the wiki. If it is 33.3% and not 33% then I will need to run the numbers again.


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Drep on July 30, 2015, 10:49:22 am
I guess have piss poor luck.  I stopped gambling them because I'm always losing them.  I've gotten lucky a few times but I have lost much more and wanted to slap myself afterwards.


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Darpey on July 30, 2015, 01:15:40 pm
If it's "33%" then it's undoubtedly actually 1/3 (33.33333333 etc...)

33% sounds about right in my experience - but that's never been officially confirmed to my knowledge


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Rymo on August 17, 2015, 08:52:43 am
from my note ... about 1.5? year.

Minor(2k AA) x100(200k AA) x4 tried.
1st try, Greater(10k AA) x24(240k AA). +40k
2nd try, Greater(10k AA) x21(210k AA). +10k
3rd try, Greater(10k AA) x28(280k AA). +80k
4th try, Greater(10k AA) x26(260k AA). +60k

Lesser(4k AA) x100(400k AA) x2 tried.
1st try, Major(20k AA) x23(460k AA). +60k
2nd try, Major(20k AA) x30(600k AA). +200k


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Kruciel on August 17, 2015, 04:31:50 pm
I haven't personally kept a record of mine over the years, but I know I'm hundreds of thousands of AAs to the good  :P


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Akkadius on August 17, 2015, 04:34:49 pm
My buddy Drajor just wanted to show off his amazing programming skills


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Drajor on August 22, 2015, 06:15:02 am
from my note ... about 1.5? year.

Minor(2k AA) x100(200k AA) x4 tried.
1st try, Greater(10k AA) x24(240k AA). +40k
2nd try, Greater(10k AA) x21(210k AA). +10k
3rd try, Greater(10k AA) x28(280k AA). +80k
4th try, Greater(10k AA) x26(260k AA). +60k

Lesser(4k AA) x100(400k AA) x2 tried.
1st try, Major(20k AA) x23(460k AA). +60k
2nd try, Major(20k AA) x30(600k AA). +200k

Interesting numbers, thanks for sharing!


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Akkadius on August 22, 2015, 02:07:17 pm
Gambling ruins lives


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Chunka on August 22, 2015, 02:19:10 pm
Also, punctuation saves lives!

Example? "Lets eat grandpa!" or "Lets eat, grandpa!"


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Rymo on October 06, 2015, 06:07:42 pm
from my note ... about 1.5? year.

Minor(2k AA) x100(200k AA) x4 tried.
1st try, Greater(10k AA) x24(240k AA). +40k
2nd try, Greater(10k AA) x21(210k AA). +10k
3rd try, Greater(10k AA) x28(280k AA). +80k
4th try, Greater(10k AA) x26(260k AA). +60k

Lesser(4k AA) x100(400k AA) x2 tried.
1st try, Major(20k AA) x23(460k AA). +60k
2nd try, Major(20k AA) x30(600k AA). +200k

adding data.
Minor(2k AA) x100(200k AA)
5th try, Greater(10k AA) x27(270k AA). +70k

Lesser(4k AA) x100(400k AA)
3rd try, Major(20k AA) x26(520k AA). +120k

I want to buy rank20 resist stone..... I will pay 100k AA.


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Kruciel on October 06, 2015, 06:32:35 pm
resist stone no trade rymosan  :(


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Rymo on October 06, 2015, 06:56:30 pm
hehe I want to use AA.


Title: Re: Rainbow Crystals: When should you gamble?
Post by: Moruk on October 06, 2015, 07:31:09 pm
I'd try this if rainbows dropped anymore, I havent seen one in so long I forgot what they look like.  I used to be able to get 1 maybe even 2 a night.