package main import ( "bitbucket.org/hackerbots/vector" "code.google.com/p/go.net/websocket" "errors" "flag" "fmt" "log" "math/rand" "time" ) var hp = flag.Int("hp", 50, "") var speed = flag.Int("speed", 50, "") var acceleration = flag.Int("acceleration", 50, "") var weaponRadius = flag.Int("wrad", 50, "weapon radius") var scannerRadius = flag.Int("srad", 50, "scanner radius") var fireRate = flag.Int("fire-rate", 50, "scanner radius") var server = flag.String("server", "hackerbots.us", "server hostname") var port = flag.Int("port", 8666, "server port") var botname = flag.String("name", "gobot", "the name that other players will see") var verbose = flag.Bool("verbose", false, "run verbosly") type infos struct { id string width, height float32 } func connect() (*websocket.Conn, error) { origin := "http://localhost/" url := fmt.Sprintf("ws://%s:%d/ws/", *server, *port) return websocket.Dial(url, "", origin) } func negociate(ws *websocket.Conn, gameid string) (i *infos, err error) { log.Printf("trying to connect to game %s", gameid) err = websocket.JSON.Send(ws, struct { Id string `json:"id"` }{ gameid, }) if err != nil { return nil, err } var idreq struct { Type string `json:"type"` AssignedID string `json:"id"` } err = websocket.JSON.Receive(ws, &idreq) if err != nil || idreq.Type == "failure" { return nil, errors.New(fmt.Sprintf("failure: %+v", idreq)) } log.Printf("idreq: %+v", idreq) err = websocket.JSON.Send(ws, struct { Type string `json:"type"` Name string `json:"name"` Useragent string `json:"useragent"` }{ Name: *botname, Useragent: "gobot", Type: "robot", }) if err != nil { return nil, err } type BoardSize struct { Width float32 `json:"width"` Height float32 `json:"height"` } var gameparam struct { BoardSize BoardSize `json:"boardsize"` Type string `json:"type"` } err = websocket.JSON.Receive(ws, &gameparam) if gameparam.Type != "gameparam" { return nil, errors.New("didn't receive a good gameparam") } log.Printf("gameparam: %+v", gameparam) conf := ClientConfig{ ID: gameid, Stats: map[string]StatsRequest{ *botname: StatsRequest{ Hp: *hp, Speed: *speed, Acceleration: *acceleration, WeaponRadius: *weaponRadius, ScannerRadius: *scannerRadius, TurnSpeed: 50, FireRate: *fireRate, WeaponDamage: 50, WeaponSpeed: 50, }, }, } err = websocket.JSON.Send(ws, conf) var handshake struct { ID string `json:"id"` Success bool `json:"success"` Type string `json:"type"` } websocket.JSON.Receive(ws, &handshake) if !handshake.Success { return nil, errors.New("failed to validate correct stats request") } log.Printf("handshake: %+v", handshake) return &infos{ id: idreq.AssignedID, width: gameparam.BoardSize.Width, height: gameparam.BoardSize.Height, }, err } func main() { rand.Seed(time.Now().UnixNano()) var err error var gameid string flag.Parse() if flag.NArg() < 1 { gameid = "debug" } else { gameid = flag.Arg(0) } ws, err := connect() if err != nil { log.Fatal(err) } boardInfo, err := negociate(ws, gameid) log.Printf("boardInfo: %+v", boardInfo) if err != nil { log.Fatal(err) } // TODO: var target govector.Point2d moveto := govector.Point2d{ X: rand.Float32() * boardInfo.width, Y: rand.Float32() * boardInfo.height, } log.Printf("moveto: %+v", moveto) var me Robot log.Printf("negociated well, starting loop") for { var boardstate Boardstate err = websocket.JSON.Receive(ws, &boardstate) // log.Printf("%#v", boardstate) if *verbose { log.Printf("%+v", boardstate) } if err != nil { log.Fatal("Connection lost") } me = boardstate.MyRobots[0] log.Printf("%+v", me) if govector.Distance(me.Position, moveto) < 3.0 { log.Printf("old: %+v: %+v", me.Position, moveto) moveto = govector.Point2d{ X: rand.Float32() * boardInfo.width, Y: rand.Float32() * boardInfo.height, } log.Printf("new: %+v: %+v", me.Position, moveto) } // TODO: send instructions instruction := map[string]Instruction{ me.Id: { MoveTo: &moveto, FireAt: &moveto, }, } log.Printf("instruction: %+v", instruction) err = websocket.JSON.Send(ws, instruction) if err != nil { log.Fatal(err) } //log.Fatal("WIP") } }