spelled things more how I wanted to

This commit is contained in:
Stephen McQuay 2013-11-10 23:30:23 -08:00
parent 6390aa96da
commit 5f6ad59303
3 changed files with 199 additions and 153 deletions

View File

@ -9,6 +9,17 @@ type ClientConfig struct {
Stats map[string]StatsRequest `json:"stats"`
}
type BoardSize struct {
Width float32 `json:"width"`
Height float32 `json:"height"`
}
type GameParam struct {
BoardSize BoardSize `json:"boardsize"`
name string
Type string `json:"type"`
}
type StatsRequest struct {
Hp int `json:"hp"`
Speed int `json:"speed"`

174
main.go
View File

@ -1,11 +1,7 @@
package main
import (
"bitbucket.org/hackerbots/vector"
"code.google.com/p/go.net/websocket"
"errors"
"flag"
"fmt"
"log"
"math/rand"
"time"
@ -18,168 +14,40 @@ 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")
// XXX: add TurnSpeed, WeaponDamage, WeaponSpeed
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
var gameName string
flag.Parse()
if flag.NArg() < 1 {
gameid = "debug"
gameName = "debug"
} else {
gameid = flag.Arg(0)
gameName = flag.Arg(0)
}
ws, err := connect()
// XXX: add TurnSpeed, WeaponDamage, WeaponSpeed
r, err := NewRobot(
*server,
*port,
gameName,
*hp,
*speed,
*acceleration,
*weaponRadius,
*scannerRadius,
*fireRate,
)
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]
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,
},
}
err = websocket.JSON.Send(ws, instruction)
if err != nil {
log.Fatal(err)
}
}
log.Printf("%+v", r)
r.play()
}

167
robot.go Normal file
View File

@ -0,0 +1,167 @@
package main
import (
"bitbucket.org/hackerbots/vector"
"code.google.com/p/go.net/websocket"
"errors"
"fmt"
"log"
"math/rand"
)
func connect() (*websocket.Conn, error) {
origin := "http://localhost/"
url := fmt.Sprintf("ws://%s:%d/ws/", *server, *port)
return websocket.Dial(url, "", origin)
}
type robot struct {
ws *websocket.Conn
game GameParam
playerId string
}
func NewRobot(
server string,
port int,
gameName string,
hp,
speed,
acceleration,
weaponRadius,
scannerRadius,
fireRate int) (*robot, error) {
ws, err := connect()
if err != nil {
return nil, errors.New(fmt.Sprintf("connection failure: %s", err))
}
r := &robot{
ws: ws,
}
// XXX: update with missing fields
statsReq := StatsRequest{
Hp: hp,
Speed: speed,
Acceleration: acceleration,
WeaponRadius: weaponRadius,
ScannerRadius: scannerRadius,
TurnSpeed: 50,
FireRate: fireRate,
WeaponDamage: 50,
WeaponSpeed: 50,
}
err = r.negociate(statsReq, gameName)
return r, nil
}
func (r *robot) negociate(req StatsRequest, gameName string) (err error) {
log.Printf("trying to connect to game '%s'", gameName)
err = websocket.JSON.Send(r.ws, struct {
Id string `json:"id"`
}{
gameName,
})
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: *botname,
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")
}
r.game.name = gameName
log.Printf("game parameters: %+v", r.game)
conf := ClientConfig{
ID: gameName,
Stats: map[string]StatsRequest{
*botname: req,
},
}
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
// 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)
}
}
}