package main import ( "bitbucket.org/hackerbots/vector" "code.google.com/p/go.net/websocket" "errors" "fmt" "log" "math/rand" ) func connect(server string, port int) (*websocket.Conn, error) { origin := "http://localhost/" url := fmt.Sprintf("ws://%s:%d/ws/", server, port) return websocket.Dial(url, "", origin) } type robot struct { server string port int ws *websocket.Conn game GameParam playerId string name string stats StatsRequest } func (r *robot) negociate() (err error) { log.Printf("trying to connect to game '%s'", r.game.name) r.ws, err = connect(r.server, r.port) if err != nil { return errors.New(fmt.Sprintf("connection failure: %s", err)) } err = websocket.JSON.Send(r.ws, struct { Id string `json:"id"` }{ r.game.name, }) if err != nil { return err } var idreq struct { Type string `json:"type"` PlayerId string `json:"id"` } err = websocket.JSON.Receive(r.ws, &idreq) if err != nil || idreq.Type == "failure" { return errors.New(fmt.Sprintf("failure: %+v", idreq)) } log.Printf("idreq: %+v", idreq) err = websocket.JSON.Send(r.ws, struct { Type string `json:"type"` Name string `json:"name"` Useragent string `json:"useragent"` }{ Name: r.name, Useragent: "gobot", Type: "robot", }) if err != nil { return err } err = websocket.JSON.Receive(r.ws, &r.game) if r.game.Type != "gameparam" { return errors.New("didn't receive a good gameparam") } log.Printf("game parameters: %+v", r.game) conf := ClientConfig{ ID: r.game.name, Stats: map[string]StatsRequest{ r.name: r.stats, }, } err = websocket.JSON.Send(r.ws, conf) var handshake struct { Id string `json:"id"` Success bool `json:"success"` Type string `json:"type"` } websocket.JSON.Receive(r.ws, &handshake) if !handshake.Success { return errors.New("failed to validate correct stats request") } r.playerId = handshake.Id log.Printf("handshake: %+v", handshake) return nil } func (r *robot) play() { var err error err = r.negociate() if err != nil { log.Fatal("failed to negociate:", err) } log.Printf("me: %+v", r) // TODO: var target govector.Point2d moveto := govector.Point2d{ X: rand.Float32() * r.game.BoardSize.Width, Y: rand.Float32() * r.game.BoardSize.Height, } log.Printf("moveto: %+v", moveto) var me Robot log.Printf("%s: starting loop", r.playerId) for { var boardstate Boardstate err = websocket.JSON.Receive(r.ws, &boardstate) if *verbose { log.Printf("%+v", boardstate) } if err != nil { log.Fatal("Connection lost") } me = boardstate.MyRobots[0] if govector.Distance(me.Position, moveto) < 3.0 { log.Printf("old: %+v: %+v", me.Position, moveto) moveto = govector.Point2d{ X: rand.Float32() * r.game.BoardSize.Width, Y: rand.Float32() * r.game.BoardSize.Height, } log.Printf("new: %+v: %+v", me.Position, moveto) } // TODO: send instructions instruction := map[string]Instruction{ me.Id: { MoveTo: &moveto, FireAt: &moveto, }, } err = websocket.JSON.Send(r.ws, instruction) if err != nil { log.Fatal(err) } } }