Welcome, Guest. Please login or register.
Did you miss your activation email?
May 02, 2024, 10:02:27 pm *

Login with username, password and session length
Pages: [1] 2
Print
Author Topic: Rainbow Crystals: When should you gamble?  (Read 11819 times)
Drajor
Newbie
*
Posts: 27


View Profile
« 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.
Logged
Drajor
Newbie
*
Posts: 27


View Profile
« Reply #1 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()

Logged
Darpey
Sr. Member
****
Posts: 391



View Profile WWW
« Reply #2 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.
Logged

Darpey - Warrior <Focus Hope>
http://www.ezserverwiki.com/
slaughterhaus
Full Member
***
Posts: 132


View Profile
« Reply #3 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 Tongue


Deadend
Logged
Phah
Jr. Member
**
Posts: 83



View Profile
« Reply #4 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 Smiley

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...
Logged

Mine is the drill that will pierce the heavens! Or at least the next tier.

Filthy casual? Yep, that's me!
Drajor
Newbie
*
Posts: 27


View Profile
« Reply #5 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 Smiley

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.
Logged
Drep
Full Member
***
Posts: 141


View Profile
« Reply #6 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.
Logged

Drep (War),  Wudd (Cleric), Mdydar (Monk)
Darpey
Sr. Member
****
Posts: 391



View Profile WWW
« Reply #7 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
Logged

Darpey - Warrior <Focus Hope>
http://www.ezserverwiki.com/
Rymo
Newbie
*
Posts: 38


View Profile
« Reply #8 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
Logged
Kruciel
Hero Member
*****
Posts: 624


View Profile
« Reply #9 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  Tongue
Logged
Akkadius
Administrator
Legend
*****
Posts: 2016



View Profile
« Reply #10 on: August 17, 2015, 04:34:49 pm »

My buddy Drajor just wanted to show off his amazing programming skills
Logged


EZ Server GM
Drajor
Newbie
*
Posts: 27


View Profile
« Reply #11 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!
Logged
Akkadius
Administrator
Legend
*****
Posts: 2016



View Profile
« Reply #12 on: August 22, 2015, 02:07:17 pm »

Gambling ruins lives
Logged


EZ Server GM
Chunka
Hero Member
Legend
*****
Posts: 1642


Been gone so long I'm a newbie again!


View Profile
« Reply #13 on: August 22, 2015, 02:19:10 pm »

Also, punctuation saves lives!

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

"When any government, or any church for that matter, undertakes to say to its subjects, "This you may not read, this you must not see, this you are forbidden to know," the end result is tyranny and oppression, no matter how holy the motives. Mighty little force is needed to control a man whose mind has been hoodwinked; contrariwise, no amount of force can control a free man, a man whose mind is free. No, not the rack, not fission bombs, not anything — you can't conquer a free man; the most you can do is kill him." R.A. Heinlein
Rymo
Newbie
*
Posts: 38


View Profile
« Reply #14 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.
« Last Edit: October 06, 2015, 06:15:31 pm by Rymo » Logged
Pages: [1] 2
Print
Jump to:  

Recent

Stats

Members
  • Total Members: 6124
  • Latest: Havicck
Stats
  • Total Posts: 64988
  • Total Topics: 5053
  • Online Today: 161
  • Online Ever: 8678
  • (December 19, 2022, 02:32:09 pm)
Users Online
Users: 0
Guests: 116
Total: 116
TinyPortal v1.0 beta 4 © Bloc