rippleeffect

package
v1.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2026 License: MIT Imports: 19 Imported by: 0

README

Ripple Effect

Place digits into irregular cages so each cage contains 1..n exactly once, and matching digits stay outside each other’s ripple distance.

Ripple Effect gameplay

How to Play

Each outlined cage must contain the digits 1..n exactly once, where n is that cage's size. Matching digits also create a "ripple" that blocks the next n-1 cells in the same row and column from containing the same value.

Given cells are fixed. The puzzle is solved when every cell is filled and both the cage and ripple rules are satisfied.

Controls

Key Action
Arrow keys / WASD / hjkl Move cursor
1-9 Place number
Backspace / Delete Clear cell
Ctrl+R Reset puzzle
Ctrl+H Toggle full help
Escape Return to main menu

Modes

Mode Size Notes
Mini 5x5 5x5 Compact cages with extra anchors
Easy 6x6 6x6 Steady clues and approachable spacing
Medium 7x7 7x7 Mixed cage shapes and balanced clue spread
Hard 8x8 8x8 Longer cages with lighter anchoring
Expert 9x9 9x9 Winding large cages and sparse anchors

Quick Start

puzzletea new ripple-effect
puzzletea new ripple "Medium 7x7"
puzzletea new ripple-effect "Hard 8x8" --with-seed sample-seed

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultKeyMap = KeyMap{
	CursorKeyMap: game.DefaultCursorKeyMap,
	FillValue: key.NewBinding(
		key.WithKeys("1", "2", "3", "4", "5", "6", "7", "8", "9"),
		key.WithHelp("1-9", "Fill"),
	),
	Clear: key.NewBinding(
		key.WithKeys("backspace", "delete"),
		key.WithHelp("bkspc", "Clear"),
	),
}
View Source
var Definition = puzzle.NewDefinition(puzzle.DefinitionSpec{
	Name:         "Ripple Effect",
	Description:  "Fill the cages with sequential numbers without violating ripple distance.",
	Aliases:      []string{"ripple"},
	Modes:        ModeDefinitions,
	DailyModeIDs: puzzle.SelectModeIDsByIndex(ModeDefinitions, 1, 2, 3),
})
View Source
var HelpContent string
View Source
var ModeDefinitions = gameentry.BuildModeDefs(Modes)
View Source
var Modes = []game.Mode{
	NewModeWithProfile(
		"Mini 5x5",
		"Compact cages with extra anchors for quick local reads.",
		5,
		3,
		0.69,
		generationProfile{
			cageWeights:     []int{0, 5, 6, 3},
			frontierSamples: 3,
			shapeBias:       shapeBiasCompact,
			minGivensByCage: []int{0, 1, 1, 2},
		},
	),
	NewModeWithProfile(
		"Easy 6x6",
		"Gentle spacing logic with compact cages and steady clues.",
		6,
		3,
		0.64,
		generationProfile{
			cageWeights:     []int{0, 3, 5, 4},
			frontierSamples: 3,
			shapeBias:       shapeBiasCompact,
			minGivensByCage: []int{0, 1, 1, 2},
		},
	),
	NewModeWithProfile(
		"Medium 7x7",
		"Mixed cage shapes with a balanced clue spread.",
		7,
		4,
		0.59,
		generationProfile{
			cageWeights:     []int{0, 2, 4, 5, 3},
			frontierSamples: 2,
			shapeBias:       shapeBiasNeutral,
			minGivensByCage: []int{0, 1, 1, 1, 1},
		},
	),
	NewModeWithProfile(
		"Hard 8x8",
		"Longer cages and lighter anchors create broader ripple scans.",
		8,
		4,
		0.55,
		generationProfile{
			cageWeights:     []int{0, 1, 2, 4, 5},
			frontierSamples: 3,
			shapeBias:       shapeBiasWinding,
			minGivensByCage: []int{0, 1, 1, 1, 1},
		},
	),
	NewModeWithProfile(
		"Expert 9x9",
		"Sparser anchors and winding large cages push global deductions.",
		9,
		5,
		0.51,
		generationProfile{
			cageWeights:     []int{0, 1, 1, 3, 4, 5},
			frontierSamples: 4,
			shapeBias:       shapeBiasWinding,
			minGivensByCage: []int{0, 1, 1, 1, 1, 1},
		},
	),
}
View Source
var PDFPrintAdapter = printAdapter{}

Functions

func New

func New(mode Mode, puzzle Puzzle) (game.Gamer, error)

Types

type Cage

type Cage struct {
	ID    int    `json:"id"`
	Size  int    `json:"size"`
	Cells []Cell `json:"cells"`
}

type Cell

type Cell struct {
	X int `json:"x"`
	Y int `json:"y"`
}

type KeyMap

type KeyMap struct {
	game.CursorKeyMap
	FillValue key.Binding
	Clear     key.Binding
}

type Mode

type Mode struct {
	game.BaseMode
	Size       int
	MaxCage    int
	GivenRatio float64
	// contains filtered or unexported fields
}

func NewMode

func NewMode(title, description string, size, maxCage int, givenRatio float64) Mode

func NewModeWithProfile added in v1.8.0

func NewModeWithProfile(title, description string, size, maxCage int, givenRatio float64, profile generationProfile) Mode

func (Mode) Spawn

func (m Mode) Spawn() (game.Gamer, error)

func (Mode) SpawnSeeded

func (m Mode) SpawnSeeded(rng *rand.Rand) (game.Gamer, error)

type Model

type Model struct {
	// contains filtered or unexported fields
}

func ImportModel

func ImportModel(data []byte) (*Model, error)

func (Model) GetDebugInfo

func (m Model) GetDebugInfo() string

func (Model) GetFullHelp

func (m Model) GetFullHelp() [][]key.Binding

func (Model) GetSave

func (m Model) GetSave() ([]byte, error)

func (Model) Init

func (m Model) Init() tea.Cmd

func (Model) IsSolved

func (m Model) IsSolved() bool

func (Model) Reset

func (m Model) Reset() game.Gamer

func (Model) SetTitle

func (m Model) SetTitle(t string) game.Gamer

func (Model) Update

func (m Model) Update(msg tea.Msg) (game.Gamer, tea.Cmd)

func (Model) View

func (m Model) View() string

type Puzzle

type Puzzle struct {
	Width    int
	Height   int
	Cages    []Cage
	Givens   grid
	Solution grid
}

func GeneratePuzzle

func GeneratePuzzle(width, height, maxCage int, givenRatio float64) (Puzzle, error)

func GeneratePuzzleSeeded

func GeneratePuzzleSeeded(width, height, maxCage int, givenRatio float64, rng *rand.Rand) (Puzzle, error)

type Save

type Save struct {
	Width     int    `json:"width"`
	Height    int    `json:"height"`
	State     string `json:"state"`
	Givens    string `json:"givens"`
	Cages     []Cage `json:"cages"`
	ModeTitle string `json:"mode_title"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL