From 86a00042c304fbf69d14413fcee67f569276474b Mon Sep 17 00:00:00 2001 From: stephen mcquay Date: Sun, 17 Jul 2016 13:25:16 -0700 Subject: [PATCH] Make ui optional for gobot --- cmd/gobot/main.go | 32 ++++++++++++++++++++++++++------ player.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/cmd/gobot/main.go b/cmd/gobot/main.go index 456ff01..b3bccb1 100644 --- a/cmd/gobot/main.go +++ b/cmd/gobot/main.go @@ -27,6 +27,7 @@ var addr = flag.String("addr", "ws://localhost:8666", "server hostname") var botname = flag.String("name", "gobot", "the name that other players will see") var forceJSON = flag.Bool("json", false, "force json encoding") var botType = flag.String("bot", "simple", "which Bot [fraserbot, simple]") +var spectate = flag.Bool("spectate", false, "enable terminal visualizer") func main() { rand.Seed(time.Now().UnixNano()) @@ -66,14 +67,33 @@ func main() { os.Exit(1) } - var err error - err = c.Negotiate("robot", c.Player) - if err != nil { + if err := c.Negotiate("robot", c.Player); err != nil { fmt.Fprintf(os.Stderr, "%s: failed to negociate: %s\n", c.Name, err) os.Exit(1) } - if err := c.Play(); err != nil { - fmt.Fprintf(os.Stderr, "problem during play: %v\n", err) - os.Exit(1) + + if *spectate { + ui := client.NewSpectator(c.Width, c.Height) + players := client.MultiPlayer{ + c.Player, + ui, + } + c.Player = players + + go func() { + if err := c.Play(); err != nil { + fmt.Fprintf(os.Stderr, "problem during play: %v\n", err) + close(ui.Die) + } + }() + if err := ui.Spectate(); err != nil { + fmt.Fprintf(os.Stderr, "problem during visualization: %+v\n", err) + os.Exit(1) + } + } else { + if err := c.Play(); err != nil { + fmt.Fprintf(os.Stderr, "problem during play: %v\n", err) + os.Exit(1) + } } } diff --git a/player.go b/player.go index c49c393..c9b360a 100644 --- a/player.go +++ b/player.go @@ -23,3 +23,37 @@ type Player interface { // the instructions for each robot in a map of robot id to instructions Update(bs *server.Boardstate) map[string]server.Instruction } + +// MultiPlayer wraps multiple players and calls funcitons in Player in +// appropriate order. +// +// Typically used to add a Spectator to a bot. +type MultiPlayer []Player + +// GetStats implements GetStats for a collection of players asking each player +// for their stats, and returning the configuration of the first player. +func (mp MultiPlayer) GetStats() map[string]server.StatsRequest { + var s map[string]server.StatsRequest + for i := len(mp) - 1; i >= 0; i-- { + s = mp[i].GetStats() + } + return s +} + +// SetIDs passes ids to all players. +func (mp MultiPlayer) SetIDs(ids map[string]string) { + for _, p := range mp { + p.SetIDs(ids) + } +} + +// Update implements Update for a collection of players sending board state to +// each player, and returning the instructions associated with the first +// player. +func (mp MultiPlayer) Update(bs *server.Boardstate) map[string]server.Instruction { + var inst map[string]server.Instruction + for i := len(mp) - 1; i >= 0; i-- { + inst = mp[i].Update(bs) + } + return inst +}