|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/rand"
|
|
|
|
"sort"
|
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Galaxy is a collection of systems
|
|
|
|
type Galaxy struct {
|
|
|
|
systems map[int]*System
|
|
|
|
names map[string]int
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewGalaxy() *Galaxy {
|
|
|
|
g := &Galaxy{
|
|
|
|
systems: make(map[int]*System),
|
|
|
|
names: make(map[string]int),
|
|
|
|
}
|
|
|
|
g.indexSystems()
|
|
|
|
return g
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Galaxy) indexSystems() {
|
|
|
|
rows, err := db.Query(`select * from planets`)
|
|
|
|
if err != nil {
|
|
|
|
log_error("unable to select all planets: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
s := System{}
|
|
|
|
if err := rows.Scan(&s.id, &s.name, &s.x, &s.y, &s.z, &s.planets); err != nil {
|
|
|
|
log_info("unable to scan planet row: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
g.systems[s.id] = &s
|
|
|
|
g.names[s.name] = s.id
|
|
|
|
s.money = int64(rand.NormFloat64()*options.moneySigma + options.moneyMean)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetSystem gets a system by either ID or name. If the provided string
|
|
|
|
// contains an integer, we assume the lookup is intended to be by ID.
|
|
|
|
func (g *Galaxy) GetSystem(s string) *System {
|
|
|
|
id, err := strconv.Atoi(s)
|
|
|
|
if err == nil {
|
|
|
|
return g.GetSystemByID(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
return g.GetSystemByName(s)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Galaxy) GetSystemByID(id int) *System {
|
|
|
|
return g.systems[id]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Galaxy) GetSystemByName(name string) *System {
|
|
|
|
id := g.SystemID(name)
|
|
|
|
if id == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return g.GetSystemByID(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Galaxy) SystemID(name string) int { return g.names[name] }
|
|
|
|
|
|
|
|
// Neighborhood generates the neighborhood for a given system.
|
|
|
|
func (g *Galaxy) Neighborhood(sys *System) Neighborhood {
|
|
|
|
neighbors := make(Neighborhood, 0, len(g.systems))
|
|
|
|
for id, sys2 := range g.systems {
|
|
|
|
if id == sys.id {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
neighbors = append(neighbors, Neighbor{id: id, distance: sys.DistanceTo(sys2)})
|
|
|
|
}
|
|
|
|
sort.Sort(neighbors)
|
|
|
|
return neighbors
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Galaxy) randomSystem() *System {
|
|
|
|
id := rand.Intn(len(g.systems))
|
|
|
|
return g.GetSystemByID(id)
|
|
|
|
}
|