init
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"wh/config"
|
||||
"wh/fixed"
|
||||
"wh/rng"
|
||||
)
|
||||
|
||||
// Ore identifies a raw material.
|
||||
type Ore int
|
||||
|
||||
const (
|
||||
Iron Ore = iota
|
||||
Nickel
|
||||
Ice
|
||||
Platinum
|
||||
NumOre
|
||||
)
|
||||
|
||||
func (o Ore) String() string {
|
||||
return [...]string{"iron", "nickel", "ice", "platinum"}[o]
|
||||
}
|
||||
|
||||
type Asteroid struct {
|
||||
ID int64
|
||||
Orbit Orbit
|
||||
Ore [NumOre]int64 // remaining kilograms of each ore
|
||||
}
|
||||
|
||||
func (a *Asteroid) TotalOre() int64 {
|
||||
var t int64
|
||||
for _, v := range a.Ore {
|
||||
t += v
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// Station is the dropoff point, on a circular orbit in the ecliptic plane.
|
||||
type Station struct {
|
||||
Orbit Orbit
|
||||
}
|
||||
|
||||
// Stream labels keep independent generation phases from sharing randomness.
|
||||
const (
|
||||
labelBelt = iota + 1
|
||||
labelStation
|
||||
)
|
||||
|
||||
// Generate builds the asteroid field and station from the config seed.
|
||||
func Generate(cfg config.Config) ([]Asteroid, Station) {
|
||||
r := rng.Derive(cfg.Seed, labelBelt)
|
||||
asts := make([]Asteroid, cfg.AsteroidCount)
|
||||
for i := range asts {
|
||||
a := r.FixedRange(cfg.BeltInner, cfg.BeltOuter)
|
||||
asts[i] = Asteroid{
|
||||
ID: int64(i + 1),
|
||||
Orbit: Orbit{
|
||||
A: a,
|
||||
Period: PeriodFor(a, cfg.OrbitSpeed),
|
||||
M0: r.FixedRange(0, fixed.TwoPi),
|
||||
Node: r.FixedRange(0, fixed.TwoPi),
|
||||
// Bias inclination low (squared uniform).
|
||||
Inc: r.Fixed().Mul(r.Fixed()).Mul(cfg.MaxInclination),
|
||||
},
|
||||
}
|
||||
// Each asteroid has a total mass and a random mix of ores.
|
||||
total := int64(50_000) + int64(r.Intn(950_000))
|
||||
var weights [NumOre]uint64
|
||||
var wsum uint64
|
||||
for o := range weights {
|
||||
weights[o] = r.Intn(100) + 1
|
||||
wsum += weights[o]
|
||||
}
|
||||
// Platinum is rare: only a fifth of asteroids carry much of it.
|
||||
if r.Intn(5) != 0 {
|
||||
wsum -= weights[Platinum]
|
||||
weights[Platinum] = 0
|
||||
}
|
||||
for o := range weights {
|
||||
asts[i].Ore[o] = total * int64(weights[o]) / int64(wsum)
|
||||
}
|
||||
}
|
||||
sr := rng.Derive(cfg.Seed, labelStation)
|
||||
a := (cfg.BeltInner + cfg.BeltOuter).DivInt(2)
|
||||
st := Station{Orbit: Orbit{
|
||||
A: a,
|
||||
Period: PeriodFor(a, cfg.OrbitSpeed),
|
||||
M0: sr.FixedRange(0, fixed.TwoPi),
|
||||
}}
|
||||
return asts, st
|
||||
}
|
||||
Reference in New Issue
Block a user