moved a bunch of logic out of run and into functions of the game, for a cleaner separation of functionality.

Also, removed a bunch of overly verbose logging
This commit is contained in:
Fraser Graham 2013-10-20 21:15:23 -07:00
parent 776a7eee98
commit 200afffa7f
6 changed files with 84 additions and 87 deletions

143
game.go
View File

@ -104,6 +104,75 @@ func NewGame(id string, width, height float32) *game {
return g return g
} }
func (g *game) tick(payload *Boardstate) int {
robots_remaining := 0
// Update Players
for p := range g.players {
if p.Robot.Health > 0 {
robots_remaining++
p.Tick(g)
}
payload.Robots = append(payload.Robots, p.Robot)
}
// Update Projectiles
for pr := range g.projectiles {
pr.Tick(g)
}
// We do this here, because the tick calls can alter g.projectiles
for pr := range g.projectiles {
payload.Projectiles = append(payload.Projectiles, *pr)
}
// Update Splosions
for s := range g.splosions {
s.Tick()
if !s.Alive() {
delete(g.splosions, s)
}
payload.Splosions = append(payload.Splosions, *s)
}
return robots_remaining
}
func (g *game) send_update(payload *Boardstate) {
// Ensure that the robots are always sent in a consistent order
sort.Sort(RobotSorter{Robots: payload.Robots})
for p := range g.players {
// Copy the payload but only add the robots in scanner range
player_payload := NewBoardstate()
player_payload.Projectiles = payload.Projectiles
player_payload.Splosions = payload.Splosions
player_payload.Turn = payload.Turn
player_payload.Reset = payload.Reset
player_payload.Robots = append(player_payload.Robots, p.Robot)
if p.Robot.Health > 0 {
for player := range g.players {
for _, scan_entry := range p.Robot.Scanners {
if player.Robot.Id == scan_entry.Id {
player_payload.Robots = append(player_payload.Robots, player.Robot)
}
}
}
} else {
player_payload.Robots = payload.Robots
}
// x, _ := json.Marshal(player_payload)
// log.Printf("%v", string(x))
p.send <- player_payload
}
for s := range g.spectators {
s.send <- payload
}
}
func (g *game) run() { func (g *game) run() {
var t0, t1 time.Time var t0, t1 time.Time
ticker := time.NewTicker(time.Duration(*tick) * time.Millisecond) ticker := time.NewTicker(time.Duration(*tick) * time.Millisecond)
@ -129,13 +198,11 @@ func (g *game) run() {
delete(g.spectators, s) delete(g.spectators, s)
close(s.send) close(s.send)
case <-ticker.C: case <-ticker.C:
t0 = time.Now()
payload := NewBoardstate() payload := NewBoardstate()
g.turn++ g.turn++
payload.Turn = g.turn payload.Turn = g.turn
t0 = time.Now()
if *verbose { if *verbose {
log.Printf("\033[2JTurn: %v", g.turn) log.Printf("\033[2JTurn: %v", g.turn)
log.Printf("Players: %v", len(g.players)) log.Printf("Players: %v", len(g.players))
@ -143,39 +210,10 @@ func (g *game) run() {
log.Printf("Explosions: %v", len(g.splosions)) log.Printf("Explosions: %v", len(g.splosions))
} }
robots_remaining := 0
// UPDATE GAME STATE // UPDATE GAME STATE
for p := range g.players { robots_remaining := g.tick(payload)
if p.Robot.Health > 0 {
robots_remaining++
// TODO: measure if this would be better to go and wait ...
p.scan(g.players)
p.nudge(g)
if p.Robot.FireAt != nil {
proj := p.fire(g.projectiles, g.turn)
if proj != nil {
g.projectiles[proj] = true
}
}
}
payload.Robots = append(payload.Robots, p.Robot)
}
sort.Sort(RobotSorter{Robots: payload.Robots})
g.nudgeProjectiles()
for p := range g.projectiles {
payload.Projectiles = append(payload.Projectiles, *p)
}
for s := range g.splosions {
s.Tick()
if !s.Alive() {
delete(g.splosions, s)
}
payload.Splosions = append(payload.Splosions, *s)
}
// Determine end game?
if robots_remaining <= 1 && len(g.players) > 1 { if robots_remaining <= 1 && len(g.players) > 1 {
for p := range g.players { for p := range g.players {
if p.Robot.Health > 0 { if p.Robot.Health > 0 {
@ -195,34 +233,7 @@ func (g *game) run() {
} }
// SEND THE UPDATE TO EACH PLAYER // SEND THE UPDATE TO EACH PLAYER
for p := range g.players { g.send_update(payload)
// Copy the payload but only add the robots in scanner range
player_payload := NewBoardstate()
player_payload.Projectiles = payload.Projectiles
player_payload.Splosions = payload.Splosions
player_payload.Turn = payload.Turn
player_payload.Reset = payload.Reset
player_payload.Robots = append(player_payload.Robots, p.Robot)
if p.Robot.Health > 0 {
for player := range g.players {
for _, scan_entry := range p.Robot.Scanners {
if player.Robot.Id == scan_entry.Id {
player_payload.Robots = append(player_payload.Robots, player.Robot)
}
}
}
} else {
player_payload.Robots = payload.Robots
}
// x, _ := json.Marshal(player_payload)
// log.Printf("%v", string(x))
p.send <- player_payload
}
for s := range g.spectators {
s.send <- payload
}
t1 = time.Now() t1 = time.Now()
if *verbose { if *verbose {
@ -231,11 +242,3 @@ func (g *game) run() {
} }
} }
} }
func (g *game) nudgeProjectiles() (rprojectiles []Projectile) {
rprojectiles = make([]Projectile, 0)
for p := range g.projectiles {
p.Tick(g)
}
return
}

12
geom.go
View File

@ -1,12 +0,0 @@
package main
import (
"bitbucket.org/hackerbots/vector"
)
func move(d1, d2 govector.Point2d, velocity float32, timeDelta float32) govector.Point2d {
v := d2.Sub(d1)
v_norm := v.Normalize()
v_scaled := v_norm.Scale(velocity * timeDelta)
return d1.Add(v_scaled)
}

View File

@ -27,6 +27,8 @@ var idg *IdGenerator
var games MapLock var games MapLock
func main() { func main() {
log.Printf("Starting Server...")
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
flag.Parse() flag.Parse()
if *profile != "" { if *profile != "" {

View File

@ -78,7 +78,8 @@ func (p *player) checkCollisions(g *game, move_vector v.Vector2d) (bool, v.Point
return collision, intersection_point return collision, intersection_point
} }
func (p *player) nudge(g *game) { func (p *player) Tick(g *game) {
p.scan(g.players)
// Adjust Speed // Adjust Speed
if p.Robot.Speed < p.Robot.TargetSpeed { if p.Robot.Speed < p.Robot.TargetSpeed {
@ -94,7 +95,6 @@ func (p *player) nudge(g *game) {
if current_heading.Mag() == 0 { if current_heading.Mag() == 0 {
// We may have been stopped before this and had no heading // We may have been stopped before this and had no heading
current_heading = p.Robot.MoveTo.Sub(p.Robot.Position).Normalize() current_heading = p.Robot.MoveTo.Sub(p.Robot.Position).Normalize()
log.Printf("Heading WAS zero, is now %v", current_heading)
} }
// Where do we WANT to be heading? // Where do we WANT to be heading?
@ -137,6 +137,12 @@ func (p *player) nudge(g *game) {
} }
} }
if p.Robot.FireAt != nil {
proj := p.fire(g.projectiles, g.turn)
if proj != nil {
g.projectiles[proj] = true
}
}
} }
func (p *player) scan(players map[*player]bool) { func (p *player) scan(players map[*player]bool) {

View File

@ -97,13 +97,12 @@ func (s StatsRequest) Valid() bool {
s.ScannerRadius + s.Acceleration + s.TurnSpeed + s.FireRate) s.ScannerRadius + s.Acceleration + s.TurnSpeed + s.FireRate)
// allowing for 50 pts in every category // allowing for 50 pts in every category
if total > 350 { if total > 400 {
return false return false
} }
return true return true
} }
type Instruction struct { type Instruction struct {
MoveTo *v.Point2d `json:"move_to,omitempty"` MoveTo *v.Point2d `json:"move_to,omitempty"`
FireAt *v.Point2d `json:"fire_at,omitempty"` FireAt *v.Point2d `json:"fire_at,omitempty"`

View File

@ -13,7 +13,6 @@ type Spectator struct {
func (s *Spectator) sender() { func (s *Spectator) sender() {
for things := range s.send { for things := range s.send {
err := websocket.JSON.Send(s.ws, *things) err := websocket.JSON.Send(s.ws, *things)
log.Printf("%v", things)
if err != nil { if err != nil {
break break
} }