From 3ef90af3410fbe8a3869bf9d0878b94ffd5cba4c Mon Sep 17 00:00:00 2001 From: stephen mcquay Date: Mon, 31 Aug 2015 21:48:25 -0700 Subject: [PATCH] All robots are spectators --- botspectate/main.go | 27 ++++++++++----------- client.go | 15 ++++++++++-- gobot/main.go | 22 +++++++++-------- player.go | 7 +++++- spectator.go | 58 +++++++++++++++++++++++++++------------------ 5 files changed, 78 insertions(+), 51 deletions(-) diff --git a/botspectate/main.go b/botspectate/main.go index e202301..88e4dce 100644 --- a/botspectate/main.go +++ b/botspectate/main.go @@ -7,6 +7,7 @@ import ( "time" "hackerbots.us/client" + "hackerbots.us/server" ) var serverHostname = flag.String("server", "localhost", "server hostname") @@ -26,12 +27,15 @@ func main() { } c := &client.Client{ - Server: *serverHostname, - Port: *port, - Name: "bspect", - GameId: gameId, - Verbose: *verbose, - ForceJSON: *forceJSON, + Server: *serverHostname, + Port: *port, + Name: "bspect", + GameId: gameId, + Verbose: *verbose, + ForceJSON: *forceJSON, + StateStream: make(chan *server.Boardstate), + Die: make(chan struct{}), + Player: client.Spectator{}, } var err error err = c.Negociate("spectator") @@ -39,17 +43,10 @@ func main() { 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() { if err := c.Play(); err != nil { - close(spectator.Die) + close(c.Die) } }() - - spectator.Run() + c.Visualize() } diff --git a/client.go b/client.go index 2d69401..c72e853 100644 --- a/client.go +++ b/client.go @@ -29,13 +29,20 @@ type Client struct { Server string StatsReq server.StatsRequest Verbose bool - Player Player Game server.GameParam boardstate *server.Boardstate enc encoder dec decoder ws *websocket.Conn + + // visualization members + width, height float64 + viewX, viewY int + StateStream chan *server.Boardstate + Die chan struct{} + + Player } type encoder interface { @@ -156,6 +163,9 @@ func (c *Client) Negociate(clientType string) (err error) { case "spectator": } + c.width = c.Game.BoardSize.Width + c.height = c.Game.BoardSize.Height + return nil } @@ -172,7 +182,8 @@ func (c *Client) Play() error { if err != nil { 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 { return err } diff --git a/gobot/main.go b/gobot/main.go index 09e3f05..ec6348e 100644 --- a/gobot/main.go +++ b/gobot/main.go @@ -56,8 +56,12 @@ func main() { WeaponDamage: *weaponDamage, WeaponSpeed: *weaponSpeed, }, - Verbose: *verbose, - ForceJSON: *forceJSON, + Verbose: *verbose, + ForceJSON: *forceJSON, + StateStream: make(chan *server.Boardstate), + Die: make(chan struct{}), + + Player: client.NewSimplePlayer(800, 600), } var err error err = c.Negociate("robot") @@ -65,12 +69,10 @@ func main() { log.Fatalf("%s: failed to negociate: %s", c.Name, err) } - c.Player = client.NewSimplePlayer( - c.Game.BoardSize.Width, - c.Game.BoardSize.Height, - ) - - if err := c.Play(); err != nil { - log.Fatal(err) - } + go func() { + if err := c.Play(); err != nil { + close(c.Die) + } + }() + c.Visualize() } diff --git a/player.go b/player.go index 13d9a01..e54ed55 100644 --- a/player.go +++ b/player.go @@ -66,7 +66,6 @@ func (p *SimplePlayer) Update(bs *server.Boardstate) map[string]server.Instructi Probe: &probe_point, } } - return instructions } @@ -149,3 +148,9 @@ func (p *SimplePlayer) probe(destination vector.Point2d) bool { } return true } + +type Spectator struct{} + +func (s Spectator) Update(bs *server.Boardstate) map[string]server.Instruction { + return nil +} diff --git a/spectator.go b/spectator.go index 5d13208..90f5726 100644 --- a/spectator.go +++ b/spectator.go @@ -18,30 +18,13 @@ type size struct { 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 -func (s *SimpleSpectator) Update(bs *server.Boardstate) map[string]server.Instruction { - s.update <- bs +func (s *Client) Recv(bs *server.Boardstate) map[string]server.Instruction { + s.StateStream <- bs return nil } -func (s *SimpleSpectator) Run() { +func (s *Client) Visualize() { err := termbox.Init() if err != nil { log.Fatal(err) @@ -49,7 +32,7 @@ func (s *SimpleSpectator) Run() { s.viewX, s.viewY = termbox.Size() - events := make(chan termbox.Event) + events := make(chan termbox.Event, 1024) go func() { for { events <- termbox.PollEvent() @@ -83,7 +66,7 @@ func (s *SimpleSpectator) Run() { case termbox.EventError: 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) 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)) y := int((bot.Position.Y / s.height) * float64(s.viewY)) 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 { x := int((p.Position.X / s.width) * float64(s.viewX)) y := int((p.Position.Y / s.height) * float64(s.viewY))