package tins2020 import ( "math/rand" "time" ) type Game struct { Money int Terrain *Map start time.Time lastUpdate time.Duration } type Map struct { Temp NoiseMap Humid NoiseMap Variant NoiseMap PlaceX NoiseMap // displacement map of props PlaceY NoiseMap Flowers map[Point]Flower } func (m *Map) AddFlower(pos Point, traits FlowerTraits) { m.Flowers[pos] = m.NewFlower(pos, traits) } func (m *Map) NewFlower(pos Point, traits FlowerTraits) Flower { flower := Flower{ Traits: traits, } temp, humid := float32(m.Temp.Value(pos.X, pos.Y)), float32(m.Humid.Value(pos.X, pos.Y)) flower.Traits.UpdateModifier(temp, humid) return flower } func NewGame() *Game { terrain := &Map{ Temp: NewNoiseMap(rand.Int63()), Humid: NewNoiseMap(rand.Int63()), Variant: NewRandomNoiseMap(rand.Int63()), PlaceX: NewRandomNoiseMap(rand.Int63()), PlaceY: NewRandomNoiseMap(rand.Int63()), Flowers: map[Point]Flower{}, } terrain.AddFlower(Pt(0, 0), NewPoppyTraits()) return &Game{ Money: 100, Terrain: terrain, start: time.Now(), } } func (g *Game) Update() { update := time.Since(g.start) for g.lastUpdate < update { g.tick() g.lastUpdate += time.Millisecond * 10 } } func (g *Game) tick() { randomNeighbor := func(pos Point) Point { switch rand.Intn(4) { case 0: return Pt(pos.X-1, pos.Y) case 1: return Pt(pos.X, pos.Y-1) case 2: return Pt(pos.X+1, pos.Y) case 3: return Pt(pos.X, pos.Y+1) } return pos } flowers := map[Point]Flower{} for pos, flower := range g.Terrain.Flowers { if rand.Float32() < flower.Traits.Spread { dst := randomNeighbor(pos) if _, ok := g.Terrain.Flowers[dst]; !ok { if _, ok := flowers[dst]; !ok { flowers[dst] = g.Terrain.NewFlower(dst, flower.Traits) } } } if rand.Float32() < flower.Traits.Life*flower.Traits.LifeModifier { flowers[pos] = flower } } g.Terrain.Flowers = flowers }