diff --git a/bspect/main.go b/bspect/main.go new file mode 100644 index 0000000..27fec05 --- /dev/null +++ b/bspect/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "flag" + "log" + "math/rand" + "time" + + "bitbucket.org/hackerbots/client" +) + +var serverHostname = flag.String("server", "localhost", "server hostname") +var port = flag.Int("port", 8666, "server port") +var verbose = flag.Bool("verbose", false, "run verbosly") +var forceJSON = flag.Bool("json", false, "force json encoding") + +func main() { + log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) + rand.Seed(time.Now().UnixNano()) + var gameId string + flag.Parse() + if flag.NArg() < 1 { + gameId = "debug" + } else { + gameId = flag.Arg(0) + } + + c := &client.Client{ + Server: *serverHostname, + Port: *port, + Name: "bspect", + GameId: gameId, + Verbose: *verbose, + ForceJSON: *forceJSON, + } + var err error + err = c.Negociate("spectator") + if err != nil { + log.Fatalf("%s: failed to negociate: %s", c.Name, err) + } + + c.Player = client.NewSimpleSpectator( + c.Game.BoardSize.Width, + c.Game.BoardSize.Height, + ) + + if err := c.Play(); err != nil { + log.Fatal(err) + } +} diff --git a/client.go b/client.go index e63401f..e4fe9fb 100644 --- a/client.go +++ b/client.go @@ -46,7 +46,7 @@ type decoder interface { } // Negociate runs through the hackerbots negociation protocol. -func (c *Client) Negociate() (err error) { +func (c *Client) Negociate(clientType string) (err error) { if c.Verbose { log.Printf("%s: trying to connect to game '%s'", c.Name, c.GameId) } @@ -83,7 +83,7 @@ func (c *Client) Negociate() (err error) { }{ Name: c.Name, Useragent: "gobot", - Type: "robot", + Type: clientType, }) if err != nil { return err @@ -114,38 +114,45 @@ func (c *Client) Negociate() (err error) { c.dec = gob.NewDecoder(c.ws) } - conf := server.ClientConfig{ - ID: c.GameId, - Stats: map[string]server.StatsRequest{ - c.Name: c.StatsReq, - }, - } + switch clientType { + case "robot": + conf := server.ClientConfig{ + ID: c.GameId, + Stats: map[string]server.StatsRequest{ + c.Name: c.StatsReq, + }, + } + if c.Verbose { + log.Printf("%s: client config: %+v", c.Name, conf) + } - err = websocket.JSON.Send(c.ws, conf) + err = websocket.JSON.Send(c.ws, conf) - var handshake struct { - Id string `json:"id"` - Success bool `json:"success"` - Type string `json:"type"` - server.Failure - } - websocket.JSON.Receive(c.ws, &handshake) - if !handshake.Success { - return errors.New(handshake.Reason) - } - if c.Verbose { - log.Printf("%s: handshake: %+v", c.Name, handshake) - } + var handshake struct { + Id string `json:"id"` + Success bool `json:"success"` + Type string `json:"type"` + server.Failure + } + websocket.JSON.Receive(c.ws, &handshake) + if !handshake.Success { + return errors.New(handshake.Reason) + } + if c.Verbose { + log.Printf("%s: handshake: %+v", c.Name, handshake) + } - // we don't do anything useful with dstats, but could be interesting to - // pass along to the player? - dstats := struct { - Stats map[string]server.Stats `json:"stats"` - Type string `json:"type"` - }{} - err = websocket.JSON.Receive(c.ws, &dstats) - if err != nil { - return err + // we don't do anything useful with dstats, but could be interesting to + // pass along to the player? + dstats := struct { + Stats map[string]server.Stats `json:"stats"` + Type string `json:"type"` + }{} + err = websocket.JSON.Receive(c.ws, &dstats) + if err != nil { + return err + } + case "spectator": } return nil diff --git a/gobot/main.go b/gobot/main.go index 4a37936..e9edb5b 100644 --- a/gobot/main.go +++ b/gobot/main.go @@ -60,7 +60,7 @@ func main() { ForceJSON: *forceJSON, } var err error - err = c.Negociate() + err = c.Negociate("robot") if err != nil { log.Fatalf("%s: failed to negociate: %s", c.Name, err) } diff --git a/spectator.go b/spectator.go new file mode 100644 index 0000000..0b3b5c8 --- /dev/null +++ b/spectator.go @@ -0,0 +1,25 @@ +package client + +import ( + "log" + + "bitbucket.org/hackerbots/server" +) + +type SimpleSpectator struct { + width, height float64 +} + +// NewSimpleSpectator simply returns a populated, usable *SimplePlayer +func NewSimpleSpectator(width, height float64) *SimpleSpectator { + return &SimpleSpectator{ + width: width, + height: height, + } +} + +// Recv is our implementation of receiving a server.Boardstate from the server +func (p *SimpleSpectator) Update(bs *server.Boardstate) map[string]server.Instruction { + log.Println("hi") + return nil +}