clone

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

bug/architecture-test-trim-path
puzzletea / games / hitori / gamemode.go
gamemode.go 2.4K
1package hitori23import (4 _ "embed"5 "math/rand/v2"67 "github.com/FelineStateMachine/puzzletea/difficulty"8 "github.com/FelineStateMachine/puzzletea/game"9 "github.com/FelineStateMachine/puzzletea/gameentry"10 "github.com/FelineStateMachine/puzzletea/puzzle"11)1213//go:embed help.md14var HelpContent string1516type HitoriMode struct {17 game.BaseMode18 Size int19 BlackRatio float6420}2122var (23 _ game.Mode = HitoriMode{}24 _ game.Spawner = HitoriMode{}25 _ game.SeededSpawner = HitoriMode{}26 _ game.EloSpawner = HitoriMode{}27)2829func NewMode(title, desc string, size int, blackRatio float64) HitoriMode {30 return HitoriMode{31 BaseMode: game.NewBaseMode(title, desc),32 Size: size,33 BlackRatio: blackRatio,34 }35}3637func (h HitoriMode) Spawn() (game.Gamer, error) {38 puzzle, err := Generate(h.Size, h.BlackRatio)39 if err != nil {40 return nil, err41 }42 return New(h, puzzle)43}4445func (h HitoriMode) SpawnSeeded(rng *rand.Rand) (game.Gamer, error) {46 puzzle, err := GenerateSeeded(h.Size, h.BlackRatio, rng)47 if err != nil {48 return nil, err49 }50 return New(h, puzzle)51}5253var Modes = []game.Mode{54 NewMode("Mini", "5\u00d75 grid, gentle introduction.", 5, 0.32),55 NewMode("Easy", "6\u00d76 grid, straightforward logic.", 6, 0.32),56 NewMode("Medium", "8\u00d78 grid, moderate challenge.", 8, 0.30),57 NewMode("Tricky", "9\u00d79 grid, requires careful deduction.", 9, 0.30),58 NewMode("Hard", "10\u00d710 grid, advanced logic chains.", 10, 0.30),59 NewMode("Expert", "12\u00d712 grid, maximum challenge.", 12, 0.28),60}6162var ModeDefinitions = hitoriModeDefinitions(Modes)6364func hitoriModeDefinitions(modes []game.Mode) []puzzle.ModeDef {65 defs := gameentry.BuildModeDefs(modes)66 presets := []difficulty.Elo{300, 700, 1300, 1800, 2300, 2800}67 for i, mode := range modes {68 if i >= len(defs) || i >= len(presets) {69 break70 }71 if _, ok := mode.(game.EloSpawner); !ok {72 continue73 }74 elo := presets[i]75 defs[i].PresetElo = &elo76 }77 return defs78}7980var Definition = puzzle.NewDefinition(puzzle.DefinitionSpec{81 Name: "Hitori",82 Description: "Shade the cells to eliminate duplicates.",83 Modes: ModeDefinitions,84 DailyModeIDs: puzzle.SelectModeIDsByIndex(ModeDefinitions, 1, 2),85})8687var Entry = gameentry.NewEntry(gameentry.EntrySpec{88 Definition: Definition,89 Help: HelpContent,90 Import: game.AdaptImport(ImportModel),91 Modes: Modes,92 Print: PDFPrintAdapter,93})