rewrite of the stats system

This commit is contained in:
Fraser Graham 2014-01-16 00:02:59 -08:00
parent 90b7731865
commit 3fa53daadb
7 changed files with 46 additions and 14 deletions

View File

@ -129,9 +129,9 @@ func gameStats(w http.ResponseWriter, req *http.Request) {
http.Error(w, string(b), http.StatusNotFound) http.Error(w, string(b), http.StatusNotFound)
return return
} }
g.winners.RLock() g.stats.RLock()
defer g.winners.RUnlock() defer g.stats.RUnlock()
if err := json.NewEncoder(w).Encode(g.winners.m); err != nil { if err := json.NewEncoder(w).Encode(g.stats); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
} }
} }

View File

@ -21,16 +21,21 @@ func (g *deathmatch) gameOver(gg *game) (bool, *GameOver) {
stats = NewGameOver() stats = NewGameOver()
for p := range gg.players { for p := range gg.players {
gg.stats.Lock()
playerWin := false
for _, r := range p.Robots { for _, r := range p.Robots {
if r.Health > 0 { if r.Health > 0 {
log.Printf("Robot %v Survived", r.Id) log.Printf("Robot %v Survived", r.Id)
gg.winners.Lock() gg.stats.PlayerStats[p.Id].BotStats[r.Name].Wins += 1
gg.winners.m[r.Id] += 1
gg.winners.Unlock()
stats.Winners = append(stats.Winners, r.Id) stats.Winners = append(stats.Winners, r.Id)
playerWin = true
} }
r.reset(gg) r.reset(gg)
} }
if playerWin {
gg.stats.PlayerStats[p.Id].Wins += 1
}
gg.stats.Unlock()
} }
over = true over = true
} }

29
game.go
View File

@ -40,8 +40,22 @@ func (ml *MapLock) add(g *game) {
ml.Unlock() ml.Unlock()
} }
type WinnerMap struct { type BotStats struct {
m map[string]int 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 sync.RWMutex
} }
@ -65,7 +79,7 @@ type game struct {
repair_hp int repair_hp int
repair_rate float32 repair_rate float32
tick_duration int tick_duration int
winners WinnerMap stats GameStats
mode GameMode mode GameMode
} }
@ -97,7 +111,7 @@ func NewGame(id string, width, height float32, obstacles, tick, maxPoints int, m
repair_rate: 3.0, repair_rate: 3.0,
tick_duration: tick, tick_duration: tick,
players_remaining: 2, players_remaining: 2,
winners: WinnerMap{m: make(map[string]int)}, stats: GameStats{PlayerStats: make(map[string]*PlayerStats)},
} }
if mode == "melee" { if mode == "melee" {
@ -279,6 +293,13 @@ func (g *game) run() {
return return
case p := <-g.register: case p := <-g.register:
g.players[p] = true 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: case p := <-g.unregister:
delete(g.players, p) delete(g.players, p)
close(p.send) close(p.send)

View File

@ -24,6 +24,7 @@ func (g *melee) tick(gg *game, payload *Boardstate) {
if r.Health <= 0 && !ok { if r.Health <= 0 && !ok {
g.respawn[r] = g.respawn_timer g.respawn[r] = g.respawn_timer
log.Printf("%v Died, Respawn in %v", r.Name, g.respawn_timer) log.Printf("%v Died, Respawn in %v", r.Name, g.respawn_timer)
// gg.stats.playerStats[p.Id].botStats[r.Name].deaths++
} }
} }
} }

View File

@ -10,6 +10,7 @@ type player struct {
Robots []*Robot Robots []*Robot
send chan Message send chan Message
Instruction Instruction Instruction Instruction
Id string
} }
func (p *player) sender() { func (p *player) sender() {

View File

@ -234,6 +234,7 @@ func addPlayer(ws *websocket.Conn) {
Robots: []*Robot{}, Robots: []*Robot{},
send: make(chan Message), send: make(chan Message),
ws: ws, ws: ws,
Id: idg.Hash(),
} }
for name, stats := range conf.Stats { for name, stats := range conf.Stats {
@ -251,6 +252,7 @@ func addPlayer(ws *websocket.Conn) {
} }
game.register <- p game.register <- p
defer func() { defer func() {
game.unregister <- p game.unregister <- p
}() }()

View File

@ -29,6 +29,7 @@ type Robot struct {
Hit bool `json:"hit"` Hit bool `json:"hit"`
Probe *v.Point2d `json:"probe"` Probe *v.Point2d `json:"probe"`
ProbeResult *v.Point2d `json:"probe_result"` ProbeResult *v.Point2d `json:"probe_result"`
gameStats *BotStats `json:-`
} }
// This is the subset of data we send to players about robots // 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 { if r.FireAt != nil {
proj := r.fire(g.projectiles, g.turn) proj := r.fire(g)
if proj != nil { if proj != nil {
g.projectiles[proj] = true 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 // 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) { if time_since_fired < float32(r.Stats.FireRate) {
return nil return nil
} }
r.LastFired = turn r.LastFired = g.turn
r.gameStats.Shots++
return &Projectile{ return &Projectile{
Id: idg.Hash(), Id: idg.Hash(),