nurikabe

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: 24 Imported by: 0

README

Nurikabe

Build islands from numbered clues while keeping the sea connected.

How to Play

Each number is an island clue. Mark cells as island or sea until all rules are true:

  1. Every island contains exactly one clue.
  2. Island size equals clue value.
  3. All sea cells are one connected region.
  4. No 2x2 sea block is allowed.

Clue cells are fixed and always island cells. Once every sea cell is marked, any remaining undecided non-sea cells count as island for completion.

Controls

Key Action
Arrow keys / WASD / hjkl Move cursor
x Set sea
z Set island
Backspace Clear to unknown
Ctrl+R Reset puzzle
Ctrl+H Toggle full help
Escape Return to main menu

Mouse

Action Effect
Left click Move cursor, or set sea on the current cell
Left drag Paint sea from the current cell
Right click / drag Set island cells

Modes

Mode Grid Description
Mini 5x5 Gentle introduction
Easy 7x7 Balanced logic
Medium 9x9 Moderate deduction
Hard 11x11 Lower clue density
Expert 12x12 Sparse clues and longer chains

Quick Start

puzzletea new nurikabe mini
puzzletea new nurikabe medium
puzzletea new nurikabe expert
puzzletea new islands easy       # alias

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultKeyMap = KeyMap{
	CursorKeyMap: game.DefaultCursorKeyMap,
	SetSea: key.NewBinding(
		key.WithKeys("x"),
		key.WithHelp("x", "Sea"),
	),
	SetIsland: key.NewBinding(
		key.WithKeys("z"),
		key.WithHelp("z", "Island"),
	),
	Clear: key.NewBinding(
		key.WithKeys("backspace", "delete"),
		key.WithHelp("bkspc", "Clear"),
	),
}
View Source
var Definition = puzzle.NewDefinition(puzzle.DefinitionSpec{
	Name:         "Nurikabe",
	Description:  "Split the land while keeping one connected sea.",
	Aliases:      []string{"islands", "sea"},
	Modes:        ModeDefinitions,
	DailyModeIDs: puzzle.SelectModeIDsByIndex(ModeDefinitions, 1, 2),
})
View Source
var HelpContent string
View Source
var ModeDefinitions = gameentry.BuildModeDefs(Modes)
View Source
var Modes = []game.Mode{
	NewMode("Mini", "5x5 grid, gentle introduction.", 5, 5, 0.28, 5),
	NewMode("Easy", "7x7 grid, balanced logic.", 7, 7, 0.24, 7),
	NewMode("Medium", "9x9 grid, moderate deduction.", 9, 9, 0.20, 9),
	NewMode("Hard", "11x11 grid, lower clue density.", 11, 11, 0.16, 11),
	NewMode("Expert", "12x12 grid, sparse clues and long chains.", 12, 12, 0.14, 12),
}
View Source
var PDFPrintAdapter = printAdapter{}

Functions

func New

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

Types

type KeyMap

type KeyMap struct {
	game.CursorKeyMap
	SetSea    key.Binding
	SetIsland key.Binding
	Clear     key.Binding
}

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 NurikabeMode

type NurikabeMode struct {
	game.BaseMode
	Width         int
	Height        int
	ClueDensity   float64
	MaxIslandSize int
}

func NewMode

func NewMode(title, desc string, width, height int, clueDensity float64, maxIslandSize int) NurikabeMode

func (NurikabeMode) Spawn

func (n NurikabeMode) Spawn() (game.Gamer, error)

func (NurikabeMode) SpawnContext

func (n NurikabeMode) SpawnContext(ctx context.Context) (game.Gamer, error)

func (NurikabeMode) SpawnSeeded

func (n NurikabeMode) SpawnSeeded(rng *rand.Rand) (game.Gamer, error)

func (NurikabeMode) SpawnSeededContext

func (n NurikabeMode) SpawnSeededContext(ctx context.Context, rng *rand.Rand) (game.Gamer, error)

type Puzzle

type Puzzle struct {
	Width, Height int
	Clues         clueGrid
}

func Generate

func Generate(mode NurikabeMode) (Puzzle, error)

func GenerateSeeded

func GenerateSeeded(mode NurikabeMode, rng *rand.Rand) (Puzzle, error)

func GenerateSeededWithContext

func GenerateSeededWithContext(ctx context.Context, mode NurikabeMode, rng *rand.Rand) (Puzzle, error)

func GenerateWithContext

func GenerateWithContext(ctx context.Context, mode NurikabeMode) (Puzzle, error)

type Save

type Save struct {
	Width     int    `json:"width"`
	Height    int    `json:"height"`
	Clues     string `json:"clues"`
	Marks     string `json:"marks"`
	ModeTitle string `json:"mode_title"`
}

type SolveStats

type SolveStats struct {
	Nodes    int
	Branches int
	MaxDepth int
}

func CountSolutions

func CountSolutions(puzzle Puzzle, limit, nodeLimit int) (int, SolveStats, error)

func CountSolutionsContext

func CountSolutionsContext(ctx context.Context, puzzle Puzzle, limit, nodeLimit int) (int, SolveStats, error)

Jump to

Keyboard shortcuts

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