clone

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

feat/app-decomposition
puzzletea / games / nurikabe / gamemode.go
gamemode.go 2.5K
1package nurikabe23import (4 "context"5 _ "embed"6 "fmt"7 "math/rand/v2"89 "github.com/FelineStateMachine/puzzletea/game"10 "github.com/FelineStateMachine/puzzletea/gameentry"11 "github.com/FelineStateMachine/puzzletea/puzzle"12)1314//go:embed help.md15var HelpContent string1617type NurikabeMode struct {18 game.BaseMode19 Width int20 Height int21 ClueDensity float6422 MaxIslandSize int23}2425var (26 _ game.Mode = NurikabeMode{}27 _ game.Spawner = NurikabeMode{}28 _ game.SeededSpawner = NurikabeMode{}29 _ game.CancellableSpawner = NurikabeMode{}30 _ game.CancellableSeededSpawner = NurikabeMode{}31)3233func NewMode(title, desc string, width, height int, clueDensity float64, maxIslandSize int) NurikabeMode {34 return NurikabeMode{35 BaseMode: game.NewBaseMode(title, desc),36 Width: width,37 Height: height,38 ClueDensity: clueDensity,39 MaxIslandSize: maxIslandSize,40 }41}4243func (n NurikabeMode) Spawn() (game.Gamer, error) {44 return n.SpawnContext(context.Background())45}4647func (n NurikabeMode) SpawnContext(ctx context.Context) (game.Gamer, error) {48 p, err := GenerateWithContext(ctx, n)49 if err != nil {50 return nil, err51 }52 return New(n, p)53}5455func (n NurikabeMode) SpawnSeeded(rng *rand.Rand) (game.Gamer, error) {56 return n.SpawnSeededContext(context.Background(), rng)57}5859func (n NurikabeMode) SpawnSeededContext(ctx context.Context, rng *rand.Rand) (game.Gamer, error) {60 if rng == nil {61 return nil, fmt.Errorf("nil RNG")62 }63 p, err := GenerateSeededWithContext(ctx, n, rng)64 if err != nil {65 return nil, err66 }67 return New(n, p)68}6970var Modes = []game.Mode{71 NewMode("Mini", "5x5 grid, gentle introduction.", 5, 5, 0.28, 5),72 NewMode("Easy", "7x7 grid, balanced logic.", 7, 7, 0.24, 7),73 NewMode("Medium", "9x9 grid, moderate deduction.", 9, 9, 0.20, 9),74 NewMode("Hard", "11x11 grid, lower clue density.", 11, 11, 0.16, 11),75 NewMode("Expert", "12x12 grid, sparse clues and long chains.", 12, 12, 0.14, 12),76}7778var ModeDefinitions = gameentry.BuildModeDefs(Modes)7980var Definition = puzzle.NewDefinition(puzzle.DefinitionSpec{81 Name: "Nurikabe",82 Description: "Split the land while keeping one connected sea.",83 Aliases: []string{"islands", "sea"},84 Modes: ModeDefinitions,85 DailyModeIDs: puzzle.SelectModeIDsByIndex(ModeDefinitions, 1, 2),86})8788var Entry = gameentry.NewEntry(gameentry.EntrySpec{89 Definition: Definition,90 Help: HelpContent,91 Import: game.AdaptImport(ImportModel),92 Modes: Modes,93 Print: PDFPrintAdapter,94})