diff --git a/koboldsim/stats.go b/koboldsim/stats.go index ca279fc..d098f99 100644 --- a/koboldsim/stats.go +++ b/koboldsim/stats.go @@ -10,58 +10,205 @@ import ( type KoboldMine struct { BasePopulation float64 `cardsim:"stathidden"` - MiningIncome float64 `cardsim:"stat" cardsim_name:"Mining Productivity"` - ScavengingIncome float64 `cardsim:"stat" cardsim_name:"Scavenging Productivity"` - AlchemyIncome float64 `cardsim:"stat" cardsim_name:"Alchemy Productivity"` - HospitalityIncome float64 `cardsim:"stat" cardsim_name:"Hospitality Productivity"` - AgricultureIncome float64 `cardsim:"stat" cardsim_name:"Agriculture Productivity"` - ManufacturingIncome float64 `cardsim:"stat" cardsim_name:"Manufacturing Productivity"` - PlanarIncome float64 `cardsim:"stat" cardsim_name:"Planar Productivity"` - PublishingIncome float64 `cardsim:"stat" cardsim_name:"Publishing Productivity"` - ForestryIncome float64 `cardsim:"stat" cardsim_name:"Forestry Productivity"` - FinanceIncome float64 `cardsim:"stat" cardsim_name:"Finance Productivity"` - GadgetryIncome float64 `cardsim:"stat" cardsim_name:"Gadgetry Productivity"` - FishingIncome float64 `cardsim:"stat" cardsim_name:"Fishing Productivity"` - ConstructionIncome float64 `cardsim:"stat" cardsim_name:"Construction Productivity"` + MiningIncome float64 `cardsim:"stathidden" cardsim_name:"Mining Productivity"` + ScavengingIncome float64 `cardsim:"stathidden" cardsim_name:"Scavenging Productivity"` + AlchemyIncome float64 `cardsim:"stathidden" cardsim_name:"Alchemy Productivity"` + HospitalityIncome float64 `cardsim:"stathidden" cardsim_name:"Hospitality Productivity"` + AgricultureIncome float64 `cardsim:"stathidden" cardsim_name:"Agriculture Productivity"` + ManufacturingIncome float64 `cardsim:"stathidden" cardsim_name:"Manufacturing Productivity"` + PlanarIncome float64 `cardsim:"stathidden" cardsim_name:"Planar Productivity"` + PublishingIncome float64 `cardsim:"stathidden" cardsim_name:"Publishing Productivity"` + ForestryIncome float64 `cardsim:"stathidden" cardsim_name:"Forestry Productivity"` + FinanceIncome float64 `cardsim:"stathidden" cardsim_name:"Finance Productivity"` + GadgetryIncome float64 `cardsim:"stathidden" cardsim_name:"Gadgetry Productivity"` + FishingIncome float64 `cardsim:"stathidden" cardsim_name:"Fishing Productivity"` + ConstructionIncome float64 `cardsim:"stathidden" cardsim_name:"Construction Productivity"` - PropagandaExpense float64 `cardsim:"stat" cardsim_name:"Propaganda Investment"` - BureaucracyExpense float64 `cardsim:"stat" cardsim_name:"Bureaucracy Investment"` - WarExpense float64 `cardsim:"stat" cardsim_name:"War Investment"` - QoLExpense float64 `cardsim:"stat" cardsim_name:"QoL Investment"` - LogisticsExpense float64 `cardsim:"stat" cardsim_name:"Logistics Investment"` - DragonSubsExpense float64 `cardsim:"stat" cardsim_name:"Dragon Subsidies Investment"` - ResearchSubsExpense float64 `cardsim:"stat" cardsim_name:"Research Subsidies Investment"` - EducationExpense float64 `cardsim:"stat" cardsim_name:"Education Investment"` - HealthcareExpense float64 `cardsim:"stat" cardsim_name:"Healthcare Investment"` - ForeignRelExpense float64 `cardsim:"stat" cardsim_name:"Foreign Relations Investment"` - PoliceExpense float64 `cardsim:"stat" cardsim_name:"Law Enforcement Investment"` - EconPlanExpense float64 `cardsim:"stat" cardsim_name:"Economic Planning Investment"` - ParksExpense float64 `cardsim:"stat" cardsim_name:"Parks and Aesthetics Investment"` - FaithExpense float64 `cardsim:"stat" cardsim_name:"Faith Investment"` + PropagandaExpense float64 `cardsim:"stathidden" cardsim_name:"Propaganda Investment"` + BureaucracyExpense float64 `cardsim:"stathidden" cardsim_name:"Bureaucracy Investment"` + WarExpense float64 `cardsim:"stathidden" cardsim_name:"War Investment"` + QoLExpense float64 `cardsim:"stathidden" cardsim_name:"QoL Investment"` + LogisticsExpense float64 `cardsim:"stathidden" cardsim_name:"Logistics Investment"` + DragonSubsExpense float64 `cardsim:"stathidden" cardsim_name:"Dragon Subsidies Investment"` + ResearchSubsExpense float64 `cardsim:"stathidden" cardsim_name:"Research Subsidies Investment"` + EducationExpense float64 `cardsim:"stathidden" cardsim_name:"Education Investment"` + HealthcareExpense float64 `cardsim:"stathidden" cardsim_name:"Healthcare Investment"` + ForeignRelExpense float64 `cardsim:"stathidden" cardsim_name:"Foreign Relations Investment"` + PoliceExpense float64 `cardsim:"stathidden" cardsim_name:"Law Enforcement Investment"` + EconPlanExpense float64 `cardsim:"stathidden" cardsim_name:"Economic Planning Investment"` + ParksExpense float64 `cardsim:"stathidden" cardsim_name:"Parks and Aesthetics Investment"` + FaithExpense float64 `cardsim:"stathidden" cardsim_name:"Faith Investment"` - FoodSupply float64 `cardsim:"stathidden"` - ForeignRelations float64 `cardsim:"stathidden"` - HiddenRelPenalty float64 `cardsim:"stathidden"` - Secrecy float64 `cardsim:"stathidden"` + FoodSupply float64 `cardsim:"stathidden"` + ForeignRelations float64 `cardsim:"stathidden"` + HiddenRelPenalty float64 `cardsim:"stathidden"` // Lower is better. + Secrecy float64 `cardsim:"stathidden"` + PointOfDimReturns float64 `cardsim:"stathidden"` // AnotherExpense float64 `cardsim:"hiddenround5"` // A different way of adding stats that is slightly more empowering. } -func (k *KoboldMine) ProductivityFunc(s *float64) func() float64 { +func (k *KoboldMine) ProductivityFunc(s float64) func() float64 { return func() float64 { - return *s * float64(k.BasePopulation) + return math.Max(s*float64(k.Kobolds()), 0) } } +func (k *KoboldMine) ProductivityTotal() float64 { + total := math.Max(k.MiningIncome, 0.01) + total += math.Max(k.ScavengingIncome, 0) + total += math.Max(k.AlchemyIncome, 0) + total += math.Max(k.HospitalityIncome, 0) + total += math.Max(k.AgricultureIncome, 0) + total += math.Max(k.ManufacturingIncome, 0) + total += math.Max(k.PlanarIncome, 0) + total += math.Max(k.PublishingIncome, 0) + total += math.Max(k.FinanceIncome, 0) + total += math.Max(k.GadgetryIncome, 0) + total += math.Max(k.FishingIncome, 0) + total += math.Max(k.ConstructionIncome, 0.02) + total += math.Max(k.PropagandaExpense, 0) + total += math.Max(k.BureaucracyExpense, 0) + total += math.Max(k.WarExpense, 0) + total += math.Max(k.QoLExpense, 0) + total += math.Max(k.LogisticsExpense, 0) + total += math.Max(k.DragonSubsExpense, 0) + total += math.Max(k.ResearchSubsExpense, 0) + total += math.Max(k.EducationExpense, 0) + total += math.Max(k.HealthcareExpense, 0) + total += math.Max(k.ForeignRelExpense, 0) + total += math.Max(k.PoliceExpense, 0) + total += math.Max(k.EconPlanExpense, 0) + total += math.Max(k.ParksExpense, 0) + total += math.Max(k.FaithExpense, 0) + return total +} + +func (k *KoboldMine) ProductivityMultiplier() float64 { + return math.Pow(0.95, math.Max(0, k.ProductivityTotal()-k.PointOfDimReturns)) +} + +func (k *KoboldMine) TrueMiningIncome() float64 { + return math.Max(k.MiningIncome*k.ProductivityMultiplier(), 0.01) +} + +func (k *KoboldMine) TrueScavengingIncome() float64 { + return math.Max(k.ScavengingIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueAlchemyIncome() float64 { + return math.Max(k.AlchemyIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueHospitalityIncome() float64 { + return math.Max(k.HospitalityIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueAgricultureIncome() float64 { + return math.Max(k.AgricultureIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueManufacturingIncome() float64 { + return math.Max(k.ManufacturingIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TruePlanarIncome() float64 { + return math.Max(k.PlanarIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TruePublishingIncome() float64 { + return math.Max(k.PublishingIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueForestryIncome() float64 { + return math.Max(k.ForestryIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueFinanceIncome() float64 { + return math.Max(k.FinanceIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueGadgetryIncome() float64 { + return math.Max(k.GadgetryIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueFishingIncome() float64 { + return math.Max(k.FishingIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueConstructionIncome() float64 { + return math.Max(k.ConstructionIncome*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TruePropagandaExpense() float64 { + return math.Max(k.PropagandaExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueBureaucracyExpense() float64 { + return math.Max(k.BureaucracyExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueWarExpense() float64 { + return math.Max(k.WarExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueQoLExpense() float64 { + return math.Max(k.QoLExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueLogisticsExpense() float64 { + return math.Max(k.LogisticsExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueDragonSubsExpense() float64 { + return math.Max(k.DragonSubsExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueResearchSubsExpense() float64 { + return math.Max(k.ResearchSubsExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueEducationExpense() float64 { + return math.Max(k.EducationExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueHealthcareExpense() float64 { + return math.Max(k.HealthcareExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueForeignRelExpense() float64 { + return math.Max(k.ForeignRelExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TruePoliceExpense() float64 { + return math.Max(k.PoliceExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueEconPlanExpense() float64 { + return math.Max(k.EconPlanExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueParksExpense() float64 { + return math.Max(k.ParksExpense*k.ProductivityMultiplier(), 0) +} + +func (k *KoboldMine) TrueFaithExpense() float64 { + return math.Max(k.FaithExpense*k.ProductivityMultiplier(), 0) +} + func (k *KoboldMine) TotalSectorIncome() float64 { - return float64(k.Kobolds()) * (k.MiningIncome + k.ScavengingIncome + k.AlchemyIncome + k.HospitalityIncome + k.AgricultureIncome + k.ManufacturingIncome + k.PlanarIncome + k.PublishingIncome + k.FinanceIncome + k.GadgetryIncome + k.FishingIncome + k.ConstructionIncome) + return float64(k.Kobolds()) * (math.Max(k.TrueMiningIncome(), 0.01) + math.Max(k.TrueScavengingIncome(), 0) + math.Max(k.TrueAlchemyIncome(), 0) + math.Max(k.TrueHospitalityIncome(), 0) + math.Max(k.TrueAgricultureIncome(), 0) + math.Max(k.TrueManufacturingIncome(), 0) + math.Max(k.TruePlanarIncome(), 0) + math.Max(k.TruePublishingIncome(), 0) + math.Max(k.TrueFinanceIncome(), 0) + math.Max(k.TrueGadgetryIncome(), 0) + math.Max(k.TrueFishingIncome(), 0) + math.Max(k.TrueConstructionIncome(), 0.02)) } func (k *KoboldMine) TotalGovExpense() float64 { - return float64(k.Kobolds()) * (k.PropagandaExpense + k.BureaucracyExpense + k.WarExpense + k.QoLExpense + k.LogisticsExpense + k.DragonSubsExpense + k.ResearchSubsExpense + k.EducationExpense + k.HealthcareExpense + k.ForeignRelExpense + k.PoliceExpense + k.EconPlanExpense + k.ParksExpense + k.FaithExpense) + return float64(k.Kobolds()) * (math.Max(k.TruePropagandaExpense(), 0) + math.Max(k.TrueBureaucracyExpense(), 0) + math.Max(k.TrueWarExpense(), 0) + math.Max(k.TrueQoLExpense(), 0) + math.Max(k.TrueLogisticsExpense(), 0) + math.Max(k.TrueDragonSubsExpense(), 0) + math.Max(k.TrueResearchSubsExpense(), 0) + math.Max(k.TrueEducationExpense(), 0) + math.Max(k.TrueHealthcareExpense(), 0) + math.Max(k.TrueForeignRelExpense(), 0) + math.Max(k.TruePoliceExpense(), 0) + math.Max(k.TrueEconPlanExpense(), 0) + math.Max(k.TrueParksExpense(), 0) + math.Max(k.TrueFaithExpense(), 0)) } +//func (k *KoboldMine) TotalEconomicPotential() float64 { +// return (math.Max(k.MiningIncome, 0.01) + math.Max(k.ScavengingIncome, 0) + math.Max(k.AlchemyIncome, 0) + math.Max(k.HospitalityIncome, 0) + math.Max(k.AgricultureIncome, 0) + math.Max(k.ManufacturingIncome, 0) + math.Max(k.PlanarIncome, 0) + math.Max(k.PublishingIncome, 0) + math.Max(k.FinanceIncome, 0) + math.Max(k.GadgetryIncome, 0) + math.Max(k.FishingIncome, 0) + math.Max(k.ConstructionIncome, 0.02) + math.Max(k.PropagandaExpense, 0) + math.Max(k.BureaucracyExpense, 0) + math.Max(k.WarExpense, 0) + math.Max(k.QoLExpense, 0) + math.Max(k.LogisticsExpense, 0) + math.Max(k.DragonSubsExpense, 0) + math.Max(k.ResearchSubsExpense, 0) + math.Max(k.EducationExpense, 0) + math.Max(k.HealthcareExpense, 0) + math.Max(k.ForeignRelExpense, 0) + math.Max(k.PoliceExpense, 0) + math.Max(k.EconPlanExpense, 0) + math.Max(k.ParksExpense, 0) + math.Max(k.FaithExpense, 0)) * 0.8 +//} // This function is intended to enable "crowding out" effects at a later point. Each +1 increase in overall productivity increases TEP by 0.8, losing 1/5th of the gain to crowding, which should manifest as everything else declining. Now, uh... How do I scale investments by the TEP stat? With a simple multiplication, a 0.01 increase to mining would be a 0.08 increase to everything else. Damn it, I thought I had something. + func (k *KoboldMine) Taxation() float64 { return (k.TotalGovExpense() / (k.TotalSectorIncome() + k.TotalGovExpense())) * 100 } @@ -71,7 +218,7 @@ func (k *KoboldMine) StatTaxRate() float64 { } func (k *KoboldMine) Kobolds() int64 { - return int64(k.BasePopulation * k.FoodSupply * (1 - 0.5*(k.StatObesity()/100)) * (1 + k.TrueForeignRelations())) + return int64((k.BasePopulation + (k.HealthcareExpense * 1000)) * k.FoodSupply * (1 - 0.5*(k.StatObesity()/100)) * (1 + k.TrueForeignRelations())) } func (k *KoboldMine) DisplayedFoodSupply() float64 { @@ -99,111 +246,111 @@ func (k *KoboldMine) Stats() []cardsim.Stat { funcs := []cardsim.Stat{ cardsim.StatFunc( "Mining Income", - k.ProductivityFunc(&k.MiningIncome), + k.ProductivityFunc(k.TrueMiningIncome()), ), cardsim.StatFunc( "Scavenging Income", - k.ProductivityFunc(&k.ScavengingIncome), + k.ProductivityFunc(k.TrueScavengingIncome()), ), cardsim.StatFunc( "Alchemy Income", - k.ProductivityFunc(&k.AlchemyIncome), + k.ProductivityFunc(k.TrueAlchemyIncome()), ), cardsim.StatFunc( "Hospitality Income", - k.ProductivityFunc(&k.HospitalityIncome), + k.ProductivityFunc(k.TrueHospitalityIncome()), ), cardsim.StatFunc( "Agriculture Income", - k.ProductivityFunc(&k.AgricultureIncome), + k.ProductivityFunc(k.TrueAgricultureIncome()), ), cardsim.StatFunc( "Manufacturing Income", - k.ProductivityFunc(&k.ManufacturingIncome), + k.ProductivityFunc(k.TrueManufacturingIncome()), ), cardsim.StatFunc( "Planar Harvesting Income", - k.ProductivityFunc(&k.PlanarIncome), + k.ProductivityFunc(k.TruePlanarIncome()), ), cardsim.StatFunc( "Book Publishing Income", - k.ProductivityFunc(&k.PublishingIncome), + k.ProductivityFunc(k.TruePublishingIncome()), ), cardsim.StatFunc( "Forestry Income", - k.ProductivityFunc(&k.ForestryIncome), + k.ProductivityFunc(k.TrueForestryIncome()), ), cardsim.StatFunc( "Finance Income", - k.ProductivityFunc(&k.FinanceIncome), + k.ProductivityFunc(k.TrueFinanceIncome()), ), cardsim.StatFunc( "Gadgetry Income", - k.ProductivityFunc(&k.GadgetryIncome), + k.ProductivityFunc(k.TrueGadgetryIncome()), ), cardsim.StatFunc( "Fishing Income", - k.ProductivityFunc(&k.FishingIncome), + k.ProductivityFunc(k.TrueFishingIncome()), ), cardsim.StatFunc( "Construction Income", - k.ProductivityFunc(&k.ConstructionIncome), + k.ProductivityFunc(k.TrueConstructionIncome()), ), cardsim.StatFunc( "Propaganda Expense", - k.ProductivityFunc(&k.PropagandaExpense), + k.ProductivityFunc(k.TruePropagandaExpense()), ), cardsim.StatFunc( "Bureaucracy Expense", - k.ProductivityFunc(&k.BureaucracyExpense), + k.ProductivityFunc(k.TrueBureaucracyExpense()), ), cardsim.StatFunc( "War Expense", - k.ProductivityFunc(&k.WarExpense), + k.ProductivityFunc(k.TrueWarExpense()), ), cardsim.StatFunc( "QoL Expense", - k.ProductivityFunc(&k.QoLExpense), + k.ProductivityFunc(k.TrueQoLExpense()), ), cardsim.StatFunc( "Logistics Expense", - k.ProductivityFunc(&k.LogisticsExpense), + k.ProductivityFunc(k.TrueLogisticsExpense()), ), cardsim.StatFunc( "Dragon Subsidies", - k.ProductivityFunc(&k.DragonSubsExpense), + k.ProductivityFunc(k.TrueDragonSubsExpense()), ), cardsim.StatFunc( "Research Subsidies", - k.ProductivityFunc(&k.ResearchSubsExpense), + k.ProductivityFunc(k.TrueResearchSubsExpense()), ), cardsim.StatFunc( "Education Expense", - k.ProductivityFunc(&k.EducationExpense), + k.ProductivityFunc(k.TrueEducationExpense()), ), cardsim.StatFunc( "Healthcare Expense", - k.ProductivityFunc(&k.HealthcareExpense), + k.ProductivityFunc(k.TrueHealthcareExpense()), ), cardsim.StatFunc( "Foreign Relations Expense", - k.ProductivityFunc(&k.ForeignRelExpense), + k.ProductivityFunc(k.TrueForeignRelExpense()), ), cardsim.StatFunc( "Law Enforcement Expense", - k.ProductivityFunc(&k.PoliceExpense), + k.ProductivityFunc(k.TruePoliceExpense()), ), cardsim.StatFunc( "Economic Planning Expense", - k.ProductivityFunc(&k.EconPlanExpense), + k.ProductivityFunc(k.TrueEconPlanExpense()), ), cardsim.StatFunc( "Parks and Aesthetics Expense", - k.ProductivityFunc(&k.ParksExpense), + k.ProductivityFunc(k.TrueParksExpense()), ), cardsim.StatFunc( "Faith Expense", - k.ProductivityFunc(&k.FaithExpense), + k.ProductivityFunc(k.TrueFaithExpense()), ), cardsim.StatFunc( "Total Sector Income", @@ -269,5 +416,8 @@ func NewKoboldMine() *KoboldMine { ForeignRelations: -0.40, HiddenRelPenalty: -0.01, Secrecy: .95, + PointOfDimReturns: 1.0, } } + +// Note that the mine initializes with 1.02 points of overall productivity.