package main import ( "bitbucket.org/hackerbots/bot" v "bitbucket.org/hackerbots/vector" "code.google.com/p/go.net/websocket" "log" "math/rand" ) type player struct { ws *websocket.Conn Robot bot.Robot send chan *bot.Boardstate Instruction bot.Instruction } func (p *player) sender() { for things := range p.send { err := websocket.JSON.Send(p.ws, *things) if err != nil { break } } p.ws.Close() log.Printf("player %s: sender close", p.Robot.Id) } func (p *player) recv() { for { // XXX: need to mark myself as having received something, also binding // such action to a particular game turn ID var msg bot.Instruction err := websocket.JSON.Receive(p.ws, &msg) if err != nil { // TODO: perhaps we could be a bit more precise in the handling of // this 'error' by selecting on some kill signal channel and this // json read? log.Print("problem receiving JSON from player: ", err) break } if msg.MoveTo != nil { p.Robot.MoveTo = msg.MoveTo } if msg.FireAt != nil { p.Robot.FireAt = msg.FireAt } if msg.Stats.Speed > 0 { p.Robot.Stats = msg.Stats p.Robot.Health = p.Robot.Stats.Hp } } log.Printf("player %s: recv close", p.Robot.Id) p.ws.Close() } func (p *player) nudge() { // XXX: we must take into account going past our p.Robot.MoveTo ... newPos := v.Move(p.Robot.Position, *p.Robot.MoveTo, p.Robot.Stats.Speed, delta) p.Robot.Position.X = newPos.X p.Robot.Position.Y = newPos.Y } func (p *player) scan(players map[*player]bool) { p.Robot.Scanners = p.Robot.Scanners[:0] for player, _ := range players { if player.Robot.Id == p.Robot.Id || player.Robot.Health <= 0 { continue } dist := v.Distance(player.Robot.Position, p.Robot.Position) if dist < float64(p.Robot.Stats.ScannerRadius) { s := bot.Scanner{ Position: v.Point2d{ X: player.Robot.Position.X, Y: player.Robot.Position.Y, }, } p.Robot.Scanners = append(p.Robot.Scanners, s) } } } func (p *player) fire(projectiles map[*bot.Projectile]bool) *bot.Projectile { // XXX: is this to prevent us from having multiple projectiles from the // same bot? for proj := range projectiles { if proj.Id == p.Robot.Id { return nil } } return &bot.Projectile{ Id: p.Robot.Id, Position: p.Robot.Position, MoveTo: *p.Robot.FireAt, Damage: 10, Radius: p.Robot.Stats.WeaponRadius, Speed: float64(p.Robot.Stats.Speed * 2), } } func (p *player) reset() { start_pos := v.Point2d{ X: rand.Float64() * *width, Y: rand.Float64() * *height, } p.Robot.MoveTo = &start_pos p.Robot.Position = start_pos p.Robot.Health = p.Robot.Stats.Hp }