From 3fa53daadb495fe21e0b8a07eb88f4c2678a1773 Mon Sep 17 00:00:00 2001 From: Fraser Graham Date: Thu, 16 Jan 2014 00:02:59 -0800 Subject: [PATCH] rewrite of the stats system --- control.go | 6 +++--- deathmatch.go | 11 ++++++++--- game.go | 29 +++++++++++++++++++++++++---- melee.go | 1 + player.go | 1 + protocol.go | 2 ++ robot.go | 10 ++++++---- 7 files changed, 46 insertions(+), 14 deletions(-) diff --git a/control.go b/control.go index 05a9287..21c3e01 100644 --- a/control.go +++ b/control.go @@ -129,9 +129,9 @@ func gameStats(w http.ResponseWriter, req *http.Request) { http.Error(w, string(b), http.StatusNotFound) return } - g.winners.RLock() - defer g.winners.RUnlock() - if err := json.NewEncoder(w).Encode(g.winners.m); err != nil { + g.stats.RLock() + defer g.stats.RUnlock() + if err := json.NewEncoder(w).Encode(g.stats); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } diff --git a/deathmatch.go b/deathmatch.go index b8c55a6..ed483e2 100644 --- a/deathmatch.go +++ b/deathmatch.go @@ -21,16 +21,21 @@ func (g *deathmatch) gameOver(gg *game) (bool, *GameOver) { stats = NewGameOver() for p := range gg.players { + gg.stats.Lock() + playerWin := false for _, r := range p.Robots { if r.Health > 0 { log.Printf("Robot %v Survived", r.Id) - gg.winners.Lock() - gg.winners.m[r.Id] += 1 - gg.winners.Unlock() + gg.stats.PlayerStats[p.Id].BotStats[r.Name].Wins += 1 stats.Winners = append(stats.Winners, r.Id) + playerWin = true } r.reset(gg) } + if playerWin { + gg.stats.PlayerStats[p.Id].Wins += 1 + } + gg.stats.Unlock() } over = true } diff --git a/game.go b/game.go index 7af2b66..b859f7a 100644 --- a/game.go +++ b/game.go @@ -40,8 +40,22 @@ func (ml *MapLock) add(g *game) { ml.Unlock() } -type WinnerMap struct { - m map[string]int +type BotStats struct { + Kills int + Deaths int + Suicides int + Shots int + Hits int + Wins int +} + +type PlayerStats struct { + BotStats map[string]*BotStats + Wins int +} + +type GameStats struct { + PlayerStats map[string]*PlayerStats sync.RWMutex } @@ -65,7 +79,7 @@ type game struct { repair_hp int repair_rate float32 tick_duration int - winners WinnerMap + stats GameStats mode GameMode } @@ -97,7 +111,7 @@ func NewGame(id string, width, height float32, obstacles, tick, maxPoints int, m repair_rate: 3.0, tick_duration: tick, players_remaining: 2, - winners: WinnerMap{m: make(map[string]int)}, + stats: GameStats{PlayerStats: make(map[string]*PlayerStats)}, } if mode == "melee" { @@ -279,6 +293,13 @@ func (g *game) run() { return case p := <-g.register: g.players[p] = true + g.stats.PlayerStats[p.Id] = &PlayerStats{ + BotStats: make(map[string]*BotStats), + } + for _, r := range p.Robots { + g.stats.PlayerStats[p.Id].BotStats[r.Name] = &BotStats{} + r.gameStats = g.stats.PlayerStats[p.Id].BotStats[r.Name] + } case p := <-g.unregister: delete(g.players, p) close(p.send) diff --git a/melee.go b/melee.go index afe70e7..670bf09 100644 --- a/melee.go +++ b/melee.go @@ -24,6 +24,7 @@ func (g *melee) tick(gg *game, payload *Boardstate) { if r.Health <= 0 && !ok { g.respawn[r] = g.respawn_timer log.Printf("%v Died, Respawn in %v", r.Name, g.respawn_timer) + // gg.stats.playerStats[p.Id].botStats[r.Name].deaths++ } } } diff --git a/player.go b/player.go index bde3dd5..cae8751 100644 --- a/player.go +++ b/player.go @@ -10,6 +10,7 @@ type player struct { Robots []*Robot send chan Message Instruction Instruction + Id string } func (p *player) sender() { diff --git a/protocol.go b/protocol.go index d028241..0b46b73 100644 --- a/protocol.go +++ b/protocol.go @@ -234,6 +234,7 @@ func addPlayer(ws *websocket.Conn) { Robots: []*Robot{}, send: make(chan Message), ws: ws, + Id: idg.Hash(), } for name, stats := range conf.Stats { @@ -251,6 +252,7 @@ func addPlayer(ws *websocket.Conn) { } game.register <- p + defer func() { game.unregister <- p }() diff --git a/robot.go b/robot.go index d5f3cc4..a621b9c 100644 --- a/robot.go +++ b/robot.go @@ -29,6 +29,7 @@ type Robot struct { Hit bool `json:"hit"` Probe *v.Point2d `json:"probe"` ProbeResult *v.Point2d `json:"probe_result"` + gameStats *BotStats `json:-` } // This is the subset of data we send to players about robots @@ -323,7 +324,7 @@ func (r *Robot) Tick(g *game) { } if r.FireAt != nil { - proj := r.fire(g.projectiles, g.turn) + proj := r.fire(g) if proj != nil { g.projectiles[proj] = true } @@ -384,14 +385,15 @@ func (r *Robot) scan(g *game) { } -func (r *Robot) fire(projectiles map[*Projectile]bool, turn int) *Projectile { +func (r *Robot) fire(g *game) *Projectile { // Throttle the fire rate - time_since_fired := (float32(turn) * (delta * 1000)) - (float32(r.LastFired) * (delta * 1000)) + time_since_fired := (float32(g.turn) * (delta * 1000)) - (float32(r.LastFired) * (delta * 1000)) if time_since_fired < float32(r.Stats.FireRate) { return nil } - r.LastFired = turn + r.LastFired = g.turn + r.gameStats.Shots++ return &Projectile{ Id: idg.Hash(),