Move logic into simulation

This commit is contained in:
Trevor Slocum 2023-06-29 21:28:31 -07:00
parent 6e408b23d9
commit 3098eb9867
5 changed files with 77 additions and 87 deletions

View file

@ -33,11 +33,7 @@ Run `~/go/bin/pretzel-tycoon` to play.
Please share issues and suggestions [here](https://code.rocketnine.space/tslocum/pretzel-tycoon/issues).
## Credits
- [Trevor Slocum](https://rocketnine.space) - Game design and programming
## Dependencies
- [ebitengine](https://github.com/hajimehoshi/ebiten) - Game engine
- [etk](https://code.rocketnine.space/tslocum/etk) - Graphical user interface toolkit
- [messeji](https://code.rocketnine.space/tslocum/messeji) - Text widgets

View file

@ -34,19 +34,9 @@ type Game struct {
dayBuffer [][]byte
day int
inputLetters bool // Whether to allow the user to input letters.
makePretzels int // In dozens.
makePretzelsLast int
makeSigns int
makeSignsLast int
pretzelPrice int // In cents.
pretzelPriceLast int
simulation *Simulation
sim *Simulation
}
func loadFont() font.Face {
@ -77,16 +67,9 @@ func NewGame() (*Game, error) {
etk.Style.TextFont = loadFont()
g := &Game{
currentView: world.StartingView,
day: 1,
makePretzels: -1,
makePretzelsLast: -1,
makeSigns: -1,
makeSignsLast: -1,
pretzelPrice: -1,
pretzelPriceLast: -1,
dayBuffer: make([][]byte, 18),
simulation: &Simulation{},
currentView: world.StartingView,
dayBuffer: make([][]byte, 18),
sim: NewSimulation(),
}
g.inputBuffer = etk.NewInput("", "", g.acceptInput)
g.textBuffer = etk.NewText("Hello world!")
@ -122,35 +105,30 @@ func (g *Game) Layout(_, _ int) (screenWidth, screenHeight int) {
}
func (g *Game) inputActive() bool {
switch g.currentView {
case world.ViewStartDayProduction1:
return g.makePretzels == -1
case world.ViewStartDayProduction2:
return g.makeSigns == -1
case world.ViewStartDayProduction3:
return g.pretzelPrice == -1
for _, view := range world.InputViews {
if g.currentView == view {
return true
}
}
return false
}
func (g *Game) acceptInput(text string) (handled bool) {
if text == "" {
log.Println("blank", g.currentView)
switch g.currentView {
case world.ViewStartDayProduction1:
if g.makePretzelsLast == -1 {
if g.sim.MakePretzels == -1 {
return false
}
g.makePretzels = g.makePretzelsLast
case world.ViewStartDayProduction2:
if g.makeSignsLast == -1 {
if g.sim.MakeSigns == -1 {
return false
}
g.makeSigns = g.makeSignsLast
case world.ViewStartDayProduction3:
if g.pretzelPriceLast == -1 {
if g.sim.PretzelPrice == -1 {
return false
}
g.pretzelPrice = g.pretzelPriceLast
}
} else {
// TODO handle non-numeric input
@ -160,27 +138,30 @@ func (g *Game) acceptInput(text string) (handled bool) {
}
switch g.currentView {
case world.ViewStartDayProduction1:
g.makePretzels = i
g.sim.MakePretzels = i
case world.ViewStartDayProduction2:
g.makeSigns = i
g.sim.MakeSigns = i
case world.ViewStartDayProduction3:
g.pretzelPrice = i
g.sim.PretzelPrice = i
}
}
log.Println("accept input:" + text)
g.currentView++
partialTransition := g.currentView == world.ViewStartDayProduction2 || g.currentView == world.ViewStartDayProduction3
if partialTransition {
viewBytes := viewText[g.currentView-1]
lines := bytes.Split(viewBytes, []byte("\n"))
g.viewTicks = len(lines) - 4
g.viewTicks = len(lines) - 2
} else {
g.viewTicks = 0
}
log.Println(g.currentView)
if g.currentView == world.ViewDay {
g.simulation.StartDay()
log.Println("start day")
g.sim.StartDay()
}
g.refreshBuffer()
@ -234,7 +215,7 @@ func (g *Game) drawDay() error {
drawPretzelStand(12, 6)
// Draw actors.
for _, a := range g.simulation.Actors {
for _, a := range g.sim.Actors {
g.setDayCell(a.X, a.Y, 'o')
g.setDayCell(a.X+1, a.Y, 'o')
}
@ -257,12 +238,9 @@ func (g *Game) refreshBuffer() error {
return g.drawDay()
}
pretzelsSold := 50
pretzelPrice := "$.10"
totalIncome := "$5.00"
income := g.sim.PretzelsSold * g.sim.PretzelPrice
totalIncome := fmt.Sprintf("$%d.%02d", income/100, income%100)
pretzelsMade := 50
signsMade := 3
totalExpenses := "$1.45"
profit := "$3.55"
@ -286,20 +264,24 @@ func (g *Game) refreshBuffer() error {
}
}
formatCents := func(cents int) string {
return fmt.Sprintf("$%d.%02d", cents/100, cents%100)
}
// Format view.
var lines [][]byte
switch g.currentView {
case world.ViewStartDayProduction1:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day))
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.sim.Day))
lines = bytes.Split(viewBytes, []byte("\n"))
case world.ViewStartDayProduction2:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day, g.makePretzels))
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.sim.Day, g.sim.MakePretzels))
lines = bytes.Split(viewBytes, []byte("\n"))
case world.ViewStartDayProduction3:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day, g.makePretzels, g.makeSigns))
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.sim.Day, g.sim.MakePretzels, g.sim.MakeSigns))
lines = bytes.Split(viewBytes, []byte("\n"))
case world.ViewFinancialReport:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day, pretzelsSold, pretzelPrice, totalIncome, pretzelsMade, signsMade, totalExpenses, profit, assets))
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.sim.Day, g.sim.PretzelsSold, formatCents(g.sim.PretzelPrice), totalIncome, g.sim.MakePretzels, g.sim.MakeSigns, totalExpenses, profit, assets))
lines = bytes.Split(viewBytes, []byte("\n"))
default:
lines = bytes.Split(viewBytes, []byte("\n"))
@ -328,18 +310,6 @@ func (g *Game) refreshBuffer() error {
return nil
}
func (g *Game) resetDay() error {
g.makePretzelsLast = g.makePretzels
g.makePretzels = -1
g.makeSignsLast = g.makeSigns
g.makeSigns = -1
g.pretzelPriceLast = g.pretzelPrice
g.pretzelPrice = -1
return nil
}
func (g *Game) Update() error {
if ebiten.IsWindowBeingClosed() || (!world.WASM && ebiten.IsKeyPressed(ebiten.KeyEscape)) {
g.Exit()
@ -381,9 +351,18 @@ func (g *Game) Update() error {
}
} else if inpututil.IsKeyJustPressed(ebiten.KeyEnter) || inpututil.IsKeyJustPressed(ebiten.KeyKPEnter) || (g.currentView != world.ViewDay && inpututil.IsKeyJustPressed(ebiten.KeySpace)) {
if g.currentView == world.ViewFinancialReport {
g.resetDay()
g.sim.Day++
g.currentView = world.ViewStartDayProduction1
} else {
// Skip to end of day.
if g.currentView == world.ViewDay {
for !g.sim.DayFinished {
err := g.sim.Tick()
if err != nil {
return err
}
}
}
g.currentView++
}
g.viewTicks = 0
@ -395,13 +374,13 @@ func (g *Game) Update() error {
numTicks = 4
}
for i := 0; i < numTicks; i++ {
err := g.simulation.Tick()
err := g.sim.Tick()
if err != nil {
return err
}
}
if g.simulation.DayFinished {
if g.sim.DayFinished {
g.currentView++
g.viewTicks = 0
}

View file

@ -14,10 +14,28 @@ type SimulationActor struct {
}
type Simulation struct {
Day int
Money int
Actors []*SimulationActor
DayFinished bool
DayFinishedTicks int
PretzelsSold int
MakePretzels int
MakeSigns int
PretzelPrice int // In cents.
}
func NewSimulation() *Simulation {
return &Simulation{
Day: 1,
MakePretzels: -1,
MakeSigns: -1,
PretzelPrice: -1,
}
}
func (s *Simulation) generateActors() {
@ -42,6 +60,7 @@ func (s *Simulation) StartDay() {
s.Actors = s.Actors[:0]
s.DayFinished = false
s.DayFinishedTicks = 25
s.PretzelsSold = 0
s.generateActors()
}
@ -89,6 +108,8 @@ func (s *Simulation) Tick() error {
if a.X == tx && a.Y == ty {
if !a.TargetActive {
s.PretzelsSold++
a.TargetActive = true
a.WaitTicks = 100 + rand.Intn(150)
continue

View file

@ -49,22 +49,14 @@ YOU WILL BEGIN WITH $4.20 CASH (ASSETS).
// viewStartDayProduction1
[]byte(` DAY %d
STARTING SUPPLIES
PRODUCTION AMOUNTS
HOW MANY BATCHES (DOZENS) OF PRETZELS
DO YOU WISH TO MAKE ?`),
HOW MANY PRETZELS ($0.15 EACH) DO YOU
WISH TO MAKE ?`),
// viewStartDayProduction2
[]byte(` DAY %d
STARTING SUPPLIES
PRODUCTION AMOUNTS
HOW MANY BATCHES (DOZENS) OF PRETZELS
DO YOU WISH TO MAKE ?%d
HOW MANY PRETZELS ($0.15 EACH) DO YOU
WISH TO MAKE ?%d
HOW MANY ADVERTISING SIGNS ($1.25 EACH)
DO YOU WISH TO MAKE ?`),
@ -72,12 +64,8 @@ DO YOU WISH TO MAKE ?`),
// viewStartDayProduction3
[]byte(` DAY %d
STARTING SUPPLIES
PRODUCTION AMOUNTS
HOW MANY BATCHES (DOZENS) OF PRETZELS
DO YOU WISH TO MAKE ?%d
HOW MANY PRETZELS ($0.15 EACH) DO YOU
WISH TO MAKE ?%d
HOW MANY ADVERTISING SIGNS ($1.25 EACH)
DO YOU WISH TO MAKE ?%d

View file

@ -24,6 +24,12 @@ const (
ViewFinancialReport
)
var InputViews = []ViewType{
ViewStartDayProduction1,
ViewStartDayProduction2,
ViewStartDayProduction3,
}
var (
ScreenWidth int
ScreenHeight int