clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

chore/regenerate-vhs-gifs
puzzletea / registry / registry.go
registry.go 3.6K
1// Package registry is the concrete runtime composition root for built-in games,2// imports, help text, and daily-capable modes.3package registry45import (6 "fmt"78 "github.com/FelineStateMachine/puzzletea/catalog"9 "github.com/FelineStateMachine/puzzletea/fillomino"10 "github.com/FelineStateMachine/puzzletea/game"11 "github.com/FelineStateMachine/puzzletea/gameentry"12 "github.com/FelineStateMachine/puzzletea/hashiwokakero"13 "github.com/FelineStateMachine/puzzletea/hitori"14 "github.com/FelineStateMachine/puzzletea/lightsout"15 "github.com/FelineStateMachine/puzzletea/netwalk"16 "github.com/FelineStateMachine/puzzletea/nonogram"17 "github.com/FelineStateMachine/puzzletea/nurikabe"18 "github.com/FelineStateMachine/puzzletea/puzzle"19 "github.com/FelineStateMachine/puzzletea/rippleeffect"20 "github.com/FelineStateMachine/puzzletea/shikaku"21 "github.com/FelineStateMachine/puzzletea/spellpuzzle"22 "github.com/FelineStateMachine/puzzletea/sudoku"23 "github.com/FelineStateMachine/puzzletea/sudokurgb"24 "github.com/FelineStateMachine/puzzletea/takuzu"25 "github.com/FelineStateMachine/puzzletea/takuzuplus"26 "github.com/FelineStateMachine/puzzletea/wordsearch"27)2829type (30 ModeEntry = gameentry.ModeEntry31 Entry = gameentry.Entry32)3334type DailyEntry struct {35 Spawner game.SeededSpawner36 GameID puzzle.GameID37 GameType string38 ModeID puzzle.ModeID39 Mode string40}4142var all = []Entry{43 fillomino.Entry,44 hashiwokakero.Entry,45 hitori.Entry,46 lightsout.Entry,47 netwalk.Entry,48 nonogram.Entry,49 nurikabe.Entry,50 rippleeffect.Entry,51 shikaku.Entry,52 spellpuzzle.Entry,53 sudoku.Entry,54 sudokurgb.Entry,55 takuzu.Entry,56 takuzuplus.Entry,57 wordsearch.Entry,58}5960var (61 definitions = buildDefinitions(all)62 index = catalog.MustBuild(definitions)63 entriesByID = buildEntriesByID(all)64)6566func buildDefinitions(entries []Entry) []puzzle.Definition {67 defs := make([]puzzle.Definition, 0, len(entries))68 for _, entry := range entries {69 defs = append(defs, entry.Definition)70 }71 return defs72}7374func buildEntriesByID(entries []Entry) map[puzzle.GameID]Entry {75 result := make(map[puzzle.GameID]Entry, len(entries))76 for _, entry := range entries {77 result[entry.Definition.ID] = entry78 }79 return result80}8182func Entries() []Entry {83 return append([]Entry(nil), all...)84}8586func Definitions() []puzzle.Definition {87 return index.Definitions()88}8990func Names() []string {91 return index.Names()92}9394func Lookup(name string) (Entry, bool) {95 def, ok := index.Lookup(name)96 if !ok {97 return Entry{}, false98 }99 entry, ok := entriesByID[def.ID]100 return entry, ok101}102103func Resolve(name string) (Entry, bool) {104 def, ok := index.Resolve(name)105 if !ok {106 return Entry{}, false107 }108 entry, ok := entriesByID[def.ID]109 return entry, ok110}111112func Import(gameType string, data []byte) (game.Gamer, error) {113 entry, ok := Lookup(gameType)114 if !ok {115 return nil, fmt.Errorf("unknown game type %q in save data", gameType)116 }117 g, err := entry.Import(data)118 if err != nil {119 return nil, fmt.Errorf("failed to import game: %w", err)120 }121 return g, nil122}123124func DailyEntries() []DailyEntry {125 dailies := index.DailyEntries()126 result := make([]DailyEntry, 0, len(dailies))127 for _, daily := range dailies {128 entry, ok := entriesByID[daily.GameID]129 if !ok {130 continue131 }132 for _, mode := range entry.Modes {133 if mode.Definition.ID != daily.ModeID || mode.Seeded == nil {134 continue135 }136 result = append(result, DailyEntry{137 Spawner: mode.Seeded,138 GameID: daily.GameID,139 GameType: entry.Definition.Name,140 ModeID: daily.ModeID,141 Mode: mode.Definition.Title,142 })143 break144 }145 }146 return result147}148149func Help(name string) (string, bool) {150 entry, ok := Resolve(name)151 if !ok {152 return "", false153 }154 return entry.Help, true155}