client/main.go

189 lines
4.3 KiB
Go

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")
}
}