refactor for bot
This commit is contained in:
parent
835303c53d
commit
b495b16065
48
game.go
48
game.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bitbucket.org/hackerbots/bot"
|
||||||
"log"
|
"log"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
@ -9,8 +10,8 @@ import (
|
|||||||
type game struct {
|
type game struct {
|
||||||
id string
|
id string
|
||||||
players map[*player]bool
|
players map[*player]bool
|
||||||
projectiles map[*projectile]bool
|
projectiles map[*bot.Projectile]bool
|
||||||
splosions map[*splosion]bool
|
splosions map[*bot.Splosion]bool
|
||||||
register chan *player
|
register chan *player
|
||||||
unregister chan *player
|
unregister chan *player
|
||||||
robot_id chan int
|
robot_id chan int
|
||||||
@ -27,8 +28,8 @@ func NewGame(id string, width, height float64) *game {
|
|||||||
id: id,
|
id: id,
|
||||||
register: make(chan *player),
|
register: make(chan *player),
|
||||||
unregister: make(chan *player),
|
unregister: make(chan *player),
|
||||||
projectiles: make(map[*projectile]bool),
|
projectiles: make(map[*bot.Projectile]bool),
|
||||||
splosions: make(map[*splosion]bool),
|
splosions: make(map[*bot.Splosion]bool),
|
||||||
players: make(map[*player]bool),
|
players: make(map[*player]bool),
|
||||||
turn: 0,
|
turn: 0,
|
||||||
width: width,
|
width: width,
|
||||||
@ -40,29 +41,6 @@ func NewGame(id string, width, height float64) *game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Stats stats `json:"stats"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type boardstate struct {
|
|
||||||
Robots []robot `json:"robots"`
|
|
||||||
Projectiles []projectile `json:"projectiles"`
|
|
||||||
Splosions []splosion `json:"splosions"`
|
|
||||||
Reset bool `json:"reset"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Turn int `json:"turn"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBoardstate(id int) *boardstate {
|
|
||||||
return &boardstate{
|
|
||||||
Robots: []robot{},
|
|
||||||
Projectiles: []projectile{},
|
|
||||||
Type: "boardstate",
|
|
||||||
Turn: id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *game) run() {
|
func (g *game) run() {
|
||||||
g.robot_id = make(chan int)
|
g.robot_id = make(chan int)
|
||||||
go func() {
|
go func() {
|
||||||
@ -88,13 +66,15 @@ func (g *game) run() {
|
|||||||
case <-time.Tick(time.Duration(*tick) * time.Millisecond):
|
case <-time.Tick(time.Duration(*tick) * time.Millisecond):
|
||||||
g.turn++
|
g.turn++
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
|
|
||||||
if *verbose {
|
if *verbose {
|
||||||
log.Printf("\033[2JTurn: %v", g.turn)
|
log.Printf("\033[2JTurn: %v", g.turn)
|
||||||
log.Printf("Players: %v", len(g.players))
|
log.Printf("Players: %v", len(g.players))
|
||||||
log.Printf("Projectiles: %v", len(g.projectiles))
|
log.Printf("Projectiles: %v", len(g.projectiles))
|
||||||
log.Printf("Explosions: %v", len(g.splosions))
|
log.Printf("Explosions: %v", len(g.splosions))
|
||||||
}
|
}
|
||||||
payload := NewBoardstate(g.turn)
|
|
||||||
|
payload := bot.NewBoardstate(g.turn)
|
||||||
|
|
||||||
robots_remaining := 0
|
robots_remaining := 0
|
||||||
|
|
||||||
@ -103,21 +83,25 @@ func (g *game) run() {
|
|||||||
robots_remaining++
|
robots_remaining++
|
||||||
p.scan()
|
p.scan()
|
||||||
p.nudge()
|
p.nudge()
|
||||||
|
// XXX: change to pointer, check for pointer as (0, 0) is valid target
|
||||||
if p.Robot.FireAt.X != 0 && p.Robot.FireAt.Y != 0 {
|
if p.Robot.FireAt.X != 0 && p.Robot.FireAt.Y != 0 {
|
||||||
p.fire()
|
proj := p.fire()
|
||||||
|
if proj != nil {
|
||||||
|
g.projectiles[proj] = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
payload.Robots = append(payload.Robots, p.Robot)
|
payload.Robots = append(payload.Robots, p.Robot)
|
||||||
}
|
}
|
||||||
sort.Sort(robotSorter{payload.Robots})
|
sort.Sort(bot.RobotSorter{payload.Robots})
|
||||||
|
|
||||||
for p := range g.projectiles {
|
for p := range g.projectiles {
|
||||||
p.nudge()
|
// XXX: p.nudge()
|
||||||
payload.Projectiles = append(payload.Projectiles, *p)
|
payload.Projectiles = append(payload.Projectiles, *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
for s := range g.splosions {
|
for s := range g.splosions {
|
||||||
s.tick()
|
// XXX: s.tick()
|
||||||
payload.Splosions = append(payload.Splosions, *s)
|
payload.Splosions = append(payload.Splosions, *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
http.go
24
http.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bitbucket.org/hackerbots/bot"
|
||||||
"code.google.com/p/go.net/websocket"
|
"code.google.com/p/go.net/websocket"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -23,6 +24,7 @@ func startGame(w http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
gameLock.Lock()
|
gameLock.Lock()
|
||||||
games[new_game_name] = _g
|
games[new_game_name] = _g
|
||||||
|
log.Printf("%+v", games)
|
||||||
gameLock.Unlock()
|
gameLock.Unlock()
|
||||||
|
|
||||||
w.Write([]byte(fmt.Sprintf(`{"id": "%s"}`, new_game_name)))
|
w.Write([]byte(fmt.Sprintf(`{"id": "%s"}`, new_game_name)))
|
||||||
@ -42,7 +44,7 @@ func listGames(w http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
func addPlayer(ws *websocket.Conn) {
|
func addPlayer(ws *websocket.Conn) {
|
||||||
// route to appropriate game ...
|
// route to appropriate game ...
|
||||||
var gid GameID
|
var gid bot.GameID
|
||||||
err := websocket.JSON.Receive(ws, &gid)
|
err := websocket.JSON.Receive(ws, &gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("problem parsing the requested game id")
|
log.Println("problem parsing the requested game id")
|
||||||
@ -50,11 +52,15 @@ func addPlayer(ws *websocket.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gameLock.Lock()
|
gameLock.Lock()
|
||||||
game := games[gid.Id]
|
game, ok := games[gid.Id]
|
||||||
gameLock.Unlock()
|
gameLock.Unlock()
|
||||||
log.Printf("%+v", game)
|
|
||||||
|
|
||||||
id := "asdf"
|
if !ok {
|
||||||
|
log.Println("ERROR: game not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
id := idg.Hash()
|
||||||
|
|
||||||
conf, err := Negociate(ws, id, 400, 800)
|
conf, err := Negociate(ws, id, 400, 800)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -63,15 +69,17 @@ func addPlayer(ws *websocket.Conn) {
|
|||||||
|
|
||||||
if conf != nil {
|
if conf != nil {
|
||||||
p := &player{
|
p := &player{
|
||||||
Robot: robot{
|
Robot: bot.Robot{
|
||||||
Stats: conf.Stats,
|
Stats: conf.Stats,
|
||||||
Id: id,
|
Id: id,
|
||||||
Health: conf.Stats.Hp,
|
Health: conf.Stats.Hp,
|
||||||
Scanners: make([]scanner, 0)},
|
Scanners: make([]bot.Scanner, 0)},
|
||||||
send: make(chan *boardstate),
|
send: make(chan *bot.Boardstate),
|
||||||
ws: ws,
|
ws: ws,
|
||||||
|
game: game,
|
||||||
}
|
}
|
||||||
p.reset()
|
p.reset()
|
||||||
|
log.Printf("game: %+v", game)
|
||||||
game.register <- p
|
game.register <- p
|
||||||
defer func() {
|
defer func() {
|
||||||
game.unregister <- p
|
game.unregister <- p
|
||||||
@ -81,7 +89,7 @@ func addPlayer(ws *websocket.Conn) {
|
|||||||
log.Printf("%v has been disconnect from this game\n", p.Robot.Id)
|
log.Printf("%v has been disconnect from this game\n", p.Robot.Id)
|
||||||
} else {
|
} else {
|
||||||
s := &Spectator{
|
s := &Spectator{
|
||||||
send: make(chan *boardstate),
|
send: make(chan *bot.Boardstate),
|
||||||
ws: ws,
|
ws: ws,
|
||||||
}
|
}
|
||||||
game.sregister <- s
|
game.sregister <- s
|
||||||
|
24
player.go
24
player.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bitbucket.org/hackerbots/bot"
|
||||||
v "bitbucket.org/hackerbots/vector"
|
v "bitbucket.org/hackerbots/vector"
|
||||||
"code.google.com/p/go.net/websocket"
|
"code.google.com/p/go.net/websocket"
|
||||||
"log"
|
"log"
|
||||||
@ -9,15 +10,16 @@ import (
|
|||||||
|
|
||||||
type player struct {
|
type player struct {
|
||||||
ws *websocket.Conn
|
ws *websocket.Conn
|
||||||
Robot robot
|
game *game
|
||||||
send chan *boardstate
|
Robot bot.Robot
|
||||||
|
send chan *bot.Boardstate
|
||||||
Instruction instruction
|
Instruction instruction
|
||||||
}
|
}
|
||||||
|
|
||||||
type instruction struct {
|
type instruction struct {
|
||||||
MoveTo *v.Point2d `json:"move_to,omitempty"`
|
MoveTo *v.Point2d `json:"move_to,omitempty"`
|
||||||
FireAt *v.Point2d `json:"fire_at,omitempty"`
|
FireAt *v.Point2d `json:"fire_at,omitempty"`
|
||||||
Stats stats `json:"stats"`
|
Stats bot.Stats `json:"stats"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *player) sender() {
|
func (p *player) sender() {
|
||||||
@ -60,14 +62,14 @@ func (p *player) nudge() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *player) scan() {
|
func (p *player) scan() {
|
||||||
p.Robot.Scanners = make([]scanner, 0)
|
p.Robot.Scanners = make([]bot.Scanner, 0)
|
||||||
for player := range g.players {
|
for player := range p.game.players {
|
||||||
if player.Robot.Id == p.Robot.Id || player.Robot.Health <= 0 {
|
if player.Robot.Id == p.Robot.Id || player.Robot.Health <= 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dist := distance(player.Robot.Position, p.Robot.Position)
|
dist := distance(player.Robot.Position, p.Robot.Position)
|
||||||
if dist < float64(p.Robot.Stats.ScannerRadius) {
|
if dist < float64(p.Robot.Stats.ScannerRadius) {
|
||||||
s := scanner{
|
s := bot.Scanner{
|
||||||
Position: v.Point2d{
|
Position: v.Point2d{
|
||||||
X: player.Robot.Position.X,
|
X: player.Robot.Position.X,
|
||||||
Y: player.Robot.Position.Y,
|
Y: player.Robot.Position.Y,
|
||||||
@ -78,15 +80,14 @@ func (p *player) scan() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *player) fire() {
|
func (p *player) fire() *bot.Projectile {
|
||||||
|
for proj := range p.game.projectiles {
|
||||||
for proj := range g.projectiles {
|
|
||||||
if proj.Id == p.Robot.Id {
|
if proj.Id == p.Robot.Id {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proj := &projectile{
|
return &bot.Projectile{
|
||||||
Id: p.Robot.Id,
|
Id: p.Robot.Id,
|
||||||
Position: p.Robot.Position,
|
Position: p.Robot.Position,
|
||||||
MoveTo: p.Robot.FireAt,
|
MoveTo: p.Robot.FireAt,
|
||||||
@ -94,7 +95,6 @@ func (p *player) fire() {
|
|||||||
Radius: p.Robot.Stats.WeaponRadius,
|
Radius: p.Robot.Stats.WeaponRadius,
|
||||||
Speed: float64(p.Robot.Stats.Speed * 2),
|
Speed: float64(p.Robot.Stats.Speed * 2),
|
||||||
}
|
}
|
||||||
g.projectiles[proj] = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *player) reset() {
|
func (p *player) reset() {
|
||||||
|
84
protocol.go
84
protocol.go
@ -1,77 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bitbucket.org/hackerbots/bot"
|
||||||
"code.google.com/p/go.net/websocket"
|
"code.google.com/p/go.net/websocket"
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GameID struct {
|
|
||||||
Id string `json:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// > identify
|
|
||||||
type IdRequest struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
AssignedID string `json:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIdRequest(id string) *IdRequest {
|
|
||||||
return &IdRequest{
|
|
||||||
Type: "idreq",
|
|
||||||
AssignedID: id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// < [robot | spectator], name, client-type, game ID
|
|
||||||
type ClientID struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Useragent string `json:"useragent"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientID) Valid() (bool, string) {
|
|
||||||
switch c.Type {
|
|
||||||
case "robot", "spectator":
|
|
||||||
return true, ""
|
|
||||||
}
|
|
||||||
return false, "usergent must be 'robot' or 'spectator'"
|
|
||||||
}
|
|
||||||
|
|
||||||
type BoardSize struct {
|
|
||||||
Width float64 `json:"width"`
|
|
||||||
Height float64 `json:"height"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GameParam struct {
|
|
||||||
BoardSize BoardSize `json:"boardsize"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// > [OK | FULL | NOT AUTH], board size, game params
|
|
||||||
func NewGameParam(w, h float64) *GameParam {
|
|
||||||
return &GameParam{
|
|
||||||
BoardSize: BoardSize{
|
|
||||||
Width: w,
|
|
||||||
Height: h,
|
|
||||||
},
|
|
||||||
Type: "gameparam",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Handshake struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Success bool `json:"success"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHandshake(id string, success bool) *Handshake {
|
|
||||||
return &Handshake{
|
|
||||||
ID: id,
|
|
||||||
Success: success,
|
|
||||||
Type: "handshake",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Failure struct {
|
type Failure struct {
|
||||||
Reason string `json:"reason"`
|
Reason string `json:"reason"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
@ -84,15 +18,15 @@ func NewFailure(reason string) *Failure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Negociate(ws *websocket.Conn, id string, width, height float64) (*Config, error) {
|
func Negociate(ws *websocket.Conn, id string, width, height float64) (*bot.Config, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
err = websocket.JSON.Send(ws, NewIdRequest(id))
|
err = websocket.JSON.Send(ws, bot.NewIdRequest(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("generic servr error")
|
return nil, errors.New("generic servr error")
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientid ClientID
|
var clientid bot.ClientID
|
||||||
err = websocket.JSON.Receive(ws, &clientid)
|
err = websocket.JSON.Receive(ws, &clientid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("could not parse id")
|
return nil, errors.New("could not parse id")
|
||||||
@ -105,7 +39,7 @@ func Negociate(ws *websocket.Conn, id string, width, height float64) (*Config, e
|
|||||||
return nil, errors.New(msg)
|
return nil, errors.New(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
gameParam := NewGameParam(width, height)
|
gameParam := bot.NewGameParam(width, height)
|
||||||
err = websocket.JSON.Send(ws, gameParam)
|
err = websocket.JSON.Send(ws, gameParam)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
websocket.JSON.Send(ws, NewFailure("generic server error"))
|
websocket.JSON.Send(ws, NewFailure("generic server error"))
|
||||||
@ -113,18 +47,18 @@ func Negociate(ws *websocket.Conn, id string, width, height float64) (*Config, e
|
|||||||
}
|
}
|
||||||
switch clientid.Type {
|
switch clientid.Type {
|
||||||
case "robot":
|
case "robot":
|
||||||
var conf Config
|
var conf bot.Config
|
||||||
for {
|
for {
|
||||||
err = websocket.JSON.Receive(ws, &conf)
|
err = websocket.JSON.Receive(ws, &conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// TODO: verify conf's type
|
// TODO: verify conf's type
|
||||||
if conf.Stats.valid() {
|
if conf.Stats.Valid() {
|
||||||
_ = websocket.JSON.Send(ws, NewHandshake(id, true))
|
_ = websocket.JSON.Send(ws, bot.NewHandshake(id, true))
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
_ = websocket.JSON.Send(ws, NewHandshake(id, false))
|
_ = websocket.JSON.Send(ws, bot.NewHandshake(id, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &conf, nil
|
return &conf, nil
|
||||||
|
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"code.google.com/p/go.net/websocket"
|
"code.google.com/p/go.net/websocket"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -17,6 +18,10 @@ type clientIDTest struct {
|
|||||||
expected result
|
expected result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CreatedGame struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
var clientIDTests = []clientIDTest{
|
var clientIDTests = []clientIDTest{
|
||||||
{ClientID{Type: "robot"}, result{true, ""}},
|
{ClientID{Type: "robot"}, result{true, ""}},
|
||||||
{ClientID{Type: "spectator"}, result{true, ""}},
|
{ClientID{Type: "spectator"}, result{true, ""}},
|
||||||
@ -52,11 +57,13 @@ var handled bool
|
|||||||
func DummyServer() (*websocket.Conn, error) {
|
func DummyServer() (*websocket.Conn, error) {
|
||||||
if !handled {
|
if !handled {
|
||||||
http.Handle("/ws/", websocket.Handler(addPlayer))
|
http.Handle("/ws/", websocket.Handler(addPlayer))
|
||||||
|
http.Handle("/game/start/", JsonHandler(startGame))
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
g = NewGame("hello world", 400, 800)
|
games = make(map[string]*game)
|
||||||
go g.run()
|
idg = NewIdGenerator()
|
||||||
|
|
||||||
go http.ListenAndServe(*addr, nil)
|
go http.ListenAndServe(*addr, nil)
|
||||||
|
|
||||||
origin := "http://localhost/"
|
origin := "http://localhost/"
|
||||||
@ -66,6 +73,18 @@ func DummyServer() (*websocket.Conn, error) {
|
|||||||
|
|
||||||
func TestGoodProtocol(t *testing.T) {
|
func TestGoodProtocol(t *testing.T) {
|
||||||
ws, err := DummyServer()
|
ws, err := DummyServer()
|
||||||
|
log.Printf("blah: %+v", ws)
|
||||||
|
|
||||||
|
resp, err := http.Get("http://localhost:8666/game/start/")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error getting: %+v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
var g CreatedGame
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&g); err != nil {
|
||||||
|
t.Errorf("json parse error? %+v", err)
|
||||||
|
}
|
||||||
|
log.Printf("g: %+v\n", g)
|
||||||
|
|
||||||
err = websocket.JSON.Send(ws, GameID{
|
err = websocket.JSON.Send(ws, GameID{
|
||||||
"test",
|
"test",
|
||||||
|
164
robot.go
164
robot.go
@ -1,126 +1,52 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
v "bitbucket.org/hackerbots/vector"
|
|
||||||
)
|
|
||||||
|
|
||||||
type weapon struct {
|
type weapon struct {
|
||||||
Strength float64 `json:"strength"`
|
Strength float64 `json:"strength"`
|
||||||
Radius float64 `json:"radius"`
|
Radius float64 `json:"radius"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type stats struct {
|
// XXX: this needs to go into game somehow
|
||||||
Hp int `json:"hp"`
|
// func (p *bot.Projectile) nudge() {
|
||||||
Speed float64 `json:"speed"`
|
// newPos := move(p.Position, p.MoveTo, float64(p.Speed), delta)
|
||||||
WeaponRadius int `json:"weapon_radius"`
|
//
|
||||||
ScannerRadius int `json:"scanner_radius"`
|
// hit_player := false
|
||||||
}
|
// for player := range p.game.players {
|
||||||
|
// if player.Robot.Id == p.Id {
|
||||||
func (s stats) valid() bool {
|
// continue
|
||||||
total := int(s.Speed) + s.Hp + s.WeaponRadius + s.ScannerRadius
|
// }
|
||||||
if total > 500 {
|
// dist := distance(player.Robot.Position, p.Position)
|
||||||
return false
|
// if dist < 5.0 {
|
||||||
}
|
// hit_player = true
|
||||||
return true
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
type scanner struct {
|
// if distance(p.Position, p.MoveTo) < 5 || hit_player {
|
||||||
Position v.Point2d `json:"position"`
|
// delete(p.game.projectiles, p)
|
||||||
Stats stats `json:"stats"`
|
//
|
||||||
}
|
// // Spawn a splosion
|
||||||
|
// splo := &splosion{
|
||||||
type robot struct {
|
// Id: p.Id,
|
||||||
Id string `json:"id"`
|
// Position: p.Position,
|
||||||
Stats stats `json:"stats"`
|
// Radius: p.Radius,
|
||||||
Health int `json:"health"`
|
// MaxDamage: 10,
|
||||||
Position v.Point2d `json:"position"`
|
// MinDamage: 5,
|
||||||
MoveTo v.Point2d `json:"move_to"`
|
// Lifespan: 8,
|
||||||
FireAt v.Point2d `json:"fire_at"`
|
// }
|
||||||
Scanners []scanner `json:"scanners"`
|
// p.game.splosions[splo] = true
|
||||||
}
|
//
|
||||||
|
// for player := range p.game.players {
|
||||||
type robotSorter struct {
|
// dist := distance(player.Robot.Position, p.Position)
|
||||||
robots []robot
|
// if dist < float64(p.Radius) {
|
||||||
}
|
//
|
||||||
|
// // TODO map damage Max to Min based on distance from explosion
|
||||||
func (s robotSorter) Len() int {
|
// if player.Robot.Health > 0 {
|
||||||
return len(s.robots)
|
// player.Robot.Health -= p.Damage
|
||||||
}
|
// if player.Robot.Health <= 0 {
|
||||||
|
// }
|
||||||
func (s robotSorter) Swap(i, j int) {
|
// }
|
||||||
s.robots[i], s.robots[j] = s.robots[j], s.robots[i]
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
func (s robotSorter) Less(i, j int) bool {
|
// p.Position.X = newPos.X
|
||||||
return s.robots[i].Id < s.robots[j].Id
|
// p.Position.Y = newPos.Y
|
||||||
}
|
// }
|
||||||
|
|
||||||
type projectile struct {
|
|
||||||
Id string `json:"id"`
|
|
||||||
Position v.Point2d `json:"position"`
|
|
||||||
MoveTo v.Point2d `json:"move_to"`
|
|
||||||
Radius int `json:"radius"`
|
|
||||||
Speed float64 `json:"speed"`
|
|
||||||
Damage int `json:"damage"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *projectile) nudge() {
|
|
||||||
newPos := move(p.Position, p.MoveTo, float64(p.Speed), delta)
|
|
||||||
|
|
||||||
hit_player := false
|
|
||||||
for player := range g.players {
|
|
||||||
if player.Robot.Id == p.Id {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
dist := distance(player.Robot.Position, p.Position)
|
|
||||||
if dist < 5.0 {
|
|
||||||
hit_player = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if distance(p.Position, p.MoveTo) < 5 || hit_player {
|
|
||||||
delete(g.projectiles, p)
|
|
||||||
|
|
||||||
// Spawn a splosion
|
|
||||||
splo := &splosion{
|
|
||||||
Id: p.Id,
|
|
||||||
Position: p.Position,
|
|
||||||
Radius: p.Radius,
|
|
||||||
MaxDamage: 10,
|
|
||||||
MinDamage: 5,
|
|
||||||
Lifespan: 8,
|
|
||||||
}
|
|
||||||
g.splosions[splo] = true
|
|
||||||
|
|
||||||
for player := range g.players {
|
|
||||||
dist := distance(player.Robot.Position, p.Position)
|
|
||||||
if dist < float64(p.Radius) {
|
|
||||||
|
|
||||||
// TODO map damage Max to Min based on distance from explosion
|
|
||||||
if player.Robot.Health > 0 {
|
|
||||||
player.Robot.Health -= p.Damage
|
|
||||||
if player.Robot.Health <= 0 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.Position.X = newPos.X
|
|
||||||
p.Position.Y = newPos.Y
|
|
||||||
}
|
|
||||||
|
|
||||||
type splosion struct {
|
|
||||||
Id string `json:"id"`
|
|
||||||
Position v.Point2d `json:"position"`
|
|
||||||
Radius int `json:"radius"`
|
|
||||||
MaxDamage int `json:"damage"`
|
|
||||||
MinDamage int `json:"damage"`
|
|
||||||
Lifespan int `json:"lifespan"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *splosion) tick() {
|
|
||||||
s.Lifespan--
|
|
||||||
if s.Lifespan <= 0 {
|
|
||||||
delete(g.splosions, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bitbucket.org/hackerbots/bot"
|
||||||
"code.google.com/p/go.net/websocket"
|
"code.google.com/p/go.net/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Spectator struct {
|
type Spectator struct {
|
||||||
ws *websocket.Conn
|
ws *websocket.Conn
|
||||||
send chan *boardstate
|
send chan *bot.Boardstate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Spectator) sender() {
|
func (s *Spectator) sender() {
|
||||||
|
Loading…
Reference in New Issue
Block a user