tins2021/score.go

89 lines
1.7 KiB
Go
Raw Permalink Normal View History

2021-08-11 06:03:02 +00:00
package tins2021
import (
"crypto/sha256"
"encoding/base64"
"fmt"
)
const scoreFileName = "score.json"
type Highscores []Score
func (h Highscores) AddScore(score, difficulty int) (Highscores, bool) {
highscores := len(h)
var rank = highscores
for ; rank > 0; rank-- {
if score <= h[rank-1].Score {
break
}
}
highscore := NewScore(score, difficulty)
if rank == highscores && highscores < 10 {
return append(h, highscore), true
}
if rank < 10 {
h = append(h[:rank], append([]Score{highscore}, h[rank:highscores]...)...)
if len(h) > 10 {
h = h[:10]
}
return h, true
2021-08-11 06:03:02 +00:00
}
return h, false
}
type Score struct {
Score int
Difficulty int
Hash string
}
func NewScore(score, difficulty int) Score {
s := Score{Score: score, Difficulty: difficulty}
s.Hash = s.hash()
return s
}
func (s *Score) hash() string {
hashText := fmt.Sprintf("tins2021_qbitter, %d, %d", s.Score, s.Difficulty)
hash := sha256.Sum256([]byte(hashText))
return base64.StdEncoding.EncodeToString(hash[:])
}
func (s *Score) Validate() bool {
hash := s.hash()
if hash == s.Hash {
return true
}
s.Score = 0
s.Difficulty = 0
return false
}
type ScoreState struct {
2021-08-12 20:35:33 +00:00
Current Score
CurrentLives int
Highscores Highscores
2021-08-11 06:03:02 +00:00
}
func LoadScores() (ScoreState, error) {
var state ScoreState
if err := LoadUserFileJSON(scoreFileName, &state); err != nil {
return ScoreState{}, err
}
state.Current.Validate()
for i := 0; i < len(state.Highscores); {
if !state.Highscores[i].Validate() {
state.Highscores = append(state.Highscores[:i], state.Highscores[i+1:]...)
} else {
i++
}
}
return state, nil
}
func SaveScores(s *ScoreState) error {
return SaveUserFileJSON(scoreFileName, s)
}