M11: oändligt läge och New Game+
All checks were successful
release / build-release (push) Successful in 1m34s
All checks were successful
release / build-release (push) Successful in 1m34s
internal/endless lottar mål ur en seed: en av storyns nätkopplade stationer (aldrig samma två gånger i rad) med ett resmål som minst ett tåg går rakt till men inte alla; banan kopieras, bedöms om mot nätet, sällskapet växer var tredje mål och tidsgränsen krymper. O på bankartan (eller -endless) startar en omgång; klarade mål ger poäng och XP, Enter ger nästa mål, förlust eller Esc avslutar och omgången hamnar i sparfilens poänglista (fem bästa). G två gånger startar New Game+: items, banresultat, pengar och debuffar nollställs, skills, XP och japanskan behålls, sällskapet är en person större per varv. Docs, wiki, tester och skärmdumpar uppdaterade. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/lang"
|
||||
@@ -40,6 +41,38 @@ type State struct {
|
||||
Progress *progress.Progress `json:"progress"`
|
||||
Current *RunRef `json:"current,omitempty"`
|
||||
NavMode string `json:"navMode,omitempty"` // "list" (standard) eller "signs"
|
||||
Endless []EndlessRecord `json:"endless,omitempty"` // oändligt läge: bästa omgångarna, högst poäng först
|
||||
}
|
||||
|
||||
// EndlessRecord är en avslutad omgång i oändligt läge.
|
||||
type EndlessRecord struct {
|
||||
Score int `json:"score"`
|
||||
Goals int `json:"goals"` // antal klarade mål
|
||||
Seed [2]uint64 `json:"seed"`
|
||||
When time.Time `json:"when"`
|
||||
}
|
||||
|
||||
// MaxEndlessRecords är hur många omgångar som sparas i listan.
|
||||
const MaxEndlessRecords = 5
|
||||
|
||||
// AddEndless lägger in en omgång i listan (sorterad på poäng, högst först)
|
||||
// och rapporterar om den är ny bästa.
|
||||
func (s *State) AddEndless(r EndlessRecord) (best bool) {
|
||||
best = len(s.Endless) == 0 || r.Score > s.Endless[0].Score
|
||||
s.Endless = append(s.Endless, r)
|
||||
sort.SliceStable(s.Endless, func(i, j int) bool { return s.Endless[i].Score > s.Endless[j].Score })
|
||||
if len(s.Endless) > MaxEndlessRecords {
|
||||
s.Endless = s.Endless[:MaxEndlessRecords]
|
||||
}
|
||||
return best
|
||||
}
|
||||
|
||||
// BestEndless är bästa omgången (nil om ingen).
|
||||
func (s *State) BestEndless() *EndlessRecord {
|
||||
if len(s.Endless) == 0 {
|
||||
return nil
|
||||
}
|
||||
return &s.Endless[0]
|
||||
}
|
||||
|
||||
// New är ett nytt spel.
|
||||
|
||||
@@ -76,3 +76,19 @@ func TestDefaultPath(t *testing.T) {
|
||||
t.Fatalf("path=%q err=%v", p, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEndlessRecords(t *testing.T) {
|
||||
s := New()
|
||||
if s.BestEndless() != nil {
|
||||
t.Fatal("tom lista")
|
||||
}
|
||||
if !s.AddEndless(EndlessRecord{Score: 100, Goals: 1}) || s.AddEndless(EndlessRecord{Score: 50, Goals: 1}) || !s.AddEndless(EndlessRecord{Score: 300, Goals: 3}) {
|
||||
t.Fatal("ny bästa ska rapporteras bara när poängen slår listans topp")
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
s.AddEndless(EndlessRecord{Score: 10 + i})
|
||||
}
|
||||
if len(s.Endless) != MaxEndlessRecords || s.BestEndless().Score != 300 || s.Endless[1].Score != 100 {
|
||||
t.Fatalf("listan: %+v", s.Endless)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user