Refactor, new menu, issue feature update

It's now possible to make issue options enabled or disabled conditional upon having taken other actions with that issue before.
This commit is contained in:
Rakeela Windrider 2023-04-04 13:22:43 -07:00
parent ccd141ddc5
commit e0dad09045
6 changed files with 169 additions and 211 deletions

4
go.mod
View File

@ -2,4 +2,6 @@ module git.chromaticdragon.app/kistaro/KoboldSim
go 1.20 go 1.20
require git.chromaticdragon.app/kistaro/CardSimEngine v0.1.3 require git.chromaticdragon.app/kistaro/CardSimEngine v0.3.0
require golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect

8
go.sum
View File

@ -1,4 +1,4 @@
git.chromaticdragon.app/kistaro/CardSimEngine v0.1.2 h1:+8KVFhSxXbQO7CPzmL89sJ+qjgU4J42Z5OinGuDMR0U= git.chromaticdragon.app/kistaro/CardSimEngine v0.3.0 h1:PYpW6+XTod3oJHf7JyfCpHMCdGILrvyqSJPH/71FMRQ=
git.chromaticdragon.app/kistaro/CardSimEngine v0.1.2/go.mod h1:VFaOagdbtM6gH87ioHent8v76nDh9PddpymMqWdrLfI= git.chromaticdragon.app/kistaro/CardSimEngine v0.3.0/go.mod h1:FYuoJHaK7lDI8Fwf4lZY2Y+8P9zavT4oLvSFUG6drw4=
git.chromaticdragon.app/kistaro/CardSimEngine v0.1.3 h1:rNaDDXnPVoMpavpx4vR9k30sl0nO0BnCe32nZbAF2IM= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
git.chromaticdragon.app/kistaro/CardSimEngine v0.1.3/go.mod h1:VFaOagdbtM6gH87ioHent8v76nDh9PddpymMqWdrLfI= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=

View File

@ -12,15 +12,15 @@ var cards = []Card{
UnenactedDesc: cardsim.MsgStr(`Your war chief paces irritably. "We have terrible threats facing us. It's imperative that we build up our numbers in both the military and the domestic sense. I want creches under military control and a good hunting crew to supply them with food."`), UnenactedDesc: cardsim.MsgStr(`Your war chief paces irritably. "We have terrible threats facing us. It's imperative that we build up our numbers in both the military and the domestic sense. I want creches under military control and a good hunting crew to supply them with food."`),
EnactedDesc: cardsim.MsgStr("[current policy] Your war chief is presntly monitoring the situation, building up your military, and securing your creches."), EnactedDesc: cardsim.MsgStr("[current policy] Your war chief is presntly monitoring the situation, building up your military, and securing your creches."),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value += 100 p.Stats.Kobolds += 100
p.Stats.ScavengingIncome.Value += 0.01 p.Stats.ScavengingIncome += 0.01
p.Stats.WarExpense.Value += 0.02 p.Stats.WarExpense += 0.02
return cardsim.MsgStr("Kobolds are known to be born warriors."), nil return cardsim.MsgStr("Kobolds are known to be born warriors."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value -= 100 p.Stats.Kobolds -= 100
p.Stats.ScavengingIncome.Value -= 0.01 p.Stats.ScavengingIncome -= 0.01
p.Stats.WarExpense.Value -= 0.02 p.Stats.WarExpense -= 0.02
return nil return nil
}, },
CanDo: YesWeCan, CanDo: YesWeCan,
@ -29,15 +29,15 @@ var cards = []Card{
UnenactedDesc: cardsim.MsgStr(`Your head miner considers the matter worriedly. "Creches under military control? No. That would invite chaos. We need to dig deeper; we can have a peaceful, orderly society if we just get far enough away from surfacers."`), UnenactedDesc: cardsim.MsgStr(`Your head miner considers the matter worriedly. "Creches under military control? No. That would invite chaos. We need to dig deeper; we can have a peaceful, orderly society if we just get far enough away from surfacers."`),
EnactedDesc: cardsim.MsgStr("[current policy] Your head miner is presently leading a project to dig as far away from the surface as possible."), EnactedDesc: cardsim.MsgStr("[current policy] Your head miner is presently leading a project to dig as far away from the surface as possible."),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value += 40 p.Stats.Kobolds += 40
p.Stats.MiningIncome.Value += 0.02 p.Stats.MiningIncome += 0.02
p.Stats.BureaucracyExpense.Value += 0.01 p.Stats.BureaucracyExpense += 0.01
return cardsim.MsgStr("Kobolds are known to be cowards hiding in the dark."), nil return cardsim.MsgStr("Kobolds are known to be cowards hiding in the dark."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value -= 40 p.Stats.Kobolds -= 40
p.Stats.MiningIncome.Value -= 0.02 p.Stats.MiningIncome -= 0.02
p.Stats.BureaucracyExpense.Value -= 0.01 p.Stats.BureaucracyExpense -= 0.01
return nil return nil
}, },
CanDo: YesWeCan, CanDo: YesWeCan,
@ -46,15 +46,15 @@ var cards = []Card{
UnenactedDesc: cardsim.MsgStr(`Your nursery director is incensed. "Creches under military control? Never! Let young kobolds play! In fact, cut the military just for suggesting this. The threats facing us are completely overstated."`), UnenactedDesc: cardsim.MsgStr(`Your nursery director is incensed. "Creches under military control? Never! Let young kobolds play! In fact, cut the military just for suggesting this. The threats facing us are completely overstated."`),
EnactedDesc: cardsim.MsgStr("[current policy] Military funding has been diverted into early childhood education."), EnactedDesc: cardsim.MsgStr("[current policy] Military funding has been diverted into early childhood education."),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value -= 40 p.Stats.Kobolds -= 40
p.Stats.ScavengingIncome.Value -= 0.01 p.Stats.ScavengingIncome -= 0.01
p.Stats.WarExpense.Value -= 0.02 p.Stats.WarExpense -= 0.02
return cardsim.MsgStr("An undefended hunting outpost near the surface was recently wiped out by a raid."), nil return cardsim.MsgStr("An undefended hunting outpost near the surface was recently wiped out by a raid."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value += 40 p.Stats.Kobolds += 40
p.Stats.ScavengingIncome.Value += 0.01 p.Stats.ScavengingIncome += 0.01
p.Stats.WarExpense.Value += 0.02 p.Stats.WarExpense += 0.02
return nil return nil
}, },
CanDo: YesWeCan, CanDo: YesWeCan,
@ -63,11 +63,11 @@ var cards = []Card{
Default: &BasicPolicy{ Default: &BasicPolicy{
UnenactedDesc: cardsim.MsgStr("This isn't about a disaster and can probably be safely dismissed."), UnenactedDesc: cardsim.MsgStr("This isn't about a disaster and can probably be safely dismissed."),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value += 20 p.Stats.Kobolds += 20
return cardsim.MsgStr("Creche control doesn't shift that easily."), nil return cardsim.MsgStr("Creche control doesn't shift that easily."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value -= 20 p.Stats.Kobolds -= 20
return nil return nil
}, },
CanDo: YesWeCan, CanDo: YesWeCan,
@ -102,15 +102,15 @@ var cards = []Card{
UnenactedDesc: cardsim.MsgStr(`Your Minister of Administration is practically jumping for joy. "This is our opportunity to prove that we're a prosperous society and attract some fresh blood! We need to raise salaries in the bureaucracy, grant some time off to our bureaucrats to make sure they can attend, and try to hire talent away from other nations. We'll forge productive trade relations by this, you'll see!`), UnenactedDesc: cardsim.MsgStr(`Your Minister of Administration is practically jumping for joy. "This is our opportunity to prove that we're a prosperous society and attract some fresh blood! We need to raise salaries in the bureaucracy, grant some time off to our bureaucrats to make sure they can attend, and try to hire talent away from other nations. We'll forge productive trade relations by this, you'll see!`),
EnactedDesc: cardsim.MsgStr("[current policy] Your bureaucrats are really looking forward to attending, where they can boast about how the festival boosted their salaries."), EnactedDesc: cardsim.MsgStr("[current policy] Your bureaucrats are really looking forward to attending, where they can boast about how the festival boosted their salaries."),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value += 80 p.Stats.Kobolds += 80
p.Stats.ScavengingIncome.Value += 0.01 p.Stats.ScavengingIncome += 0.01
p.Stats.BureaucracyExpense.Value += 0.03 p.Stats.BureaucracyExpense += 0.03
return cardsim.MsgStr("Bureaucrats are considered pillars of society."), nil return cardsim.MsgStr("Bureaucrats are considered pillars of society."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value -= 80 p.Stats.Kobolds -= 80
p.Stats.ScavengingIncome.Value -= 0.01 p.Stats.ScavengingIncome -= 0.01
p.Stats.BureaucracyExpense.Value -= 0.03 p.Stats.BureaucracyExpense -= 0.03
return nil return nil
}, },
CanDo: YesWeCan, CanDo: YesWeCan,
@ -119,16 +119,18 @@ var cards = []Card{
UnenactedDesc: cardsim.MsgStr(`Your Minister of Finance pulls you aside. "This is a good opportunity to head-hunt. Bureaucrats from many nations will be attending. There's got to be some who'll work for less than the ones we've got. There are some terribly threatened or impoverished communities among kobolds.`), UnenactedDesc: cardsim.MsgStr(`Your Minister of Finance pulls you aside. "This is a good opportunity to head-hunt. Bureaucrats from many nations will be attending. There's got to be some who'll work for less than the ones we've got. There are some terribly threatened or impoverished communities among kobolds.`),
EnactedDesc: cardsim.MsgStr("[current policy] Your nation's policy is clear: the festival of bureaucracy is a chance to trade workers with other kobold nations in your attempts to build a more efficient government."), EnactedDesc: cardsim.MsgStr("[current policy] Your nation's policy is clear: the festival of bureaucracy is a chance to trade workers with other kobold nations in your attempts to build a more efficient government."),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value += 20 p.Stats.Kobolds += 20
p.Stats.BureaucracyExpense.Value -= 0.01 p.Stats.BureaucracyExpense -= 0.01
return cardsim.MsgStr("Immigrant bureaucrats complain about being under-appreciated."), nil return cardsim.MsgStr("Immigrant bureaucrats complain about being under-appreciated."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value -= 20 p.Stats.Kobolds -= 20
p.Stats.BureaucracyExpense.Value += 0.01 p.Stats.BureaucracyExpense += 0.01
return nil return nil
}, },
CanDo: func(p *Player) bool { return p.Stats.BureaucracyExpense.Value >= 0.02 }, CanDo: func(b *BasicPolicy, p *Player) bool {
return p.Stats.BureaucracyExpense >= 0.02 && b.LastEnactedIdx != 3
},
// CanDo: func(p *Player) bool { // CanDo: func(p *Player) bool {
// if p.Stats.GovBureaucracyExpense.Value >= 0.02 { // if p.Stats.GovBureaucracyExpense.Value >= 0.02 {
// return true // return true
@ -141,28 +143,30 @@ var cards = []Card{
UnenactedDesc: cardsim.MsgStr(`Your Minister of Finance greets you exuberantly. "We've trimmed the wages of the bureaucracy beautifully, but maybe we can scout some outright volunteers. Some nations are absolute disasters, after all.`), UnenactedDesc: cardsim.MsgStr(`Your Minister of Finance greets you exuberantly. "We've trimmed the wages of the bureaucracy beautifully, but maybe we can scout some outright volunteers. Some nations are absolute disasters, after all.`),
EnactedDesc: cardsim.MsgStr(`[current policy] It's hard to find volunteer workers at the festival, but your nation is doing its best.`), EnactedDesc: cardsim.MsgStr(`[current policy] It's hard to find volunteer workers at the festival, but your nation is doing its best.`),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value += 10 p.Stats.Kobolds += 10
p.Stats.BureaucracyExpense.Value -= 0.02 p.Stats.BureaucracyExpense -= 0.02
return cardsim.MsgStr("The local bureaucracy is staffed by volunteer labor."), nil return cardsim.MsgStr("The local bureaucracy is staffed by volunteer labor."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value -= 10 p.Stats.Kobolds -= 10
p.Stats.BureaucracyExpense.Value += 0.02 p.Stats.BureaucracyExpense += 0.02
return nil return nil
}, },
CanDo: func(p *Player) bool { return p.Stats.BureaucracyExpense.Value < 0.02 }, CanDo: func(b *BasicPolicy, p *Player) bool {
return p.Stats.BureaucracyExpense < 0.02 && b.LastEnactedIdx != 3
},
}, },
&BasicPolicy{ &BasicPolicy{
UnenactedDesc: cardsim.MsgStr(`One of your non-bureaucrat friends has been in a foul temper. "This festival is everything that's wrong with our society. Life isn't about filling out forms. We ought to snub this festival and outright fire some bureaucrats."`), UnenactedDesc: cardsim.MsgStr(`One of your non-bureaucrat friends has been in a foul temper. "This festival is everything that's wrong with our society. Life isn't about filling out forms. We ought to snub this festival and outright fire some bureaucrats."`),
EnactedDesc: cardsim.MsgStr("Your nation currently bans the International Festival of Bureaucracy. There will be no local celebration without a policy change."), EnactedDesc: cardsim.MsgStr("Your nation currently bans the International Festival of Bureaucracy. There will be no local celebration without a policy change."),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value -= 80 p.Stats.Kobolds -= 80
p.Stats.BureaucracyExpense.Value -= 0.04 p.Stats.BureaucracyExpense -= 0.04
return cardsim.MsgStr("A wave of bureaucrats just emigrated along with kobolds incensed by the nation's lack of respect for administration."), nil return cardsim.MsgStr("A wave of bureaucrats just emigrated along with kobolds incensed by the nation's lack of respect for administration."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value += 80 p.Stats.Kobolds += 80
p.Stats.BureaucracyExpense.Value += 0.04 p.Stats.BureaucracyExpense += 0.04
return nil return nil
}, },
CanDo: YesWeCan, CanDo: YesWeCan,
@ -172,11 +176,11 @@ var cards = []Card{
UnenactedDesc: cardsim.MsgStr("Some kobolds will attend the festival on their own, and we may face desertions for our lack of interest."), UnenactedDesc: cardsim.MsgStr("Some kobolds will attend the festival on their own, and we may face desertions for our lack of interest."),
EnactedDesc: cardsim.MsgStr("Some kobolds will attend the festival on their own. No change is expected."), EnactedDesc: cardsim.MsgStr("Some kobolds will attend the festival on their own. No change is expected."),
Do: func(p *Player) (cardsim.Message, error) { Do: func(p *Player) (cardsim.Message, error) {
p.Stats.Kobolds.Value -= 20 p.Stats.Kobolds -= 20
return cardsim.MsgStr("A festival of bureaucracy lured away a few kobolds to other nations."), nil return cardsim.MsgStr("A festival of bureaucracy lured away a few kobolds to other nations."), nil
}, },
Undo: func(p *Player) error { Undo: func(p *Player) error {
p.Stats.Kobolds.Value += 20 p.Stats.Kobolds += 20
return nil return nil
}, },
CanDo: YesWeCan, CanDo: YesWeCan,
@ -187,13 +191,13 @@ var cards = []Card{
&DisabledPolicy{cardsim.MsgStr("Neglecting the event would be less popular and more inefficient than our current policy.")}, &DisabledPolicy{cardsim.MsgStr("Neglecting the event would be less popular and more inefficient than our current policy.")},
&FuncPolicy{ &FuncPolicy{
OptionTextFunc: func(p *Player) (cardsim.Message, error) { OptionTextFunc: func(p *Player) (cardsim.Message, error) {
if p.Stats.BureaucracyExpense.Value >= -0.03 { if p.Stats.BureaucracyExpense >= -0.03 {
return cardsim.MsgStr("Permitting the festival will yield some immigration, but we'll be expected to rebuild our bureaucracy."), nil return cardsim.MsgStr("Permitting the festival will yield some immigration, but we'll be expected to rebuild our bureaucracy."), nil
} }
return cardsim.MsgStr("Permitting the festival will yield some immigration."), nil return cardsim.MsgStr("Permitting the festival will yield some immigration."), nil
}, },
EnactFunc: func(p *Player) (cardsim.Message, error) { EnactFunc: func(p *Player) (cardsim.Message, error) {
if p.Stats.BureaucracyExpense.Value >= -0.03 { if p.Stats.BureaucracyExpense >= -0.03 {
return cardsim.MsgStr("A festival of bureaucracy just saw the nation's bureaucracy rebuilt."), ErrKeepMessage return cardsim.MsgStr("A festival of bureaucracy just saw the nation's bureaucracy rebuilt."), ErrKeepMessage
} }
return cardsim.MsgStr("A festival of bureaucracy brought in immigrants wondering at the nation's lack thereof."), ErrKeepMessage return cardsim.MsgStr("A festival of bureaucracy brought in immigrants wondering at the nation's lack thereof."), ErrKeepMessage

View File

@ -114,25 +114,29 @@ type BasicPolicy struct {
NothingChanged cardsim.Message NothingChanged cardsim.Message
Do func(*Player) (cardsim.Message, error) Do func(*Player) (cardsim.Message, error)
Undo func(*Player) error Undo func(*Player) error
CanDo func(*Player) bool CanDo func(*BasicPolicy, *Player) bool
currentlyEnacted bool CurrentlyEnacted bool
LastEnactedPolicy Policy
LastEnactedIdx int
} }
// YesWeCan returns true. It's the default value for BasicPolicy.CanDo / BasicPolicy.CanUndo. // YesWeCan returns true. It's the default value for BasicPolicy.CanDo / BasicPolicy.CanUndo.
func YesWeCan(*Player) bool { func YesWeCan(*BasicPolicy, *Player) bool {
return true return true
} }
// LastEnacted notifies b about the last-enacted policy in its group. It updates // LastEnacted notifies b about the last-enacted policy in its group. It updates
// b.currentlyEnacted accordingly. // b.currentlyEnacted accordingly.
func (b *BasicPolicy) LastEnacted(_ int, p Policy) { func (b *BasicPolicy) LastEnacted(i int, p Policy) {
b.currentlyEnacted = b.Is(p) b.LastEnactedPolicy = p
b.LastEnactedIdx = i
b.CurrentlyEnacted = b.Is(p)
} }
// OptionText implements CardOption. // OptionText implements CardOption.
func (b *BasicPolicy) OptionText(*Player) (cardsim.Message, error) { func (b *BasicPolicy) OptionText(*Player) (cardsim.Message, error) {
if b.currentlyEnacted { if b.CurrentlyEnacted {
if b.EnactedDesc == nil { if b.EnactedDesc == nil {
return nil, ErrUnimplemented return nil, ErrUnimplemented
} }
@ -149,7 +153,7 @@ func (b *BasicPolicy) Enact(p *Player) (cardsim.Message, error) {
if b.Do == nil { if b.Do == nil {
return nil, ErrUnimplemented return nil, ErrUnimplemented
} }
if b.currentlyEnacted { if b.CurrentlyEnacted {
p.ActionsRemaining++ p.ActionsRemaining++
if b.NothingChanged == nil { if b.NothingChanged == nil {
b.NothingChanged = cardsim.MsgStr("You continue your current approach.") b.NothingChanged = cardsim.MsgStr("You continue your current approach.")
@ -161,7 +165,7 @@ func (b *BasicPolicy) Enact(p *Player) (cardsim.Message, error) {
// Unenact implements Policy. // Unenact implements Policy.
func (b *BasicPolicy) Unenact(p *Player) error { func (b *BasicPolicy) Unenact(p *Player) error {
if !b.currentlyEnacted { if !b.CurrentlyEnacted {
return ErrPolicyNotEnacted return ErrPolicyNotEnacted
} }
if b.Undo == nil { if b.Undo == nil {
@ -172,13 +176,13 @@ func (b *BasicPolicy) Unenact(p *Player) error {
// Enabled implements CardOption. // Enabled implements CardOption.
func (b *BasicPolicy) Enabled(p *Player) bool { func (b *BasicPolicy) Enabled(p *Player) bool {
if b.currentlyEnacted { if b.CurrentlyEnacted {
return true return true
} }
if b.CanDo == nil { if b.CanDo == nil {
panic(ErrUnimplemented) panic(ErrUnimplemented)
} }
return b.CanDo(p) return b.CanDo(b, p)
} }
func (b *BasicPolicy) Is(p Policy) bool { func (b *BasicPolicy) Is(p Policy) bool {
@ -192,14 +196,14 @@ func (b *BasicPolicy) Is(p Policy) bool {
// policy. Which policy is used is determined by what the previous policy for // policy. Which policy is used is determined by what the previous policy for
// the card was (as reported via a call to LastEnacted): // the card was (as reported via a call to LastEnacted):
// //
// * If no policy has yet been enacted, use FirstTime. // - If no policy has yet been enacted, use FirstTime.
// * If a policy has been enacted, use the Policy at the slot in Variants // - If a policy has been enacted, use the Policy at the slot in Variants
// that corresponds to the slot (on the Card) of the currently-enacted policy. // that corresponds to the slot (on the Card) of the currently-enacted policy.
// * If the policy retrieved in this way returns ErrUnimplemented, throw away // - If the policy retrieved in this way returns ErrUnimplemented, throw away
// its response and use Default instead. For Enabled, which does not have // its response and use Default instead. For Enabled, which does not have
// an error component to its return value, look for ErrUnimplemented as the // an error component to its return value, look for ErrUnimplemented as the
// argument to a Panic call, instead. // argument to a Panic call, instead.
// * If the policy retrieved in this way returns ErrKeepMessage when Enact // - If the policy retrieved in this way returns ErrKeepMessage when Enact
// is called, it calls Default for the side effects but ignores its message, // is called, it calls Default for the side effects but ignores its message,
// retaining the message from the original call. This is to avoid having to // retaining the message from the original call. This is to avoid having to
// repeat the same Enact function except with different text each time. // repeat the same Enact function except with different text each time.
@ -254,7 +258,7 @@ func (v *VerbosePolicy) fillDefaults() {
for len(v.Variants) <= v.lastIdx { for len(v.Variants) <= v.lastIdx {
v.Variants = append(v.Variants, v.Default) v.Variants = append(v.Variants, v.Default)
} }
if v.lastIdx > 0 && v.Variants[v.lastIdx] == nil { if v.lastIdx >= 0 && v.Variants[v.lastIdx] == nil {
v.Variants[v.lastIdx] = v.Default v.Variants[v.lastIdx] = v.Default
} }
} }

View File

@ -1,6 +1,10 @@
package koboldsim package koboldsim
import "git.chromaticdragon.app/kistaro/CardSimEngine/cardsim" import (
"strings"
"git.chromaticdragon.app/kistaro/CardSimEngine/cardsim"
)
func InitPlayer() *Player { func InitPlayer() *Player {
p := cardsim.InitPlayer(NewKoboldMine()) p := cardsim.InitPlayer(NewKoboldMine())
@ -13,6 +17,16 @@ func InitPlayer() *Player {
Name: cardsim.MsgStr("All Stats"), Name: cardsim.MsgStr("All Stats"),
Intro: cardsim.MsgStr("All available statistics."), Intro: cardsim.MsgStr("All available statistics."),
}, },
&cardsim.BasicStatsPanel[*KoboldMine]{
Name: cardsim.MsgStr("Per Capita Economic"),
Intro: cardsim.MsgStr("Yield and Investment per Capita"),
Filter: cardsim.All(
cardsim.VisibleOrDebug[*KoboldMine],
func(p *Player, s cardsim.Stat) bool {
return strings.Contains(s.StatName(), "Productivity") || strings.Contains(s.StatName(), "Investment")
},
),
},
} }
p.Prompt = &cardsim.BasicStatsPanel[*KoboldMine]{ p.Prompt = &cardsim.BasicStatsPanel[*KoboldMine]{
Name: cardsim.MsgStr("The Kobold Mine"), Name: cardsim.MsgStr("The Kobold Mine"),
@ -21,6 +35,7 @@ func InitPlayer() *Player {
"Kobolds", "Kobolds",
"Total Sector Income", "Total Sector Income",
"Total Government Expense", "Total Government Expense",
"Tax Rate",
), ),
} }
p.State = cardsim.GameActive p.State = cardsim.GameActive

View File

@ -6,48 +6,59 @@ import (
// KoboldMine is the state of a kobold mine. // KoboldMine is the state of a kobold mine.
type KoboldMine struct { type KoboldMine struct {
Kobolds cardsim.Stored[int64] Kobolds int64 `cardsim:"stat"`
MiningIncome cardsim.Stored[float64] MiningIncome float64 `cardsim:"stat" cardsim_name:"Mining Productivity"`
ScavengingIncome cardsim.Stored[float64] ScavengingIncome float64 `cardsim:"stat" cardsim_name:"Scavenging Productivity"`
AlchemyIncome cardsim.Stored[float64] AlchemyIncome float64 `cardsim:"stat" cardsim_name:"Alchemy Productivity"`
HospitalityIncome cardsim.Stored[float64] HospitalityIncome float64 `cardsim:"stat" cardsim_name:"Hospitality Productivity"`
AgricultureIncome cardsim.Stored[float64] AgricultureIncome float64 `cardsim:"stat" cardsim_name:"Agriculture Productivity"`
ManufacturingIncome cardsim.Stored[float64] ManufacturingIncome float64 `cardsim:"stat" cardsim_name:"Manufacturing Productivity"`
PlanarIncome cardsim.Stored[float64] PlanarIncome float64 `cardsim:"stat" cardsim_name:"Planar Productivity"`
PublishingIncome cardsim.Stored[float64] PublishingIncome float64 `cardsim:"stat" cardsim_name:"Publishing Productivity"`
FinanceIncome cardsim.Stored[float64] FinanceIncome float64 `cardsim:"stat" cardsim_name:"Finance Productivity"`
GadgetryIncome cardsim.Stored[float64] GadgetryIncome float64 `cardsim:"stat" cardsim_name:"Gadgetry Productivity"`
FishingIncome cardsim.Stored[float64] FishingIncome float64 `cardsim:"stat" cardsim_name:"Fishing Productivity"`
ConstructionIncome cardsim.Stored[float64] ConstructionIncome float64 `cardsim:"stat" cardsim_name:"Construction Productivity"`
BureaucracyExpense cardsim.Stored[float64] BureaucracyExpense float64 `cardsim:"stat" cardsim_name:"Bureaucracy Investment"`
WarExpense cardsim.Stored[float64] WarExpense float64 `cardsim:"stat" cardsim_name:"War Investment"`
QoLExpense cardsim.Stored[float64] QoLExpense float64 `cardsim:"stat" cardsim_name:"QoL Investment"`
LogisticsExpense cardsim.Stored[float64] LogisticsExpense float64 `cardsim:"stat" cardsim_name:"Logistics Investment"`
DragonSubsExpense cardsim.Stored[float64] DragonSubsExpense float64 `cardsim:"stat" cardsim_name:"Dragon Subsidies Investment"`
ResearchSubsExpense cardsim.Stored[float64] ResearchSubsExpense float64 `cardsim:"stat" cardsim_name:"Research Subsidies Investment"`
EducationExpense cardsim.Stored[float64] EducationExpense float64 `cardsim:"stat" cardsim_name:"Education Investment"`
HealthcareExpense cardsim.Stored[float64] HealthcareExpense float64 `cardsim:"stat" cardsim_name:"Healthcare Investment"`
ForeignRelExpense cardsim.Stored[float64] ForeignRelExpense float64 `cardsim:"stat" cardsim_name:"Foreign Relations Investment"`
PoliceExpense cardsim.Stored[float64] PoliceExpense float64 `cardsim:"stat" cardsim_name:"Law Enforcement Investment"`
EconPlanExpense cardsim.Stored[float64] EconPlanExpense float64 `cardsim:"stat" cardsim_name:"Economic Planning Investment"`
ParksExpense cardsim.Stored[float64] ParksExpense float64 `cardsim:"stat" cardsim_name:"Parks and Aesthetics Investment"`
FaithExpense cardsim.Stored[float64] FaithExpense float64 `cardsim:"stat" cardsim_name:"Faith Investment"`
// AnotherExpense float64 `cardsim:"hiddenround5"`
// A different way of adding stats that is slightly more empowering.
} }
func (k *KoboldMine) ProductivityFunc(s *cardsim.Stored[float64]) func() float64 { func (k *KoboldMine) ProductivityFunc(s *float64) func() float64 {
return func() float64 { return func() float64 {
return s.Value * float64(k.Kobolds.Value) return *s * float64(k.Kobolds)
} }
} }
func (k *KoboldMine) TotalSectorIncome() float64 { func (k *KoboldMine) TotalSectorIncome() float64 {
return float64(k.Kobolds.Value) * (k.MiningIncome.Value + k.ScavengingIncome.Value + k.AlchemyIncome.Value + k.HospitalityIncome.Value + k.AgricultureIncome.Value + k.ManufacturingIncome.Value + k.PlanarIncome.Value + k.PublishingIncome.Value + k.FinanceIncome.Value + k.GadgetryIncome.Value + k.FishingIncome.Value + k.ConstructionIncome.Value) 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)
} }
func (k *KoboldMine) TotalGovExpense() float64 { func (k *KoboldMine) TotalGovExpense() float64 {
return float64(k.Kobolds.Value) * (k.BureaucracyExpense.Value + k.WarExpense.Value + k.QoLExpense.Value + k.LogisticsExpense.Value + k.DragonSubsExpense.Value + k.ResearchSubsExpense.Value + k.EducationExpense.Value + k.HealthcareExpense.Value + k.ForeignRelExpense.Value + k.PoliceExpense.Value + k.EconPlanExpense.Value + k.ParksExpense.Value + k.FaithExpense.Value) return float64(k.Kobolds) * (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)
}
func (k *KoboldMine) Taxation() float64 {
return (k.TotalGovExpense() / (k.TotalSectorIncome() + k.TotalGovExpense())) * 100
}
func (k *KoboldMine) StatTaxRate() float64 {
return k.Taxation()
} }
func (k *KoboldMine) Stats() []cardsim.Stat { func (k *KoboldMine) Stats() []cardsim.Stat {
@ -169,109 +180,31 @@ func (k *KoboldMine) Stats() []cardsim.Stat {
func NewKoboldMine() *KoboldMine { func NewKoboldMine() *KoboldMine {
return &KoboldMine{ return &KoboldMine{
Kobolds: cardsim.Stored[int64]{ Kobolds: 1000,
Name: "Kobolds", MiningIncome: 0.15,
Value: 1000, ScavengingIncome: 0.1,
}, AlchemyIncome: 0.01,
MiningIncome: cardsim.Stored[float64]{ HospitalityIncome: 0.0,
Name: "Mining Productivity", AgricultureIncome: 0.0,
Value: 0.15, ManufacturingIncome: 0.10,
}, PlanarIncome: 0.00,
ScavengingIncome: cardsim.Stored[float64]{ PublishingIncome: 0.02,
Name: "Scavenging Productivity", FinanceIncome: 0.02,
Value: 0.1, GadgetryIncome: 0.03,
}, FishingIncome: 0.0,
AlchemyIncome: cardsim.Stored[float64]{ ConstructionIncome: 0.05,
Name: "Alchemy Productivity", BureaucracyExpense: 0.05,
Value: 0.01, WarExpense: 0.1,
}, QoLExpense: 0.01,
HospitalityIncome: cardsim.Stored[float64]{ LogisticsExpense: 0.02,
Name: "Hospitality Productivity", DragonSubsExpense: 0.0,
Value: 0.0, ResearchSubsExpense: 0.0,
}, EducationExpense: 0.01,
AgricultureIncome: cardsim.Stored[float64]{ HealthcareExpense: 0.01,
Name: "Agricultural Productivity", ForeignRelExpense: 0.0,
Value: 0.0, PoliceExpense: 0.03,
}, EconPlanExpense: 0.02,
ManufacturingIncome: cardsim.Stored[float64]{ ParksExpense: 0.0,
Name: "Manufacturing Productivity", FaithExpense: 0.03,
Value: 0.10,
},
PlanarIncome: cardsim.Stored[float64]{
Name: "Planar Harvesting Productivity",
Value: 0.00,
},
PublishingIncome: cardsim.Stored[float64]{
Name: "Book Publishing Productivity",
Value: 0.02,
},
FinanceIncome: cardsim.Stored[float64]{
Name: "Finance Productivity",
Value: 0.02,
},
GadgetryIncome: cardsim.Stored[float64]{
Name: "Gadgetry Productivity",
Value: 0.03,
},
FishingIncome: cardsim.Stored[float64]{
Name: "Fishing Productivity",
Value: 0.0,
},
ConstructionIncome: cardsim.Stored[float64]{
Name: "Construction Productivity",
Value: 0.05,
},
BureaucracyExpense: cardsim.Stored[float64]{
Name: "Bureaucracy Investment",
Value: 0.05,
},
WarExpense: cardsim.Stored[float64]{
Name: "War Investment",
Value: 0.1,
},
QoLExpense: cardsim.Stored[float64]{
Name: "QoL Investment",
Value: 0.01,
},
LogisticsExpense: cardsim.Stored[float64]{
Name: "Logistics Investment",
Value: 0.02,
},
DragonSubsExpense: cardsim.Stored[float64]{
Name: "Dragon Subsidies Investment",
Value: 0.0,
},
ResearchSubsExpense: cardsim.Stored[float64]{
Name: "Research Subsidies Investment",
Value: 0.0,
},
EducationExpense: cardsim.Stored[float64]{
Name: "Education Investment",
Value: 0.01,
},
HealthcareExpense: cardsim.Stored[float64]{
Name: "Healthcare Investment",
Value: 0.01,
},
ForeignRelExpense: cardsim.Stored[float64]{
Name: "Foreign Relations Investment",
Value: 0.0,
},
PoliceExpense: cardsim.Stored[float64]{
Name: "Law Enforcement Investment",
Value: 0.03,
},
EconPlanExpense: cardsim.Stored[float64]{
Name: "Economic Planning Investment",
Value: 0.02,
},
ParksExpense: cardsim.Stored[float64]{
Name: "Parks and Aesthetics Investment",
Value: 0.0,
},
FaithExpense: cardsim.Stored[float64]{
Name: "Faith Investment",
Value: 0.03,
},
} }
} }