added new scan implementation

slack
Jordan Orelli 10 years ago
parent de28dc142d
commit 444896f364

@ -120,6 +120,9 @@ var scanCommand = &Command{
fmt.Fprintf(conn, "scanners are still recharging. Can scan again in %v\n", conn.NextScan()) fmt.Fprintf(conn, "scanners are still recharging. Can scan again in %v\n", conn.NextScan())
return return
} }
s := &scan{start: time.Now(), origin: conn.System()}
currentGame.Register(s)
conn.RecordScan() conn.RecordScan()
system := conn.System() system := conn.System()
log_info("scan sent from %s", system.name) log_info("scan sent from %s", system.name)

@ -12,6 +12,8 @@ type Game struct {
winner string winner string
winMethod string winMethod string
connections map[*Connection]bool connections map[*Connection]bool
frame int64
elems map[GameElement]bool
} }
func gamesTable() { func gamesTable() {
@ -32,6 +34,7 @@ func NewGame() *Game {
id: NewId(), id: NewId(),
start: time.Now(), start: time.Now(),
connections: make(map[*Connection]bool, 32), connections: make(map[*Connection]bool, 32),
elems: make(map[GameElement]bool, 32),
} }
if err := game.Create(); err != nil { if err := game.Create(); err != nil {
log_error("unable to create game: %v", err) log_error("unable to create game: %v", err)
@ -96,3 +99,40 @@ func (g *Game) Reset() {
*g = *fresh *g = *fresh
g.connections = connections g.connections = connections
} }
func (g *Game) Run() {
ticker := time.Tick(time.Second / time.Duration(frameRate))
for {
select {
case <-ticker:
g.tick()
}
}
}
func (g *Game) Register(elem GameElement) {
g.elems[elem] = true
}
func (g *Game) tick() {
g.frame += 1
for elem := range g.elems {
if elem.Dead() {
delete(g.elems, elem)
}
}
for elem := range g.elems {
elem.Tick(g.frame)
}
}
type GameElement interface {
Tick(frame int64)
Dead() Mortality
}
type Mortality bool
func (m Mortality) Dead() Mortality {
return m
}

@ -16,6 +16,8 @@ var (
info_log *log.Logger info_log *log.Logger
error_log *log.Logger error_log *log.Logger
currentGame *Game currentGame *Game
frameRate = 100 // frames/second
lightSpeed = 0.01 // parsecs/frame
) )
func log_error(template string, args ...interface{}) { func log_error(template string, args ...interface{}) {
@ -90,6 +92,7 @@ func main() {
go RunQueue() go RunQueue()
currentGame = NewGame() currentGame = NewGame()
go currentGame.Run()
for { for {
conn, err := listener.Accept() conn, err := listener.Accept()

@ -0,0 +1,30 @@
package main
import (
"time"
)
type scan struct {
Mortality
start time.Time
origin *System
dist float64
nextHitIndex int
}
func (s *scan) Tick(frame int64) {
s.dist += lightSpeed
for {
candidate := s.origin.Distances()[s.nextHitIndex]
if s.dist < candidate.dist {
break
}
log_info("scan hit %v. Traveled %v in %v", candidate.s.name, candidate.dist, time.Since(s.start))
s.nextHitIndex += 1
if s.nextHitIndex >= len(s.origin.Distances()) {
s.Mortality = true
log_info("scan complete")
break
}
}
}

@ -22,6 +22,7 @@ type System struct {
players map[*Connection]bool players map[*Connection]bool
miningRate float64 miningRate float64
colonizedBy *Connection colonizedBy *Connection
distances []Ray
} }
func (s *System) Arrive(conn *Connection) { func (s *System) Arrive(conn *Connection) {
@ -87,6 +88,42 @@ func (s *System) TravelTimeTo(other *System) time.Duration {
return time.Duration(int64(s.DistanceTo(other) * 125000000)) return time.Duration(int64(s.DistanceTo(other) * 125000000))
} }
type Ray struct {
s *System
dist float64 // distance in parsecs
}
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)
if err != nil {
log_error("unable to query for system distances: %v", err)
return nil
}
for rows.Next() {
var (
r Ray
id int
dist float64
)
if err := rows.Scan(&id, &dist); err != nil {
log_error("unable to unpack Ray from sql result: %v", err)
continue
}
r.s = index[id]
r.dist = dist
s.distances = append(s.distances, r)
}
}
return s.distances
}
func (s *System) Bombed(bomber *Connection) { func (s *System) Bombed(bomber *Connection) {
s.EachConn(func(conn *Connection) { s.EachConn(func(conn *Connection) {
conn.Die() conn.Die()
@ -230,7 +267,7 @@ func scanSystem(id int, reply int) {
system := index[id] system := index[id]
source := index[reply] source := index[reply]
delay := system.LightTimeTo(source) delay := system.LightTimeTo(source)
log_info("scan hit %s from %s after traveling for %v", system.name, source.name, delay) // log_info("scan hit %s from %s after traveling for %v", system.name, source.name, delay)
system.EachConn(func(conn *Connection) { system.EachConn(func(conn *Connection) {
fmt.Fprintf(conn, "scan detected from %s\n", source.name) fmt.Fprintf(conn, "scan detected from %s\n", source.name)
@ -248,7 +285,7 @@ func deliverReply(id int, echo int, results *scanResults) {
system := index[id] system := index[id]
source := index[echo] source := index[echo]
delay := system.LightTimeTo(source) delay := system.LightTimeTo(source)
log_info("echo received at %s reflected from %s after traveling for %v", system.name, source.name, delay) // log_info("echo received at %s reflected from %s after traveling for %v", system.name, source.name, delay)
system.EachConn(func(conn *Connection) { system.EachConn(func(conn *Connection) {
if results.negative() { if results.negative() {
return return

Loading…
Cancel
Save