Providing the bot ID to name mapping to the player after negotiation

This commit is contained in:
Fraser Graham 2016-07-13 21:25:51 -06:00
parent 6c67d83f49
commit 9be5f226f5
5 changed files with 81 additions and 25 deletions

View File

@ -135,10 +135,17 @@ func (c *Client) Negotiate(clientType string, player Player) (err error) {
Stats map[string]server.Stats `json:"stats"` Stats map[string]server.Stats `json:"stats"`
Type string `json:"type"` Type string `json:"type"`
}{} }{}
err = websocket.JSON.Receive(c.ws, &dstats) err = websocket.JSON.Receive(c.ws, &dstats)
if err != nil { if err != nil {
return err return err
} }
ids := make(map[string]string)
for name, entry := range dstats.Stats {
ids[entry.Id] = name
}
player.SetIDs(ids)
case "spectator": case "spectator":
} }

View File

@ -63,7 +63,7 @@ func main() {
case "simple": case "simple":
c.Player = client.NewSimplePlayer(800, 600, sr) c.Player = client.NewSimplePlayer(800, 600, sr)
case "fraserbot": case "fraserbot":
c.Player = client.NewFraserbot("Fraserbot", sr) c.Player = client.NewFraserbot("Fraserbot")
} }
var err error var err error

View File

@ -2,6 +2,7 @@ package client
import ( import (
"fmt" "fmt"
"log"
"math/rand" "math/rand"
"hackerbots.us/server" "hackerbots.us/server"
@ -10,21 +11,18 @@ import (
// Fraserbot is a bad ass motherfucker, that will fuck SHIT UUUUUP // Fraserbot is a bad ass motherfucker, that will fuck SHIT UUUUUP
type Fraserbot struct { type Fraserbot struct {
me server.Robot
knownObstacles map[string]server.Obstacle knownObstacles map[string]server.Obstacle
nearestEnemy *server.OtherRobot nearestEnemy *server.OtherRobot
fireat *vector.Point2d fireat *vector.Point2d
moveto *vector.Point2d moveto *vector.Point2d
speed float64
stats server.StatsRequest
name string name string
botIDs map[string]string
} }
// NewFraserbot simply returns a populated, usable *Fraserbot // NewFraserbot simply returns a populated, usable *Fraserbot
func NewFraserbot(name string, stats server.StatsRequest) *Fraserbot { func NewFraserbot(name string) *Fraserbot {
return &Fraserbot{ return &Fraserbot{
knownObstacles: make(map[string]server.Obstacle), knownObstacles: make(map[string]server.Obstacle),
stats: stats,
name: name, name: name,
} }
} }
@ -35,62 +33,102 @@ func (p *Fraserbot) GetStats() map[string]server.StatsRequest {
s := make(map[string]server.StatsRequest) s := make(map[string]server.StatsRequest)
s[fmt.Sprintf("%v_MAIN", p.name)] = server.StatsRequest{ s[fmt.Sprintf("%v_MAIN", p.name)] = server.StatsRequest{
Hp: 10, Hp: 100,
Speed: 10, Speed: 10,
Acceleration: 10, Acceleration: 10,
ScannerRadius: 10, ScannerRadius: 10,
TurnSpeed: 10, TurnSpeed: 10,
FireRate: 10, FireRate: 30,
WeaponRadius: 10, WeaponRadius: 20,
WeaponDamage: 10, WeaponDamage: 30,
WeaponSpeed: 10, WeaponSpeed: 30,
} }
s[fmt.Sprintf("%v_Jr", p.name)] = server.StatsRequest{ s[fmt.Sprintf("%v_Jr", p.name)] = server.StatsRequest{
Hp: 10, Hp: 10,
Speed: 10, Speed: 100,
Acceleration: 10, Acceleration: 10,
ScannerRadius: 10, ScannerRadius: 60,
TurnSpeed: 10, TurnSpeed: 48,
FireRate: 10, FireRate: 1,
WeaponRadius: 10, WeaponRadius: 10,
WeaponDamage: 10, WeaponDamage: 10,
WeaponSpeed: 10, WeaponSpeed: 1,
} }
return s return s
} }
// SetIDs provides the mapping of names to ID's for each bot
func (p *Fraserbot) SetIDs(ids map[string]string) {
p.botIDs = ids
log.Println(ids)
}
// Update is our implementation of recieving and processing a server.Boardstate // Update is our implementation of recieving and processing a server.Boardstate
// from the server // from the server
func (p *Fraserbot) Update(bs *server.Boardstate) map[string]server.Instruction { func (p *Fraserbot) Update(bs *server.Boardstate) map[string]server.Instruction {
instructions := make(map[string]server.Instruction) instructions := make(map[string]server.Instruction)
for _, bot := range bs.MyRobots { for _, bot := range bs.MyRobots {
p.me = bot me := bot
p.speed = 1000
// We're just starting out
if p.moveto == nil { if p.moveto == nil {
p.moveto = &p.me.Position p.moveto = &me.Position
} }
if p.me.Position.Sub(*p.moveto).Mag() < 30 { speed := float64(200)
p.moveto = p.randomDirection() // If we're close to where we want to go then pick a new
// place to go, we done good
if me.Position.Sub(*p.moveto).Mag() < 30 {
p.moveto = p.randomDirection(me.Position, 400)
}
if me.ProbeResult != nil && me.ProbeResult.Type == "obstacle" {
speed = -50
p.moveto = p.randomDirection(me.Position, 600)
}
if len(me.Scanners) > 0 {
// Find the bots that are not mine
var index int
found := false
for i, entry := range me.Scanners {
_, ok := p.botIDs[entry.Id]
if !ok {
index = i
found = true
break
}
}
if found {
// log.Println(me.Scanners[0])
for _, bot := range bs.OtherRobots {
if bot.Id == me.Scanners[index].Id {
p.fireat = &bot.Position
log.Printf("%v Found Enemy: %v\n", me.Name, bot.Name)
}
}
}
} }
instructions[bot.Id] = server.Instruction{ instructions[bot.Id] = server.Instruction{
MoveTo: p.moveto, MoveTo: p.moveto,
TargetSpeed: &p.speed, TargetSpeed: &speed,
FireAt: p.fireat, FireAt: p.fireat,
Probe: p.moveto,
} }
} }
return instructions return instructions
} }
// randomDirection is a spot within 200 of the current position // randomDirection is a spot within 200 of the current position
func (p *Fraserbot) randomDirection() *vector.Point2d { func (p *Fraserbot) randomDirection(pos vector.Point2d, dist float64) *vector.Point2d {
pt := vector.Vector2d{ pt := vector.Vector2d{
X: (rand.Float64() * 400) - 200 + p.me.Position.X, X: (rand.Float64() * dist) - (dist / 2) + pos.X,
Y: (rand.Float64() * 400) - 200 + p.me.Position.Y, Y: (rand.Float64() * dist) - (dist / 2) + pos.Y,
}.ToPoint() }.ToPoint()
return &pt return &pt
} }

View File

@ -13,6 +13,13 @@ type Player interface {
// containing the desired stats for that robot // containing the desired stats for that robot
GetStats() map[string]server.StatsRequest GetStats() map[string]server.StatsRequest
// SetIDs is called from the client once the server
// has accepted the robots supplied in GetStats and validated
// their config, the data passed into SetIDs is a mapping of
// bot name to server side bot ID that is used in all bot
// dats sent from the server
SetIDs(map[string]string)
// Update is called on reciept of a board state packet and the response is // Update is called on reciept of a board state packet and the response is
// the instructions for each robot in a map of robot id to instructions // the instructions for each robot in a map of robot id to instructions
Update(bs *server.Boardstate) map[string]server.Instruction Update(bs *server.Boardstate) map[string]server.Instruction
@ -20,6 +27,8 @@ type Player interface {
type Spectator struct{} type Spectator struct{}
func (s Spectator) SetIDs(map[string]string) {}
func (s Spectator) GetStats() map[string]server.StatsRequest { func (s Spectator) GetStats() map[string]server.StatsRequest {
return nil return nil
} }

View File

@ -35,6 +35,8 @@ func NewSimplePlayer(width, height float64, stats server.StatsRequest) *SimplePl
} }
} }
func (p *SimplePlayer) SetIDs(map[string]string) {}
// GetStats returns a map with an entry for each robot the player will control // GetStats returns a map with an entry for each robot the player will control
// containing the desired stats for that robot // containing the desired stats for that robot
func (p *SimplePlayer) GetStats() map[string]server.StatsRequest { func (p *SimplePlayer) GetStats() map[string]server.StatsRequest {