89 lines
1.7 KiB
Go
89 lines
1.7 KiB
Go
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
|
|
}
|
|
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 {
|
|
Current Score
|
|
CurrentLives int
|
|
Highscores Highscores
|
|
}
|
|
|
|
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)
|
|
}
|