All robots are spectators

This commit is contained in:
Stephen McQuay 2015-08-31 21:48:25 -07:00
parent 855208b39d
commit 3ef90af341
5 changed files with 78 additions and 51 deletions

View File

@ -7,6 +7,7 @@ import (
"time" "time"
"hackerbots.us/client" "hackerbots.us/client"
"hackerbots.us/server"
) )
var serverHostname = flag.String("server", "localhost", "server hostname") var serverHostname = flag.String("server", "localhost", "server hostname")
@ -26,12 +27,15 @@ func main() {
} }
c := &client.Client{ c := &client.Client{
Server: *serverHostname, Server: *serverHostname,
Port: *port, Port: *port,
Name: "bspect", Name: "bspect",
GameId: gameId, GameId: gameId,
Verbose: *verbose, Verbose: *verbose,
ForceJSON: *forceJSON, ForceJSON: *forceJSON,
StateStream: make(chan *server.Boardstate),
Die: make(chan struct{}),
Player: client.Spectator{},
} }
var err error var err error
err = c.Negociate("spectator") err = c.Negociate("spectator")
@ -39,17 +43,10 @@ func main() {
log.Fatalf("%s: failed to negociate: %s", c.Name, err) log.Fatalf("%s: failed to negociate: %s", c.Name, err)
} }
spectator := client.NewSimpleSpectator(
c.Game.BoardSize.Width,
c.Game.BoardSize.Height,
)
c.Player = spectator
go func() { go func() {
if err := c.Play(); err != nil { if err := c.Play(); err != nil {
close(spectator.Die) close(c.Die)
} }
}() }()
c.Visualize()
spectator.Run()
} }

View File

@ -29,13 +29,20 @@ type Client struct {
Server string Server string
StatsReq server.StatsRequest StatsReq server.StatsRequest
Verbose bool Verbose bool
Player Player
Game server.GameParam Game server.GameParam
boardstate *server.Boardstate boardstate *server.Boardstate
enc encoder enc encoder
dec decoder dec decoder
ws *websocket.Conn ws *websocket.Conn
// visualization members
width, height float64
viewX, viewY int
StateStream chan *server.Boardstate
Die chan struct{}
Player
} }
type encoder interface { type encoder interface {
@ -156,6 +163,9 @@ func (c *Client) Negociate(clientType string) (err error) {
case "spectator": case "spectator":
} }
c.width = c.Game.BoardSize.Width
c.height = c.Game.BoardSize.Height
return nil return nil
} }
@ -172,7 +182,8 @@ func (c *Client) Play() error {
if err != nil { if err != nil {
return errors.New(fmt.Sprintf("%s: Connection likely lost: %s", c.Name, err)) return errors.New(fmt.Sprintf("%s: Connection likely lost: %s", c.Name, err))
} }
err = c.enc.Encode(c.Player.Update(bs)) c.StateStream <- bs
err = c.enc.Encode(c.Update(bs))
if err != nil { if err != nil {
return err return err
} }

View File

@ -56,8 +56,12 @@ func main() {
WeaponDamage: *weaponDamage, WeaponDamage: *weaponDamage,
WeaponSpeed: *weaponSpeed, WeaponSpeed: *weaponSpeed,
}, },
Verbose: *verbose, Verbose: *verbose,
ForceJSON: *forceJSON, ForceJSON: *forceJSON,
StateStream: make(chan *server.Boardstate),
Die: make(chan struct{}),
Player: client.NewSimplePlayer(800, 600),
} }
var err error var err error
err = c.Negociate("robot") err = c.Negociate("robot")
@ -65,12 +69,10 @@ func main() {
log.Fatalf("%s: failed to negociate: %s", c.Name, err) log.Fatalf("%s: failed to negociate: %s", c.Name, err)
} }
c.Player = client.NewSimplePlayer( go func() {
c.Game.BoardSize.Width, if err := c.Play(); err != nil {
c.Game.BoardSize.Height, close(c.Die)
) }
}()
if err := c.Play(); err != nil { c.Visualize()
log.Fatal(err)
}
} }

View File

@ -66,7 +66,6 @@ func (p *SimplePlayer) Update(bs *server.Boardstate) map[string]server.Instructi
Probe: &probe_point, Probe: &probe_point,
} }
} }
return instructions return instructions
} }
@ -149,3 +148,9 @@ func (p *SimplePlayer) probe(destination vector.Point2d) bool {
} }
return true return true
} }
type Spectator struct{}
func (s Spectator) Update(bs *server.Boardstate) map[string]server.Instruction {
return nil
}

View File

@ -18,30 +18,13 @@ type size struct {
width, height int width, height int
} }
type SimpleSpectator struct {
width, height float64
viewX, viewY int
update chan *server.Boardstate
Die chan struct{}
}
// NewSimpleSpectator simply returns a populated, usable *SimplePlayer
func NewSimpleSpectator(width, height float64) *SimpleSpectator {
return &SimpleSpectator{
width: width,
height: height,
update: make(chan *server.Boardstate),
Die: make(chan struct{}),
}
}
// Recv is our implementation of receiving a server.Boardstate from the server // Recv is our implementation of receiving a server.Boardstate from the server
func (s *SimpleSpectator) Update(bs *server.Boardstate) map[string]server.Instruction { func (s *Client) Recv(bs *server.Boardstate) map[string]server.Instruction {
s.update <- bs s.StateStream <- bs
return nil return nil
} }
func (s *SimpleSpectator) Run() { func (s *Client) Visualize() {
err := termbox.Init() err := termbox.Init()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -49,7 +32,7 @@ func (s *SimpleSpectator) Run() {
s.viewX, s.viewY = termbox.Size() s.viewX, s.viewY = termbox.Size()
events := make(chan termbox.Event) events := make(chan termbox.Event, 1024)
go func() { go func() {
for { for {
events <- termbox.PollEvent() events <- termbox.PollEvent()
@ -83,7 +66,7 @@ func (s *SimpleSpectator) Run() {
case termbox.EventError: case termbox.EventError:
log.Fatalf("Quitting because of termbox error: \n%s\n", event.Err) log.Fatalf("Quitting because of termbox error: \n%s\n", event.Err)
} }
case u := <-s.update: case u := <-s.StateStream:
termbox.Clear(termbox.ColorBlack, termbox.ColorBlack) termbox.Clear(termbox.ColorBlack, termbox.ColorBlack)
for _, obstacle := range u.Obstacles { for _, obstacle := range u.Obstacles {
@ -103,7 +86,7 @@ func (s *SimpleSpectator) Run() {
} }
} }
for _, bot := range u.OtherRobots { for _, bot := range u.MyRobots {
x := int((bot.Position.X / s.width) * float64(s.viewX)) x := int((bot.Position.X / s.width) * float64(s.viewX))
y := int((bot.Position.Y / s.height) * float64(s.viewY)) y := int((bot.Position.Y / s.height) * float64(s.viewY))
var b rune var b rune
@ -132,6 +115,35 @@ func (s *SimpleSpectator) Run() {
) )
} }
for _, bot := range u.OtherRobots {
x := int((bot.Position.X / s.width) * float64(s.viewX))
y := int((bot.Position.Y / s.height) * float64(s.viewY))
var b rune
if math.Abs(bot.Heading.X) > math.Abs(bot.Heading.Y) {
if bot.Heading.X > 0 {
b = botRight
} else {
b = botLeft
}
} else {
if bot.Heading.Y > 0 {
b = botUp
} else {
b = botDown
}
}
c := termbox.ColorRed
if bot.Health <= 0 {
c = termbox.ColorBlack
}
termbox.SetCell(
x,
s.viewY-y,
b,
c, termbox.ColorBlack,
)
}
for _, p := range u.Projectiles { for _, p := range u.Projectiles {
x := int((p.Position.X / s.width) * float64(s.viewX)) x := int((p.Position.X / s.width) * float64(s.viewX))
y := int((p.Position.Y / s.height) * float64(s.viewY)) y := int((p.Position.Y / s.height) * float64(s.viewY))