client/fraserbot.go

135 lines
3.1 KiB
Go

package client
import (
"fmt"
"log"
"math/rand"
"hackerbots.us/server"
"hackerbots.us/vector"
)
// Fraserbot is a bad ass motherfucker, that will fuck SHIT UUUUUP
type Fraserbot struct {
knownObstacles map[string]server.Obstacle
nearestEnemy *server.OtherRobot
fireat *vector.Point2d
moveto *vector.Point2d
name string
botIDs map[string]string
}
// NewFraserbot simply returns a populated, usable *Fraserbot
func NewFraserbot(name string) *Fraserbot {
return &Fraserbot{
knownObstacles: make(map[string]server.Obstacle),
name: name,
}
}
// GetStats returns a map with an entry for each robot the player will control
// containing the desired stats for that robot
func (p *Fraserbot) GetStats() map[string]server.StatsRequest {
s := make(map[string]server.StatsRequest)
s[fmt.Sprintf("%v_MAIN", p.name)] = server.StatsRequest{
Hp: 100,
Speed: 10,
Acceleration: 10,
ScannerRadius: 10,
TurnSpeed: 10,
FireRate: 30,
WeaponRadius: 20,
WeaponDamage: 30,
WeaponSpeed: 30,
}
s[fmt.Sprintf("%v_Jr", p.name)] = server.StatsRequest{
Hp: 10,
Speed: 100,
Acceleration: 10,
ScannerRadius: 60,
TurnSpeed: 48,
FireRate: 1,
WeaponRadius: 10,
WeaponDamage: 10,
WeaponSpeed: 1,
}
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
// from the server
func (p *Fraserbot) Update(bs *server.Boardstate) map[string]server.Instruction {
instructions := make(map[string]server.Instruction)
for _, bot := range bs.MyRobots {
me := bot
// We're just starting out
if p.moveto == nil {
p.moveto = &me.Position
}
speed := float64(200)
// 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{
MoveTo: p.moveto,
TargetSpeed: &speed,
FireAt: p.fireat,
Probe: p.moveto,
}
}
return instructions
}
// randomDirection is a spot within 200 of the current position
func (p *Fraserbot) randomDirection(pos vector.Point2d, dist float64) *vector.Point2d {
pt := vector.Vector2d{
X: (rand.Float64() * dist) - (dist / 2) + pos.X,
Y: (rand.Float64() * dist) - (dist / 2) + pos.Y,
}.ToPoint()
return &pt
}