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:
parent
776a7eee98
commit
200afffa7f
157
game.go
157
game.go
@ -104,70 +104,29 @@ func NewGame(id string, width, height float32) *game {
|
|||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *game) run() {
|
func (g *game) tick(payload *Boardstate) int {
|
||||||
var t0, t1 time.Time
|
|
||||||
ticker := time.NewTicker(time.Duration(*tick) * time.Millisecond)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-g.kill:
|
|
||||||
log.Printf("game %s: received kill signal, dying gracefully", g.id)
|
|
||||||
games.Lock()
|
|
||||||
for player := range g.players {
|
|
||||||
close(player.send)
|
|
||||||
}
|
|
||||||
delete(games.m, g.id)
|
|
||||||
games.Unlock()
|
|
||||||
return
|
|
||||||
case p := <-g.register:
|
|
||||||
g.players[p] = true
|
|
||||||
case p := <-g.unregister:
|
|
||||||
delete(g.players, p)
|
|
||||||
close(p.send)
|
|
||||||
case s := <-g.sregister:
|
|
||||||
g.spectators[s] = true
|
|
||||||
case s := <-g.sunregister:
|
|
||||||
delete(g.spectators, s)
|
|
||||||
close(s.send)
|
|
||||||
case <-ticker.C:
|
|
||||||
payload := NewBoardstate()
|
|
||||||
|
|
||||||
g.turn++
|
|
||||||
payload.Turn = g.turn
|
|
||||||
|
|
||||||
t0 = time.Now()
|
|
||||||
|
|
||||||
if *verbose {
|
|
||||||
log.Printf("\033[2JTurn: %v", g.turn)
|
|
||||||
log.Printf("Players: %v", len(g.players))
|
|
||||||
log.Printf("Projectiles: %v", len(g.projectiles))
|
|
||||||
log.Printf("Explosions: %v", len(g.splosions))
|
|
||||||
}
|
|
||||||
|
|
||||||
robots_remaining := 0
|
robots_remaining := 0
|
||||||
|
|
||||||
// UPDATE GAME STATE
|
// Update Players
|
||||||
for p := range g.players {
|
for p := range g.players {
|
||||||
if p.Robot.Health > 0 {
|
if p.Robot.Health > 0 {
|
||||||
robots_remaining++
|
robots_remaining++
|
||||||
// TODO: measure if this would be better to go and wait ...
|
p.Tick(g)
|
||||||
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)
|
payload.Robots = append(payload.Robots, p.Robot)
|
||||||
}
|
}
|
||||||
sort.Sort(RobotSorter{Robots: payload.Robots})
|
|
||||||
|
|
||||||
g.nudgeProjectiles()
|
// Update Projectiles
|
||||||
for p := range g.projectiles {
|
for pr := range g.projectiles {
|
||||||
payload.Projectiles = append(payload.Projectiles, *p)
|
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 {
|
for s := range g.splosions {
|
||||||
s.Tick()
|
s.Tick()
|
||||||
if !s.Alive() {
|
if !s.Alive() {
|
||||||
@ -176,25 +135,13 @@ func (g *game) run() {
|
|||||||
payload.Splosions = append(payload.Splosions, *s)
|
payload.Splosions = append(payload.Splosions, *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if robots_remaining <= 1 && len(g.players) > 1 {
|
return robots_remaining
|
||||||
for p := range g.players {
|
|
||||||
if p.Robot.Health > 0 {
|
|
||||||
log.Printf("Robot %v Wins", p.Robot.Id)
|
|
||||||
log.Printf("game %s: game over", g.id)
|
|
||||||
}
|
|
||||||
p.reset()
|
|
||||||
}
|
|
||||||
payload.Reset = true
|
|
||||||
} else {
|
|
||||||
payload.Reset = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t1 = time.Now()
|
func (g *game) send_update(payload *Boardstate) {
|
||||||
if *verbose {
|
// Ensure that the robots are always sent in a consistent order
|
||||||
log.Printf("Turn Processes %v\n", t1.Sub(t0))
|
sort.Sort(RobotSorter{Robots: payload.Robots})
|
||||||
}
|
|
||||||
|
|
||||||
// SEND THE UPDATE TO EACH PLAYER
|
|
||||||
for p := range g.players {
|
for p := range g.players {
|
||||||
// Copy the payload but only add the robots in scanner range
|
// Copy the payload but only add the robots in scanner range
|
||||||
player_payload := NewBoardstate()
|
player_payload := NewBoardstate()
|
||||||
@ -224,6 +171,70 @@ func (g *game) run() {
|
|||||||
s.send <- payload
|
s.send <- payload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *game) run() {
|
||||||
|
var t0, t1 time.Time
|
||||||
|
ticker := time.NewTicker(time.Duration(*tick) * time.Millisecond)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-g.kill:
|
||||||
|
log.Printf("game %s: received kill signal, dying gracefully", g.id)
|
||||||
|
games.Lock()
|
||||||
|
for player := range g.players {
|
||||||
|
close(player.send)
|
||||||
|
}
|
||||||
|
delete(games.m, g.id)
|
||||||
|
games.Unlock()
|
||||||
|
return
|
||||||
|
case p := <-g.register:
|
||||||
|
g.players[p] = true
|
||||||
|
case p := <-g.unregister:
|
||||||
|
delete(g.players, p)
|
||||||
|
close(p.send)
|
||||||
|
case s := <-g.sregister:
|
||||||
|
g.spectators[s] = true
|
||||||
|
case s := <-g.sunregister:
|
||||||
|
delete(g.spectators, s)
|
||||||
|
close(s.send)
|
||||||
|
case <-ticker.C:
|
||||||
|
t0 = time.Now()
|
||||||
|
payload := NewBoardstate()
|
||||||
|
|
||||||
|
g.turn++
|
||||||
|
payload.Turn = g.turn
|
||||||
|
if *verbose {
|
||||||
|
log.Printf("\033[2JTurn: %v", g.turn)
|
||||||
|
log.Printf("Players: %v", len(g.players))
|
||||||
|
log.Printf("Projectiles: %v", len(g.projectiles))
|
||||||
|
log.Printf("Explosions: %v", len(g.splosions))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE GAME STATE
|
||||||
|
robots_remaining := g.tick(payload)
|
||||||
|
|
||||||
|
// Determine end game?
|
||||||
|
if robots_remaining <= 1 && len(g.players) > 1 {
|
||||||
|
for p := range g.players {
|
||||||
|
if p.Robot.Health > 0 {
|
||||||
|
log.Printf("Robot %v Wins", p.Robot.Id)
|
||||||
|
log.Printf("game %s: game over", g.id)
|
||||||
|
}
|
||||||
|
p.reset()
|
||||||
|
}
|
||||||
|
payload.Reset = true
|
||||||
|
} else {
|
||||||
|
payload.Reset = false
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 = time.Now()
|
||||||
|
if *verbose {
|
||||||
|
log.Printf("Turn Processes %v\n", t1.Sub(t0))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEND THE UPDATE TO EACH PLAYER
|
||||||
|
g.send_update(payload)
|
||||||
|
|
||||||
t1 = time.Now()
|
t1 = time.Now()
|
||||||
if *verbose {
|
if *verbose {
|
||||||
log.Printf("Sent Payload %v\n", t1.Sub(t0))
|
log.Printf("Sent Payload %v\n", t1.Sub(t0))
|
||||||
@ -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
12
geom.go
@ -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)
|
|
||||||
}
|
|
2
main.go
2
main.go
@ -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 != "" {
|
||||||
|
10
player.go
10
player.go
@ -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) {
|
||||||
|
3
robot.go
3
robot.go
@ -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"`
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user