Skip to the content

Tsunagi繋ぎ

Join each pair with a separate line and fill the board, through fixed levels or seeded puzzles.

Tsunagi means joining in Japanese. About the name

Contents

Reference · Rules, solvers and generation

TwistCandidatetype

MAKING TSUNAGI'S TWISTS, on a desk: boards with bridges, and boards with walls and blocked cells (John, 2026-09-26, both chosen from the brainstorm; bridges first). Like generate.ts, only the level script calls this, and a board is kept only when the solver proves it has exactly one answer — the one it was made from.

BRIDGES. A grid is filled with lines as for a plain board. Then, where a line runs straight through a cell away from the edge and two other lines each end on the cells either side of it the other way, those two are joined into one line over the cell, which becomes a bridge: the first line goes over it one way, the joined one the other. Repeated for as many bridges as asked, never two side by side.

WALLS AND BLOCKED CELLS. A few cells are blocked before the grid is filled, so the lines go round them. Where the board then has more than one answer, walls are put on edges between two different lines — never across an edge the answer uses, so its answer stands — until it has one, and then every wall that is not needed for that is taken away again. What is left is walls a player has to use to find the answer.

Import it

import type { TwistCandidate } from "@johnmorrisdotca/tsunagi";

Definition

type TwistCandidate = LinkCandidate & {
    bridges: number;
    walls: number;
    blocked: number;
};

Members

NameTypeDescription
layoutstring
answerstring
pairsnumber
nodesnumber

Positions the solver looked at to prove the answer is the only one.

branchesnumber

Positions where it had to try more than one way: how much guessing the level asks for.

turnsnumber

Turns in the answer's lines, over all of them: how much the lines wind.

keystring

The layout in its one spelling over all eight turns and mirrors, so two levels are never the same board.

bridgesnumber
wallsnumber
blockednumber

Examples

import { TSUNAGI_4 } from "@johnmorrisdotca/tsunagi/levels-4";
import { decodeLayout, symmetryKey, turnsIn } from "@johnmorrisdotca/tsunagi";
import type { TwistCandidate } from "@johnmorrisdotca/tsunagi";

const givens = TSUNAGI_4[0][0];
const answer = TSUNAGI_4[0][1];
const layout = decodeLayout(givens,4)!;
const value: TwistCandidate = {...{layout:givens,answer,pairs:layout.ends.length,nodes:1,branches:0,turns:turnsIn(answer,layout),key:symmetryKey(givens,4)},bridges:0,walls:0,blocked:0};
console.log(value);
{
  layout: 'A..AB..BC..CD..D',
  answer: 'AAAABBBBCCCCDDDD',
  pairs: 4,
  nodes: 1,
  branches: 0,
  turns: 0,
  key: 'A..AB..BC..CD..D',
  bridges: 0,
  walls: 0,
  blocked: 0
}

What it prints (run when this page was built)

View sourceEdit on GitHubMade from the source of @johnmorrisdotca/tsunagi 1.7.0.