package main import ( "encoding/gob" "fmt" "log" "os" "sort" "time" ) const gobfile = `score.gob` var score map[string]int type Score struct { Nick string Count int Percent float64 } type Scores []Score func (s Scores) Len() int { return len(s) } func (s Scores) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s Scores) Less(i, j int) bool { return s[i].Count < s[j].Count } func NewScores(n int) (s Scores) { for k, v := range score { s = append(s, Score{ Nick: k, Count: v, }) } sort.Sort(sort.Reverse(s)) if n > 0 && len(s) > n { s = s[:n] } var total int for _, v := range s { total += v.Count } for i := range s { s[i].Percent = 100.0 * float64(s[i].Count) / float64(total) } return } func loadScore() map[string]int { m := make(map[string]int) fd, err := os.Open(gobfile) if err != nil { return m } defer fd.Close() decoder := gob.NewDecoder(fd) if err := decoder.Decode(&m); err != nil { log.Fatal(err) } return m } func saveScore(m map[string]int) { fd, err := os.Create(gobfile) if err != nil { log.Fatal(err) } defer fd.Close() encoder := gob.NewEncoder(fd) if err := encoder.Encode(m); err != nil { log.Fatal(err) } } func (s Score) String() string { return fmt.Sprintf("%v (%v/%.1f%%)", s.Nick, s.Count, s.Percent) } func (s Scores) String() (ret string) { for n, sc := range s { ret += fmt.Sprintf("%3d. %v", n+1, sc) } return } func init() { score = loadScore() } func Count(nick string) { score[nick]++ } func AutoSaveScore() { for range time.Tick(time.Minute) { saveScore(score) } }