Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ src/domain/diagnostics/
*.sln
*.sw?
Puzzlink_Assistance.js
docs/legacy/*
docs/legacy/*
.plugin/
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ The goal is not only to produce a final answer. The app shows each deduction ste

- Runs entirely in the browser.
- Imports Slitherlink and Masyu puzzles from puzz.link-compatible URLs and Penpa+ URLs.
- Provides an explainable solver workspace with step replay, highlights, rule messages, and live stats.
- Provides an explainable solver workspace with step replay, highlights, rule messages, strong-inference branch inspection, and live stats.
- Provides an editor workspace for building Slitherlink and Masyu boards, importing URLs, and loading the result into the solver.
- Provides a small Dataset page for curated examples and benchmark-oriented puzzle sets.
- Exports supported puzzle states back to puzz.link-style URLs where available.
- Opens canonical puzz.link payloads directly in Solver through shareable deep links.

Slitherlink has the more mature rule stack. Masyu is now a first-class puzzle family with editor, import/export, rendering, replay, completion analysis, and an actively evolving solver.

Expand Down Expand Up @@ -44,9 +45,22 @@ pnpm benchmark:solve

## App Surfaces

- **Solver** (`/`): import a puzzle, run one deduction at a time, jump through the replay timeline, inspect explanations, view stats, and export supported states.
- **Solver** (`/`): import a puzzle, run one deduction at a time, jump through the replay timeline, inspect explanations and strong-inference branches, view stats, and export supported states.
- **Editor** (`/editor`): create custom Slitherlink or Masyu grids, edit clues/pearls and marks, import supported URLs, then hand the puzzle to the solver.
- **Dataset** (`/dataset`): browse curated public dataset manifests, preview puzzles, and load them into Solver or Editor.
- **Docs** (`/docs`): browse puzzle-family rule documentation and open the explanation for any solver step.

## Solver Deep Links

Solver accepts canonical puzz.link-compatible payloads through the `p` query parameter:

```text
https://smilingwayne.github.io/puzzlekit-web/?p=slither/10/10/...
https://smilingwayne.github.io/puzzlekit-web/?p=mashu/14/8/...
```

Deep links support the compact `slither/...` and `mashu/...` payload forms only. Full puzz.link,
pzplus, pzv, and Penpa+ URLs remain supported through the existing manual URL import controls.

## Architecture Snapshot

Expand All @@ -60,6 +74,7 @@ dataset/
public/ small committed dataset manifests
private/ local-only manifests ignored by git
docs/
content/ in-app MDX rule documentation
techniques/ puzzle-specific technique notes
```

Expand Down
503 changes: 503 additions & 0 deletions dataset/public/masyu.json

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions docs/MASYU_AGENT_BRIEF.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ Masyu is a first-class puzzle family with:
- Penpa+ import.
- Solver rendering, replay, explanations, stats, legend/help content, and completion analysis.
- Editor support for blank custom grids, URL import, black/white pearl placement, and load-to-solver flow.
- Deterministic rules plus bounded, explainable strong-inference rules.
- Deterministic rules plus bounded strong-inference rules with branch replay and contradiction focus.
- Tile-color topology support for inside/outside reasoning.

Public Masyu dataset manifests are not yet committed to `dataset/public`; use private manifests for local experiments until curated public examples are added.
A categorized Masyu manifest is committed to `dataset/public`; use private manifests for additional local experiments.

## Canonical Model

Expand All @@ -40,7 +40,8 @@ Implemented rule areas include:
- Candidate bridge reasoning and pearl candidate pruning.
- Adjacent white pearl lookahead.
- Tile color propagation, color-line implications, color-pearl implications, and connectivity cut coloring.
- Bounded strong inference for black pearls, white pearls, and empty cells.
- Bounded strong inference for black pearls, confirmed-line component endpoints,
and white pearls.

Default expectation: deterministic rules run first, then bounded strong-inference rules reuse the deterministic rule list for local propagation.

Expand All @@ -59,22 +60,23 @@ Use these files first:
- Lookahead helpers: `src/domain/rules/masyu/rules/lookahead*.ts`
- Masyu parser/exporter: `src/domain/parsers/puzzlink/masyuPuzzlink.ts`, `src/domain/parsers/penpa/index.ts`
- Masyu editor: `src/features/editor/MasyuEditorBoard.tsx`, `src/features/editor/editorStore.ts`
- Tests: `src/domain/rules/masyu/rules.test.ts`, `src/domain/ir/masyu.test.ts`, parser tests
- Tests: `src/domain/rules/masyu/tests/`, `src/domain/rules/masyu/completion.test.ts`, `src/domain/ir/masyu.test.ts`, parser tests

Replay and rendering plumbing:

- Rule diffs: `src/domain/rules/types.ts`
- Diff application: `src/domain/rules/engine.ts`
- Solver timeline/checkpoints: `src/features/solver/solverStore.ts`
- Board rendering: `src/features/board/CanvasBoard.tsx`
- Strong-inference inspection: `src/features/explanation/BranchInspector.tsx`

## Development Direction

Near-term Masyu work should favor small, maintainable rule improvements over broad rewrites:

- Consolidate repeated line, tile, candidate, and graph primitives when duplication becomes costly.
- Prefer named deterministic rules before adding broader assumption search.
- Keep bounded inference explainable through contradiction or common-conclusion messages.
- Keep bounded inference explainable through structured trial traces, contradiction focus, and formal conclusions.
- Add focused fixture tests whenever a rule changes.

Historical Masyu planning notes live under `docs/legacy/`. They are reference material, not the current source of truth.
Expand All @@ -90,7 +92,7 @@ Historical Masyu planning notes live under `docs/legacy/`. They are reference ma
Useful commands:

```bash
pnpm test:run src/domain/rules/masyu/rules.test.ts
pnpm test:run src/domain/rules/masyu/tests
pnpm test:run src/domain/rules/engine.test.ts src/features/solver/solverStore.test.ts
pnpm build
```
Expand Down
14 changes: 11 additions & 3 deletions docs/PROJECT_GUIDE_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dataset/
scripts/
benchmark-solve.ts
docs/
content/ # in-app MDX rule documentation
techniques/ # puzzle-specific technique notes
legacy/ # old plans and research notes
```
Expand All @@ -57,6 +58,11 @@ Boundary rule:

This contract is central: solver output must remain deterministic, replay-safe, and explainable.

Bounded inference steps may also store structured branch details: the base
puzzle, initial branch diffs, trial trace, contradiction focus, and formal
conclusion. The shared Branch Inspector replays these details for Slitherlink
and Masyu without changing solver behavior.

## 4. Plugin Contract

Puzzle families are registered in `src/domain/plugins/registry.ts`.
Expand All @@ -69,6 +75,7 @@ Each `PuzzlePlugin` may provide:
- `help` for the puzzle rules popout.
- `legend` for board legend examples.
- `getStats(puzzle)` for compact board-title stats.
- `liveStats` for puzzle-specific inference coverage series shown in the shared Live Stats panel.
- `displayOptions` for puzzle-specific board toggles.

Current families:
Expand Down Expand Up @@ -105,16 +112,17 @@ Implemented:
- Editor workspace for Slitherlink and Masyu custom boards, URL import, and load-to-solver flow.
- Dataset page with filters, previews, and load-to-Solver/Editor actions.
- Plugin-powered rules help, board legend, board display toggles, and compact puzzle stats.
- In-app rule documentation generated from the production rule registry, with stable rule deep links and read-only Canvas examples.
- Slitherlink puzz.link-compatible parse/encode, Penpa+ import, deterministic rules, branch-based inference, completion analysis, editor tools, and public dataset example.
- Masyu puzz.link-compatible parse/encode, Penpa+ import, renderer, editor, deterministic rules, completion analysis, tile-color propagation, candidate pruning, bridge reasoning, premature-loop prevention, and bounded strong inference.
- Masyu puzz.link-compatible parse/encode, Penpa+ import, renderer, editor, deterministic rules, completion analysis, tile-color propagation, candidate pruning, bridge reasoning, premature-loop prevention, and inspectable bounded strong inference.
- Public/private benchmark manifest workflow.
- GitHub Pages release workflow for tagged builds.

Partial or planned:

- Public Masyu dataset manifests are not yet committed to `dataset/public`.
- The public dataset includes a categorized Masyu manifest.
- Penpa+ support is import-oriented; export completeness is not a current guarantee.
- Puzzle-specific Live Stats wording can still be refined.
- Live Stats uses a shared timeline, step-duration chart, and rule-usage view. Each puzzle plugin declares the meaningful inference coverage series for its own IR primitives.
- Difficulty modeling is draft-level.
- Nonogram remains planned.

Expand Down
12 changes: 12 additions & 0 deletions docs/content/masyu/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Puzzle rules

Masyu asks for one continuous loop that passes through every pearl. The loop
turns on black pearls and continues straight in both neighboring cells. It
passes straight through white pearls and turns in at least one neighboring
cell.

## Solver techniques

PuzzleKit combines direct pearl rules, local patterns, candidate pruning,
inside/outside tile coloring, connectivity checks, and bounded strong
inference. Each technique below is a real rule registered in the solver.
25 changes: 25 additions & 0 deletions docs/content/masyu/rules/black-pearl-rule.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## What this technique does

A black pearl must be a turn in the loop. Each of the two exits from the pearl
must continue straight through the next cell.

## Trigger conditions

The technique acts when an exit is known, a direction is blocked, or only one
valid turning pair remains.

## Conclusions

It can force the required straight extensions, cross out an opposite exit, or
complete the only remaining turn around the pearl.

## Why it works

Using opposite exits would pass straight through the black pearl. Turning away
immediately in a neighboring cell would violate the required straight
continuation.

## Limits and related techniques

This technique checks direct pearl geometry. Black Pearl Candidate Pruning
combines that geometry with broader local feasibility checks.
25 changes: 25 additions & 0 deletions docs/content/masyu/rules/white-pearl-rule.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## What this technique does

A white pearl must be crossed by a straight section of the loop. The loop must
also turn in at least one of the cells immediately before or after the pearl.

## Trigger conditions

The technique acts when a known line, blocked direction, or impossible adjacent
turn leaves only one valid straight axis through the pearl.

## Conclusions

It can force the opposite line through the pearl, cross out perpendicular exits,
or reject a straight continuation that would make the required nearby turn
impossible.

## Why it works

Any alternative would either turn on the white pearl or continue straight on
both adjacent cells. Both outcomes violate the puzzle's white-pearl rule.

## Limits and related techniques

This is local deterministic reasoning. Candidate pruning and strong inference
can resolve cases where more than one locally valid axis remains.
12 changes: 12 additions & 0 deletions docs/content/slitherlink/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Puzzle rules

Slitherlink asks for one continuous loop along grid edges. A numbered cell
states how many of its four surrounding edges belong to the loop. The loop
cannot branch, cross itself, or split into multiple loops.

## Solver techniques

PuzzleKit combines clue and vertex completion, local patterns, sector
constraints, inside/outside coloring, connectivity checks, and bounded
inference. Each technique below is linked by the same stable ID used in the
solver trace.
25 changes: 25 additions & 0 deletions docs/content/slitherlink/rules/vertex-degree.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## What this technique does

Every Slitherlink vertex belongs to either zero or two loop edges. A vertex may
never become a dead end or a branch.

## Trigger conditions

The technique acts when the decided edges around a vertex determine the
remaining unknown edges.

## Conclusions

If two lines already meet at a vertex, every other incident edge is crossed out.
If one line and only one unknown edge remain, that unknown edge is forced.
If no lines and only one unknown edge remain, it is crossed out.

## Why it works

A single used edge creates a dead end, while three or more used edges create a
branch. Neither can be part of one continuous loop.

## Limits and related techniques

This rule enforces local degree only. Prevent Premature Loop and connectivity
rules handle larger loop structure.
37 changes: 24 additions & 13 deletions docs/techniques/masyu.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,14 @@ contradictions include:
- tile-color parity conflicts;
- assumptions that conflict with already decided lines.

When a strong-inference step is selected in the reasoning panel, its Branch
Inspector replays the rejected assumption from the base puzzle through each
deterministic trial step to the contradiction. The inspector also provides a
separate **Forced conclusion** tab showing the real deduction produced by the
proof by contradiction. This conclusion tab is visual only: the solver does not
run an additional trial branch, so existing inference budgets and behavior stay
unchanged.

### Black Pearl Strong Inference

For a black pearl, the solver assumes one possible exit direction together with
Expand All @@ -375,6 +383,22 @@ crossed out in the real puzzle.

This rule determines crossed-out line segments.

### Line Component Endpoint Strong Inference

For each open component of confirmed lines, the solver examines its two
degree-1 endpoints. Endpoints with fewer remaining directions are tested first,
followed by endpoints belonging to longer components.

For one candidate direction, the solver assumes that the component continues in
that direction and that the endpoint's other unknown exits are crossed out. If
deterministic propagation reaches a contradiction, that candidate direction is
crossed out in the real puzzle. Pearl cells may be component endpoints, but the
dedicated black-pearl strong-inference rule runs first.

Because component endpoints are already high-value candidates, this rule uses a
tighter default candidate and elapsed-time cap than the broader strong-inference
rules.

### White Pearl Strong Inference

For a white pearl with exactly two feasible straight-axis candidates, the solver
Expand All @@ -385,16 +409,3 @@ forced in the real puzzle.

This rule determines the confirmed lines and crossed-out lines belonging to the
forced white-pearl axis.

### Empty Cell Strong Inference

For a non-pearl cell, the solver can test bounded degree choices when the local
state has either one known line with exactly two unknown exits, or no known lines
with exactly two unknown exits.

In the degree-1 case, it assumes each possible continuation in turn. If one
continuation reaches a contradiction, the other continuation is forced.

In the degree-0 case, it tests the two local modes: both exits are used, or both
exits are crossed out. If one mode reaches a contradiction, the other mode is
forced in the real puzzle.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>web</title>
<title>PuzzKit Web</title>
</head>
<body>
<div id="root"></div>
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"prepare": "husky"
},
"dependencies": {
"@mdx-js/react": "^3.1.1",
"fflate": "^0.8.2",
"react": "^19.2.4",
"react-dom": "^19.2.4",
Expand All @@ -25,6 +26,7 @@
},
"devDependencies": {
"@eslint/js": "^9.39.4",
"@mdx-js/rollup": "^3.1.1",
"@playwright/test": "^1.59.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
Expand Down
Loading
Loading