scan and broadcast both work without global index

master
Jordan Orelli 5 years ago
parent dbb2c86f5a
commit ce94d3cdd2

@ -33,10 +33,10 @@ func (b *Bomb) Dead() bool {
return b.done
}
func (b *Bomb) Tick(frame int64) {
func (b *Bomb) Tick(game *Game) {
b.fti -= 1
if b.fti <= 0 {
b.target.Bombed(b.profile, frame)
b.target.Bombed(b.profile, game.frame)
b.done = true
log_info("bomb went off on %v", b.target)
}

@ -9,8 +9,8 @@ type broadcast struct {
start time.Time
origin *System
dist float64
nextHitIndex int
message string
neighborhood Neighborhood
}
func NewBroadcast(from *System, template string, args ...interface{}) *broadcast {
@ -21,20 +21,27 @@ func NewBroadcast(from *System, template string, args ...interface{}) *broadcast
}
}
func (b *broadcast) Tick(frame int64) {
func (b *broadcast) Tick(game *Game) {
if b.neighborhood == nil {
log_info("setting up neighborhood for broadcast: %s", b.message)
b.neighborhood = game.galaxy.Neighborhood(b.origin)
log_info("nearest neighbor: %v", b.neighborhood[0])
}
b.dist += options.lightSpeed
for ; b.nextHitIndex < len(b.origin.Distances()); b.nextHitIndex += 1 {
candidate := b.origin.Distances()[b.nextHitIndex]
if b.dist < candidate.dist {
break
for len(b.neighborhood) > 0 && b.neighborhood[0].distance <= b.dist {
s := game.galaxy.GetSystemByID(b.neighborhood[0].id)
log_info("broadcast %s has reached %s from %s", b.message, s, b.origin)
s.NotifyInhabitants("message received from system %v:\n\t%s\n", b.origin, b.message)
if len(b.neighborhood) > 1 {
b.neighborhood = b.neighborhood[1:]
} else {
b.neighborhood = nil
}
candidate.s.NotifyInhabitants("message received from system %v:\n\t%s\n", b.origin, b.message)
}
}
func (b *broadcast) Dead() bool {
return b.dist > b.origin.Distances()[len(b.origin.Distances())-1].dist
}
func (b *broadcast) Dead() bool { return b.neighborhood == nil }
func (b *broadcast) String() string {
return fmt.Sprintf("[broadcast origin: %v message: %s]", b.origin, b.message)

@ -212,15 +212,15 @@ func BroadcastCommand(sys *System) Command {
func NearbyCommand(sys *System) Command {
handler := func(c *Connection, args ...string) {
neighbors := c.game.galaxy.Neighborhood(sys)
c.Printf("--------------------------------------------------------------------------------\n")
c.Line()
c.Printf("%-4s %-20s %-12s %s\n", "id", "name", "distance", "trip time")
c.Printf("--------------------------------------------------------------------------------\n")
c.Line()
for _, neighbor := range neighbors[:25] {
other := index[neighbor.id]
other := c.game.galaxy.GetSystemByID(neighbor.id)
dur := NewTravel(c, sys, other).(*TravelState).tripTime()
c.Printf("%-4d %-20s %-12.6v %v\n", other.id, other.name, neighbor.distance, dur)
c.Printf("%-4d %-20s %-12.6vpc %v\n", other.id, other.name, neighbor.distance, dur)
}
c.Printf("--------------------------------------------------------------------------------\n")
c.Line()
}
return Command{
name: "nearby",

@ -40,14 +40,14 @@ func (c *Connection) Dead() bool {
return false
}
func (c *Connection) Tick(frame int64) {
func (c *Connection) Tick(game *Game) {
if c.ConnectionState == nil {
log_error("connected client has nil state.")
c.Printf("somehow you have a nil state. I don't know what to do so I'm going to kick you off.")
c.Close()
return
}
c.SetState(c.ConnectionState.Tick(c, frame))
c.SetState(c.ConnectionState.Tick(c, game.frame))
}
func (c *Connection) RunCommand(name string, args ...string) {
@ -221,11 +221,3 @@ func (c *Connection) Win(method string) {
func (c *Connection) Die(frame int64) {
c.SetState(NewDeadState(frame))
}
func SpawnRandomly() ConnectionState {
sys, err := randomSystem()
if err != nil {
return NewErrorState(fmt.Errorf("unable to create idle state: %v", err))
}
return Idle(sys)
}

@ -17,7 +17,7 @@ func (d *DeadState) Enter(c *Connection) {
func (d *DeadState) Tick(c *Connection, frame int64) ConnectionState {
if frame-d.start > options.respawnFrames {
return SpawnRandomly()
return c.game.SpawnPlayer()
}
return d
}

@ -70,8 +70,16 @@ func (g *Galaxy) SystemID(name string) int { return g.names[name] }
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)
}

@ -136,7 +136,7 @@ func (g *Game) Register(elem GameElement) {
func (g *Game) tick() {
g.frame += 1
for elem := range g.elems {
elem.Tick(g.frame)
elem.Tick(g)
}
for elem := range g.elems {
if elem.Dead() {
@ -146,7 +146,11 @@ func (g *Game) tick() {
}
}
func (g *Game) SpawnPlayer() ConnectionState {
return Idle(g.galaxy.randomSystem())
}
type GameElement interface {
Tick(frame int64)
Tick(*Game)
Dead() bool
}

@ -104,7 +104,7 @@ func (i *IdleState) scan(c *Connection, args ...string) {
return
}
c.Printf("Scanning the galaxy for signs of life...\n")
c.game.Register(NewScan(i.System))
c.game.Register(NewScan(i.System, c.game.galaxy.Neighborhood(i.System)))
}
// "make" is already a keyword

@ -114,7 +114,7 @@ var newGameCommand = Command{
c.Printf("Now playing in game: %s\n\n", game.id)
c.Line()
c.game.Join(c)
c.SetState(SpawnRandomly())
c.SetState(game.SpawnPlayer())
},
debug: false,
}
@ -135,9 +135,10 @@ Usage: join [game-code]`, " \n\t"))
return
}
id := args[0]
c.game = gm.Get(id)
game := gm.Get(id)
c.game = game
log_info("%s Joining game: %s", c.profile.name, c.game.id)
c.SetState(SpawnRandomly())
c.SetState(game.SpawnPlayer())
c.game.Join(c)
},
debug: false,

@ -18,7 +18,7 @@ var options struct {
frameLength time.Duration
colonyCost int
frameRate int
lightSpeed float64
lightSpeed float64 // the distance that light travels in one tick
makeBombTime time.Duration
makeColonyTime time.Duration
makeShieldTime time.Duration

@ -12,6 +12,7 @@ type scan struct {
nextHitIndex int
nextEchoIndex int
results []scanResult
neighborhood Neighborhood
}
type scanResult struct {
@ -38,17 +39,18 @@ func (r *scanResult) playerNames() []string {
return names
}
func NewScan(origin *System) *scan {
func NewScan(origin *System, n Neighborhood) *scan {
return &scan{
origin: origin,
start: time.Now(),
results: make([]scanResult, 0, len(origin.Distances())),
origin: origin,
start: time.Now(),
results: make([]scanResult, 0, len(origin.Distances())),
neighborhood: n,
}
}
func (s *scan) Tick(frame int64) {
func (s *scan) Tick(game *Game) {
s.dist += options.lightSpeed
s.hits()
s.hits(game)
s.echos()
}
@ -60,14 +62,17 @@ func (s *scan) String() string {
return fmt.Sprintf("[scan origin: %s start_time: %v]", s.origin.name, s.start)
}
func (s *scan) hits() {
for ; s.nextHitIndex < len(s.origin.Distances()); s.nextHitIndex += 1 {
candidate := s.origin.Distances()[s.nextHitIndex]
if s.dist < candidate.dist {
break
func (s *scan) hits(game *Game) {
for len(s.neighborhood) > 0 && s.neighborhood[0].distance <= s.dist {
sys := game.galaxy.GetSystemByID(s.neighborhood[0].id)
s.results = append(s.results, s.hitSystem(sys, s.neighborhood[0].distance))
log_info("scan hit %v. Traveled %v in %v", sys.name, s.neighborhood[0].distance, time.Since(s.start))
if len(s.neighborhood) > 1 {
s.neighborhood = s.neighborhood[1:]
} else {
s.neighborhood = nil
}
s.results = append(s.results, s.hitSystem(candidate.s, candidate.dist))
log_info("scan hit %v. Traveled %v in %v", candidate.s.name, candidate.dist, time.Since(s.start))
}
}

@ -54,7 +54,7 @@ type Shield struct {
energy float64
}
func (s *Shield) Tick(frame int64) {
func (s *Shield) Tick() {
if s.energy < 1000 {
s.energy += (1000 - s.energy) * 0.0005
}

@ -25,13 +25,13 @@ type System struct {
money int64
}
func (s *System) Tick(frame int64) {
func (s *System) Tick(game *Game) {
if s.colonizedBy != nil && s.money > 0 {
s.colonizedBy.Deposit(1)
s.money -= 1
}
if s.Shield != nil {
s.Shield.Tick(frame)
s.Shield.Tick()
}
}
@ -45,7 +45,6 @@ func (s *System) Reset() {
}
func (s *System) Arrive(conn *Connection) {
// conn.SetSystem(s)
if s.players[conn] {
return
}
@ -125,11 +124,11 @@ func (s *System) Distances() []Ray {
if s.distances == nil {
s.distances = make([]Ray, 0, 551)
rows, err := db.Query(`
select edges.id_2, edges.distance
from edges
where edges.id_1 = ?
order by distance
;`, s.id)
select edges.id_2, edges.distance
from edges
where edges.id_1 = ?
order by distance
;`, s.id)
if err != nil {
log_error("unable to query for system distances: %v", err)
return nil
@ -247,13 +246,3 @@ func indexSystems() map[int]*System {
}
return index
}
func randomSystem() (*System, error) {
n := len(index)
if n == 0 {
return nil, fmt.Errorf("no planets are known to exist")
}
pick := rand.Intn(n)
sys := index[pick]
return sys, nil
}

Loading…
Cancel
Save