server/libfic/team_stats.go

107 lines
2.0 KiB
Go

package fic
import (
"fmt"
)
// statLine is a line of statistics for the file stats.json exposed to players.
type statLine struct {
Tip string `json:"tip"`
Total int `json:"total"`
Solved int `json:"solved"`
Tried int `json:"tried"`
Tries int `json:"tries"`
}
// teamStats represents the structure of stats.json.
type teamStats struct {
Levels []statLine `json:"levels"`
Themes map[int64]statLine `json:"themes"`
}
// GetLevel
func (s *teamStats) GetLevel(level int) *statLine {
level -= 1
for len(s.Levels) <= level {
s.Levels = append(s.Levels, statLine{
fmt.Sprintf("Level %d", (len(s.Levels) + 1)),
0,
0,
0,
0,
})
}
return &s.Levels[level]
}
// GetStats generates statistics for the Team.
func (t Team) GetStats() (interface{}, error) {
return GetTeamsStats(&t)
}
// GetTeamsStats returns statistics limited to the given Team.
func GetTeamsStats(t *Team) (interface{}, error) {
stat := teamStats{
[]statLine{},
map[int64]statLine{},
}
if themes, err := GetThemes(); err != nil {
return nil, err
} else {
for _, theme := range themes {
total := 0
solved := 0
tried := 0
tries := 0
if exercices, err := theme.GetExercices(); err != nil {
return nil, err
} else {
for _, exercice := range exercices {
var lvl int
if lvl, err = exercice.GetLevel(); err != nil {
return nil, err
}
sLvl := stat.GetLevel(lvl)
total += 1
sLvl.Total += 1
if t != nil {
if b := t.HasSolved(exercice); b != nil {
solved += 1
sLvl.Solved += 1
}
} else {
if n, _ := exercice.IsSolved(); n > 0 {
solved += n
sLvl.Solved += 1
}
}
try := NbTry(t, exercice)
if try > 0 {
tried += 1
tries += try
sLvl.Tried += 1
sLvl.Tries += try
}
}
}
stat.Themes[theme.Id] = statLine{
theme.Name,
total,
solved,
tried,
tries,
}
}
return stat, nil
}
}