Jump VS Energy train 2.0

Code used to perform the simulations.
mail@pastecode.io avatar
unknown
r
2 years ago
15 kB
61
Indexable
Never
library(data.table)
library(foreach)
library(ggplot2)

# General setup:
# - Subscriber status (150 base e, 720 natural daily e)
# - Living in PI without yacht (4525 base happy, 2% gains bonus)
# - Sleep is for the weak, can train 24/7
# - No additional Job, Faction, Education or Book bonus
# - Using refills daily (+150 e daily)
# - All trains are done on Dex (just because) in George's gym (10 e per train)
# - Training is done for 60 days (as many trains as cooldowns allow)
# - Starting stat value is the same for all trains

# Stat offsets for the formula
#   Strength  Speed   Dexterity   Defense
#   1600      1600      1800    2100
#   1700      2000      1500    -600
#   700       1350      1000    1500

# Gym dots can be exctraced from the API or from https://algisk.shinyapps.io/Torn-UI

# Define the updated gym formula (reduced version)
gymGains <- function(S=10000, dot=7.3, A=1800, B=1500, C=1000, E=10, H=4525, usedE=150, perkFaction=0,
                     perkPI=2, perkEdu=0, perkGeneral=0, perkJob=0, perkBook=0) {
    # Check if stat over 50mil
    # 50,000,000 + ( STAT - 50,000,000 ) / ( 8.77635 * LOG(STAT) ) UPDATED
    Sreal <- S
    S <- ifelse(S<50e6, S,(S-50e6)/(8.77635*log10(S))+50e6)
    # Combine all multipliers
    multi <- (1+perkFaction/100)*(1+perkPI/100)*(1+perkEdu/100)*(1+perkGeneral/100)*(1+perkJob/100)*(1+perkBook/100)
    # Plug in the formula for single train
    dS <- (1/200000)*dot*E*multi*(S*round(1+0.07*round(log((1+H/250),base=exp(1)),4),4)+8*H^1.05+A*(1-(H/99999)^2)+B)
    dSe <- C*(1/200000)*dot*E*multi
    # Get prediction for total energy used
    ## number of trains
    NT <- floor(usedE/E)
    # Initial setup
    lowH <- highH <- H
    lowStat <- highStat <- Sreal
    lowest <- (1/200000)*dot*E*multi*(S*round(1+0.07*round(log((1+H/250),base=exp(1)),4),4)+8*H^1.05+A*(1-(H/99999)^2)+B-C*(1/200000))
    highest <- (1/200000)*dot*E*multi*(S*round(1+0.07*round(log((1+H/250),base=exp(1)),4),4)+8*H^1.05+A*(1-(H/99999)^2)+B+C*(1/200000))
    firstTrain <- data.table(iteration=1, lowest_possible=lowest, highest_possible=highest, lowest_stat=lowStat, highest_stat=highStat, lowest_happy=lowH, highest_happy=highH)
    # Loop through all iterations
    allTrains <- foreach(I=1:(NT+1), .combine=rbind) %do% {
        lowH <- ifelse(lowH-0.6*E<0,0,lowH-0.6*E)
        highH <- ifelse(highH-0.4*E<0,0,highH-0.4*E)
        lowStat <- lowStat + lowest
        highStat <- lowStat + highest
        newLow <- ifelse(lowStat < 50e6, lowStat, (lowStat-50e6)/(8.77635*log10(lowStat))+50e6)
        newHigh <- ifelse(highStat < 50e6, highStat, (highStat-50e6)/(8.77635*log10(highStat))+50e6)
        lowest <- (1/200000)*dot*E*multi*(newLow*round(1+0.07*round(log((1+lowH/250),base=exp(1)),4),4)+8*lowH^1.05+A*(1-(lowH/99999)^2)+B-C*(1/200000))
        highest <- (1/200000)*dot*E*multi*(newHigh*round(1+0.07*round(log((1+highH/250),base=exp(1)),4),4)+8*highH^1.05+A*(1-(highH/99999)^2)+B+C*(1/200000))
        data.table(iteration=I+1, lowest_possible=lowest, highest_possible=highest, lowest_stat=round(lowStat), highest_stat=round(highStat), lowest_happy=lowH, highest_happy=highH)
    }
    allTrains <- rbind(firstTrain, allTrains)
    minTrain <- allTrains[NT+1]$lowest_stat-Sreal
    maxTrain <- allTrains[NT+1]$highest_stat-Sreal
    avgTrain <- mean(c(minTrain, maxTrain))
    # Predicted total
    dM <- ifelse(usedE/E==1, dS, avgTrain)
    dMe <- (maxTrain-minTrain)/2
    res <- data.table(
        Train=c("Single", "Total"),
        GainsN=c(round(dS,2),round(dM,2)),
        ErrorN=c(round(dSe,1),round(dMe,1)),
        Gains=c(round(dS,2),round(dM,2)),
        Error=c(round(dSe,1),round(dMe,1))
    )
    return(list(res,NT))
}    

# Define a wrapper for simulating different jumps and train numbers
jumpSim <- function(startStat=10000, jumpH=4525, jumpE=150, nJump=60, 
                    jumpType=NA, Days=60, vStart=NA) {
    out <- data.table(
        Jump=0,
        Stat=startStat,
        Gain=0,
        Error=0,
        Type=jumpType,
        Start=vStart
    )
    newStat <- startStat
    jumps <- foreach(I=1:nJump, .combine=rbind) %do% {
        totalGain <- gymGains(usedE=jumpE, H=jumpH, S=newStat)
        newStat <- newStat+as.numeric(totalGain[[1]][2,2])
        data.table(
            Jump=I,
            Stat=newStat,
            Gain=round(((newStat)/startStat)*100-100),
            Error=as.numeric(totalGain[[1]][2,3]),
            Type=jumpType,
            Start=vStart
        )
    }
    res <- rbind(out, jumps)
    res$Day <- seq(0,Days, length.out=nrow(res))
    return(res)
}

##################
# Classic happy jump
# 4x Xanax + 5x EDVD + Ecstasy + Refill = 32h CD (one train every 1.5 days)
# - Energy: 1000
# - Happy: 34050
# - Cost per train: ~22mil
# - Number of trains: 40
# - Total cost: 880mil

HJ <- rbind(
    jumpSim(startStat=10e3, jumpH=34050, jumpE=1150, nJump=40, jumpType="Happy", vStart="10k"),
    jumpSim(startStat=300e3, jumpH=34050, jumpE=1150, nJump=40, jumpType="Happy", vStart="300k"),
    jumpSim(startStat=5e6, jumpH=34050, jumpE=1150, nJump=40, jumpType="Happy", vStart="5m"),
    jumpSim(startStat=100e6, jumpH=34050, jumpE=1150, nJump=40, jumpType="Happy", vStart="100m")
)
# Classic happy jump: Adult Novelties
# * Double happy from EDVDs
# 4x Xanax + 5x EDVD + Ecstasy + Refill = 32h CD (one train every 1.5 days)
# - Energy: 1150
# - Happy: 59050
# - Cost per train: ~22mil
# - Number of trains: 40
# - Total cost: 880mil

HJAN <- rbind(
    jumpSim(startStat=10e3, jumpH=59050, jumpE=1150, nJump=40, jumpType="Happy: Adult Novelties", vStart="10k"),
    jumpSim(startStat=300e3, jumpH=59050, jumpE=1150, nJump=40, jumpType="Happy: Adult Novelties", vStart="300k"),
    jumpSim(startStat=5e6, jumpH=59050, jumpE=1150, nJump=40, jumpType="Happy: Adult Novelties", vStart="5m"),
    jumpSim(startStat=100e6, jumpH=59050, jumpE=1150, nJump=40, jumpType="Happy: Adult Novelties", vStart="100m")
)

# Single choco jump
# 1x Xanax + 48x Big Boxes of Chocolate + Ecstasy + Refill = 24h CD (one train per day)
# - Energy: 550
# - Happy: 12410
# - Cost per train: ~2.4mil
# - Number of trains: 60
# - Total cost: 144mil

SCJ <- rbind(
    jumpSim(startStat=10e3, jumpH=12410, jumpE=550, nJump=60, jumpType="Single Choco", vStart="10k"),
    jumpSim(startStat=300e3, jumpH=12410, jumpE=550, nJump=60, jumpType="Single Choco", vStart="300k"),
    jumpSim(startStat=5e6, jumpH=12410, jumpE=550, nJump=60, jumpType="Single Choco", vStart="5m"),
    jumpSim(startStat=100e6, jumpH=12410, jumpE=550, nJump=60, jumpType="Single Choco", vStart="100m")
)

# Half choco jump
# 1x Xanax + 24x Big Boxes of Chocolate + Ecstasy + Refill(*) = 12h CD (two trains per day)
# * Since you can refill energy with points only once per day, i will split the energy gain over both jumps
# - Energy: 475
# - Happy: 10730
# - Cost per train: ~1mil + daily refill
# - Number of trains: 120
# - Total cost: 120mil + 60x Refill = 188mil

HCJ <- rbind(
    jumpSim(startStat=10e3, jumpH=10730, jumpE=475, nJump=120, jumpType="Half Choco", vStart="10k"),
    jumpSim(startStat=300e3, jumpH=10730, jumpE=475, nJump=120, jumpType="Half Choco", vStart="300k"),
    jumpSim(startStat=5e6, jumpH=10730, jumpE=475, nJump=120, jumpType="Half Choco", vStart="5m"),
    jumpSim(startStat=100e6, jumpH=10730, jumpE=475, nJump=120, jumpType="Half Choco", vStart="100m")
)

# Energy training
# Energy training is very hard to put into exact formulas, because there are many ways to go about it.
# You can waste a bit of E regen and time Xanax with max E for optimal Happy, you can ignore Happy and just spam E on cooldown,
# you can include FHCs in your ration to get even more E, etc.

# Energy training: 3x Xanax
# * For simplicity, let's say  you train every 5 hours for natural regen + one refill and split the xanax gains evenly
# 3x Xanax + 750 natural regen + 150 refill = 6 trains per day
# - Energy: 270 (average)
# - Happy: 4525
# - Cost per train: ~600k
# - Number of trains: 360
# - Total cost: 216mil

ET <- rbind(
    jumpSim(startStat=10e3, jumpH=4525, jumpE=270, nJump=360, jumpType="Energy training: 3 Xanax", vStart="10k"),
    jumpSim(startStat=300e3, jumpH=4525, jumpE=270, nJump=360, jumpType="Energy training: 3 Xanax", vStart="300k"),
    jumpSim(startStat=5e6, jumpH=4525, jumpE=270, nJump=360, jumpType="Energy training: 3 Xanax", vStart="5m"),
    jumpSim(startStat=100e6, jumpH=4525, jumpE=270, nJump=360, jumpType="Energy training: 3 Xanax", vStart="100m")
)

# Energy training: 2x Xanax
# * For simplicity, let's say  you train every 5 hours for natural regen + one refill and split the xanax gains evenly
# 2x Xanax + 750 natural regen + 150 refill = 6 trains per day
# - Energy: 230 (average)
# - Happy: 4525
# - Cost per train: ~470k
# - Number of trains: 360
# - Total cost: 170mil

ET2 <- rbind(
    jumpSim(startStat=10e3, jumpH=4525, jumpE=230, nJump=360, jumpType="Energy training: 2 Xanax", vStart="10k"),
    jumpSim(startStat=300e3, jumpH=4525, jumpE=230, nJump=360, jumpType="Energy training: 2 Xanax", vStart="300k"),
    jumpSim(startStat=5e6, jumpH=4525, jumpE=230, nJump=360, jumpType="Energy training: 2 Xanax", vStart="5m"),
    jumpSim(startStat=100e6, jumpH=4525, jumpE=230, nJump=360, jumpType="Energy training: 2 Xanax", vStart="100m")
)

# Energy training: FHC (extreme case)
# * In this case, we split the E gain from FHCs over all 6 trains, but ignore the happy gain
# This is far from a perfect way to account for the single big train you get from stacking FHCs, but i'm not going through that trouble!
# 3x Xanax + 720 natural regen + 4x FHC + 150 refill = 6 trains per day
# - Energy: 370 (average)
# - Happy: 4525
# - Cost per train: ~10.6mil
# - Number of trains: 360
# - Total cost: 3.8bil

FHC <- rbind(
    jumpSim(startStat=10e3, jumpH=4525, jumpE=370, nJump=360, jumpType="Energy training: FHC", vStart="10k"),
    jumpSim(startStat=300e3, jumpH=4525, jumpE=370, nJump=360, jumpType="Energy training: FHC", vStart="300k"),
    jumpSim(startStat=5e6, jumpH=4525, jumpE=370, nJump=360, jumpType="Energy training: FHC", vStart="5m"),
    jumpSim(startStat=100e6, jumpH=4525, jumpE=370, nJump=360, jumpType="Energy training: FHC", vStart="100m")
)

## Combine the data
toplot <- rbind(HJ,HJAN,SCJ,HCJ,ET,ET2,FHC)
toplot$Start <- factor(toplot$Start, levels=rev(c("100m","5m","300k","10k")))
toplot$Type <- factor(toplot$Type, levels=unique(toplot$Type))
## Plot results
ggplot(toplot, aes(x=Day, y=Stat, color=Type)) +
    geom_line(lwd=2) + theme_bw(base_size = 18) +
    scale_color_brewer(palette="Paired") + theme(legend.position = "top") +
    facet_wrap(.~Start, scales="free")
## Without FHC
ggplot(toplot[Type!="Energy training: FHC"], aes(x=Day, y=Stat, color=Type)) +
    geom_line(lwd=2) + theme_bw(base_size = 18) +
    scale_color_brewer(palette="Paired") + theme(legend.position = "top") +
    facet_wrap(.~Start, scales="free")
# If you are just starting out, Jumping is a great way to reach the level where pure energy training is better
# Value of happy is linear, while gains from additional energy spent are almost exponential
# If your stats are close to 200k, you should consider dropping jumps and focus on energy training instead
# To get even more gains, use the free booster cooldown for E items
# Or just drink beer and do crimes :)

## Calculate costs per %
costplot <- toplot[Day==60]
costplot$CostPerGain <- 0
costplot[Type=="Happy"]$CostPerGain <- costplot[Type=="Happy"]$Gain/880e6
costplot[Type=="Happy: Adult Novelties"]$CostPerGain <- costplot[Type=="Happy: Adult Novelties"]$Gain/880e6
costplot[Type=="Single Choco"]$CostPerGain <- costplot[Type=="Single Choco"]$Gain/144e6
costplot[Type=="Half Choco"]$CostPerGain <- costplot[Type=="Half Choco"]$Gain/188e6
costplot[Type=="Energy training: 3 Xanax"]$CostPerGain <- costplot[Type=="Energy training: 3 Xanax"]$Gain/216e6
costplot[Type=="Energy training: 2 Xanax"]$CostPerGain <- costplot[Type=="Energy training: 2 Xanax"]$Gain/170e6
costplot[Type=="Energy training: FHC"]$CostPerGain <- costplot[Type=="Energy training: FHC"]$Gain/3.8e9

out <- melt(costplot[,.(Type,Gain,CostPerGain*1e9,Start)], id.vars=c("Type","Start"))

ggplot(out, aes(y=Type, x=value, fill=variable)) +
    geom_bar(stat="identity", position="dodge") +
    theme_bw(base_size = 16) + theme(legend.position = "top") +
    xlab("Gains / Value") +
    scale_fill_brewer(palette="Set1", name="", 
                      breaks=c("Gain","V3"), labels=c("Gain %","Value (scaled)")) +
    facet_wrap(.~Start, scales="free")
# FHC energy training provides best gains, but is absurdly expensive
# Best value option is to do 3 or 2 Xanax per day training if your stat is at least 250k
# Jumping is a great way to grow early on, before you reach the critical threshold of 250k
# Happy jump is faster than Half Choco jumps, but not by that much when you factor in the cost
# TLDR: Do Half Choco jumps up to ~200k stat value, then switch to pure energy training (at least 2 Xanax/day)

## Energy vs Happy value
stats <- c(1e2,1e3,10e3,50e3,100e3,150e3,200e3,250e3,300e3,500e3,1e6,1.5e6)
# Using time period of 1 happy jump
tmp <- foreach(myStat=stats, .combine=rbind) %do% {
    data.table(
        Stat=myStat,
        Gain=c(
            max(jumpSim(startStat=myStat, jumpH=34050, jumpE=1150, nJump=1, jumpType="Happy", vStart="10k")$Stat)-myStat,
            max(jumpSim(startStat=myStat, jumpH=59050, jumpE=1150, nJump=1, jumpType="Happy: Adult Novelties", vStart="10k")$Stat)-myStat,
            # max(jumpSim(startStat=myStat, jumpH=12410, jumpE=550, nJump=3, jumpType="Single Choco", vStart="10k")$Stat),
            max(jumpSim(startStat=myStat, jumpH=10730, jumpE=475, nJump=3, jumpType="Half Choco", vStart="10k")$Stat)-myStat,
            max(jumpSim(startStat=myStat, jumpH=4525, jumpE=270, nJump=9, jumpType="Energy training: 3 Xanax", vStart="10k")$Stat)-myStat,
            max(jumpSim(startStat=myStat, jumpH=4525, jumpE=230, nJump=9, jumpType="Energy training: 2 Xanax", vStart="10k")$Stat)-myStat
            # max(jumpSim(startStat=myStat, jumpH=4525, jumpE=370, nJump=18, jumpType="Energy training: FHC", vStart="10k")$Stat)
        ),
        Type=c("Happy","Happy: Adult Novelites","Half Choco","Energy training: 3 Xanax","Energy training: 2 Xanax")
    )
}

# When to switch methods?
ggplot(tmp, aes(x=Stat, y=Gain, color=Type)) +
    geom_line(lwd=1.5) + xlab("Starting stat") + ylab("Stat gain") +
    geom_rect(aes(xmin=245e3,xmax=450e3,ymin=20e3,ymax=50e3), fill=NA, col="red") +
    geom_point(aes(x=1.32e6,y=99e3), col="red", size=3) +
    theme_bw(base_size = 18) +
    scale_color_brewer(palette="Paired") +
    scale_x_continuous(breaks=seq(0,1.5e6,300e3)) +
    theme(legend.position = "top") 

# Switching from Jump training to Energy based training is best around 250-400k stat
# If you insist on jumping, then Half-Choco jumps become more efficient at around 1.2mil stat
# Only exception is if you are working in an AN company - in that case, Happy jumping offers the best gains up to ~900k stat