numberlink.notebook_viewerΒΆ

Interactive notebook viewer for NumberLink environments.

This module provides a widget based viewer to play and inspect NumberLink puzzles inside Jupyter and Google Colab. It wraps a numberlink.env.NumberLinkRGBEnv instance and exposes keyboard and pointer controls similar to the pygame viewer included elsewhere in the project. Optional notebook dependencies load lazily to keep the base installation light. Install extras with pip install numberlink[notebook] when using the notebook viewer.

The main entry point is numberlink.notebook_viewer.NumberLinkNotebookViewer. To render the viewer in a notebook construct it with a prepared environment and call numberlink.notebook_viewer.NumberLinkNotebookViewer.loop().

Quick start:

from numberlink.env import NumberLinkRGBEnv
from numberlink.notebook_viewer import NumberLinkNotebookViewer

env = NumberLinkRGBEnv((5, 5))
viewer = NumberLinkNotebookViewer(env)
viewer.loop()

See also

numberlink.env.NumberLinkRGBEnv

Primary environment that renders RGB frames and exposes the action space used by the viewer.

Module ContentsΒΆ

ClassesΒΆ

DOMEvent

DOM event payload captured from the notebook front end.

ObserveChange

Change notification payload for ipywidgets observers.

NumberLinkNotebookViewer

Notebook UI for numberlink.env.NumberLinkRGBEnv.

DataΒΆ

APIΒΆ

class numberlink.notebook_viewer.DOMEvent[source]ΒΆ

Bases: typing.TypedDict

DOM event payload captured from the notebook front end.

Events are emitted by ipyevents and forwarded to the viewer. Only fields required by the viewer are represented here. Values follow the browser event model and use the relative coordinate system set on the image widget.

Variables:
  • type (str) – DOM event type name such as "mousedown" or "keydown".

  • buttons (int) – Mouse button bit mask as reported by the browser when the event fired.

  • relativeX (float) – X coordinate relative to the image widget in CSS pixels.

  • relativeY (float) – Y coordinate relative to the image widget in CSS pixels.

  • key (str) – Key value from keyboard events in lower case when available or an empty string.

  • code (str) – Physical key code from keyboard events such as "ArrowUp" or "Numpad5".

  • shiftKey (bool) – Whether the Shift modifier was active.

  • ctrlKey (bool) – Whether the Control modifier was active.

  • altKey (bool) – Whether the Alt modifier was active.

  • button (int) – Primary button identifier for pointer events where buttons may be zero.

Initialization

Initialize self. See help(type(self)) for accurate signature.

type: str = None[source]ΒΆ
buttons: int = None[source]ΒΆ
button: NotRequired[int] = None[source]ΒΆ
relativeX: float = None[source]ΒΆ
relativeY: float = None[source]ΒΆ
key: str = None[source]ΒΆ
code: str = None[source]ΒΆ
shiftKey: bool = None[source]ΒΆ
ctrlKey: bool = None[source]ΒΆ
altKey: bool = None[source]ΒΆ
__contains__()[source]ΒΆ
__delattr__()[source]ΒΆ
__delitem__()[source]ΒΆ
__dir__()[source]ΒΆ
__eq__()[source]ΒΆ
__format__()[source]ΒΆ
__ge__()[source]ΒΆ
__getattribute__()[source]ΒΆ
__getitem__()[source]ΒΆ
__getstate__()[source]ΒΆ
__gt__()[source]ΒΆ
__ior__()[source]ΒΆ
__iter__()[source]ΒΆ
__le__()[source]ΒΆ
__len__()[source]ΒΆ
__lt__()[source]ΒΆ
__ne__()[source]ΒΆ
__new__()[source]ΒΆ
__or__()[source]ΒΆ
__reduce__()[source]ΒΆ
__reduce_ex__()[source]ΒΆ
__repr__()[source]ΒΆ
__reversed__()[source]ΒΆ
__ror__()[source]ΒΆ
__setattr__()[source]ΒΆ
__setitem__()[source]ΒΆ
__sizeof__()[source]ΒΆ
__str__()[source]ΒΆ
__subclasshook__()[source]ΒΆ
clear()[source]ΒΆ
copy()[source]ΒΆ
get()[source]ΒΆ
items()[source]ΒΆ
keys()[source]ΒΆ
pop()[source]ΒΆ
popitem()[source]ΒΆ
setdefault()[source]ΒΆ
update()[source]ΒΆ
values()[source]ΒΆ
class numberlink.notebook_viewer.ObserveChange[source]ΒΆ

Bases: typing.TypedDict

Change notification payload for ipywidgets observers.

This structure mirrors values passed to callback functions registered via observe on widgets. The viewer relies on the new field to determine the updated value for a setting.

Variables:

new (int | str | bytes | None) – New value of the observed trait. May be int, str, bytes or None depending on the widget.

Initialization

Initialize self. See help(type(self)) for accurate signature.

new: int | str | bytes | None = None[source]ΒΆ
__contains__()[source]ΒΆ
__delattr__()[source]ΒΆ
__delitem__()[source]ΒΆ
__dir__()[source]ΒΆ
__eq__()[source]ΒΆ
__format__()[source]ΒΆ
__ge__()[source]ΒΆ
__getattribute__()[source]ΒΆ
__getitem__()[source]ΒΆ
__getstate__()[source]ΒΆ
__gt__()[source]ΒΆ
__ior__()[source]ΒΆ
__iter__()[source]ΒΆ
__le__()[source]ΒΆ
__len__()[source]ΒΆ
__lt__()[source]ΒΆ
__ne__()[source]ΒΆ
__new__()[source]ΒΆ
__or__()[source]ΒΆ
__reduce__()[source]ΒΆ
__reduce_ex__()[source]ΒΆ
__repr__()[source]ΒΆ
__reversed__()[source]ΒΆ
__ror__()[source]ΒΆ
__setattr__()[source]ΒΆ
__setitem__()[source]ΒΆ
__sizeof__()[source]ΒΆ
__str__()[source]ΒΆ
__subclasshook__()[source]ΒΆ
clear()[source]ΒΆ
copy()[source]ΒΆ
get()[source]ΒΆ
items()[source]ΒΆ
keys()[source]ΒΆ
pop()[source]ΒΆ
popitem()[source]ΒΆ
setdefault()[source]ΒΆ
update()[source]ΒΆ
values()[source]ΒΆ
class numberlink.notebook_viewer.NumberLinkNotebookViewer(env: numberlink.env.NumberLinkRGBEnv | gymnasium.Env[numpy.typing.NDArray[numpy.uint8], numpy.int64], cell_size: int = 48)[source]ΒΆ

Notebook UI for numberlink.env.NumberLinkRGBEnv.

Present an image widget with pointer and keyboard interaction so the puzzle can be played and inspected inside a notebook. The viewer supports both path mode and cell switching mode depending on the environment variant configuration exposed by NumberLinkRGBEnv.variant.

The viewer renders frames produced by numberlink.env.NumberLinkRGBEnv._render_rgb() and uses numberlink.env.NumberLinkRGBEnv.step() to apply actions. For cell switching mode it encodes write or clear actions with numberlink.env.NumberLinkRGBEnv.encode_cell_switching_action().

Note

This class requires optional notebook dependencies. Importing or constructing it without the numberlink[notebook] extras raises a RuntimeError with details about the missing module.

Initialization

Initialize the viewer and validate inputs.

Import optional dependencies on demand and normalize the provided environment so that numberlink.env.NumberLinkRGBEnv is available via env. For wrapped Gym environments the underlying unwrapped object must be a numberlink.env.NumberLinkRGBEnv instance or a TypeError is raised.

Parameters:
  • env – Environment to render. Accepts a direct numberlink.env.NumberLinkRGBEnv or a Gym environment that wraps one and exposes it via unwrapped.

  • cell_size – Nominal pixel size per grid cell used to compute image layout. Must be positive. Defaults to 48.

Raises:
  • ValueError – If cell_size is not positive.

  • RuntimeError – If a required optional dependency such as ipyevents or ipywidgets cannot be imported. The error message names the missing module and suggests installing numberlink[notebook].

  • TypeError – If env is neither a numberlink.env.NumberLinkRGBEnv nor a Gym environment that unwraps to one.

loop() None[source]ΒΆ

Display the viewer inside the current notebook cell.

Call this method in a notebook cell to render the widget tree. It refreshes status and frame and then displays _root using IPython.display.display().

Returns:

None

_repr_svg_() str | None[source]ΒΆ

Return SVG preview for rich display in notebooks.

This special method is called by IPython’s display system to show a preview thumbnail when the viewer object is referenced in a notebook cell without calling loop(). It reads and returns the content of the preview SVG asset file.

Returns:

SVG markup as a string or None if the preview file cannot be read.

Return type:

str | None

_compose_layout() None[source]ΒΆ

Compose the widget layout and labels.

Build the color selection row, head selection row, direction pad and utility controls. This method also prepares the help content and replay controls. Call it during initialization before rendering.

Returns:

None

make_button(label: str, size: ipywidgets.widgets.widget_layout.Layout, dr: int, dc: int, *, enabled: bool) ipywidgets.widgets.widget_button.Button[source]ΒΆ

Create a direction button for the direction pad.

The returned button invokes numberlink.notebook_viewer.NumberLinkNotebookViewer._handle_direction() with the provided row and column deltas.

Parameters:
  • label – Text label to display on the button.

  • size – Widget layout for width and height.

  • dr – Row delta applied when clicked.

  • dc – Column delta applied when clicked.

  • enabled – Whether the button is active. Disabled buttons do not fire actions.

Returns:

Configured ipywidgets Button instance.

_build_direction_pad() ipywidgets.widgets.widget_box.GridBox[source]ΒΆ

Build the three by three direction pad.

Creates a grid of directional buttons with optional diagonals depending on NumberLinkRGBEnv.variant.allow_diagonal.

Returns:

ipywidgets GridBox widget containing the direction pad.

Connect widget callbacks to viewer handlers.

Wire widget events like clicks and value changes to methods such as numberlink.notebook_viewer.NumberLinkNotebookViewer._handle_reset() and numberlink.notebook_viewer.NumberLinkNotebookViewer._on_color_change(). Also install replay controls and the help panel toggle behavior.

Returns:

None

_attach_pointer_events() None[source]ΒΆ

Attach mouse or touch event handlers to the image widget.

Register an ipyevents Event to capture pointer activity using the relative coordinate system. The handler forwards events to numberlink.notebook_viewer.NumberLinkNotebookViewer._handle_pointer_event(). Events are configured to prevent default browser behavior and stop propagation to ensure proper interaction in environments like Google Colab where images may be treated as draggable elements by default.

Returns:

None

_attach_keyboard_events() None[source]ΒΆ

Attach keyboard event handlers to the image widget.

The image captures keyboard focus when clicked so arrow keys and shortcuts are delivered to the viewer. Events are handled by numberlink.notebook_viewer.NumberLinkNotebookViewer._handle_key_event().

Returns:

None

_handle_pointer_event(event: numberlink.notebook_viewer.DOMEvent) None[source]ΒΆ

Handle a pointer event from the image widget.

Interpret button presses, drags and clicks to update the cursor in cell mode or to attempt a path step in path mode. Coordinate extraction is delegated to numberlink.notebook_viewer.NumberLinkNotebookViewer._handle_pointer_coordinates().

Parameters:

event – Event payload received from ipyevents.

_handle_key_event(event: numberlink.notebook_viewer.DOMEvent) None[source]ΒΆ

Handle a keyboard event when the image widget has focus.

Support movement keys, digit selection in cell mode, backtracking and utility shortcuts. This method updates the environment through numberlink.env.NumberLinkRGBEnv.step() and refreshes the UI via numberlink.notebook_viewer.NumberLinkNotebookViewer._after_action().

Parameters:

event – Event payload containing key and modifier information.

_handle_pointer_coordinates(event: numberlink.notebook_viewer.DOMEvent) None[source]ΒΆ

Translate pointer coordinates to grid cell actions.

Convert relative CSS pixel coordinates to grid indices using the current pixel per cell information. Depending on the active mode this either moves the cursor and optionally paints a cell or attempts a path step toward the hovered cell.

Parameters:

event – Event payload with relative coordinates.

_handle_direction(dr: int, dc: int) None[source]ΒΆ

Handle a direction input from the pad or keyboard.

Apply the movement deltas depending on the active mode and trigger a UI refresh through numberlink.notebook_viewer.NumberLinkNotebookViewer._after_action().

Parameters:
  • dr – Row delta to apply.

  • dc – Column delta to apply.

_change_color(delta: int) None[source]ΒΆ

Change the selected color by a relative offset and refresh the UI.

Parameters:

delta – Positive or negative offset to apply.

_on_color_change(change: numberlink.notebook_viewer.ObserveChange) None[source]ΒΆ

React to color selector changes and update sel_color when valid.

Parameters:

change – Observe payload from an ipywidgets Dropdown.

_on_head_change(change: numberlink.notebook_viewer.ObserveChange) None[source]ΒΆ

React to changes in the selected head in path mode.

Parameters:

change – Observe payload from ipywidgets ToggleButtons.

_handle_backtrack() None[source]ΒΆ

Backtrack one step for the selected color and head in path mode.

_handle_reset() None[source]ΒΆ

Reset the environment and viewer state then refresh the UI.

_handle_new_level() None[source]ΒΆ

Generate a new level when supported by the environment and refresh the UI.

_handle_paint() None[source]ΒΆ

Paint the currently selected cell in cell switching mode and refresh the UI.

_handle_clear() None[source]ΒΆ

Clear the currently selected cell in cell switching mode and refresh the UI.

_reset_view_state(*, preserve_replay: bool = False) None[source]ΒΆ

Reset viewer local state derived from the environment and clear replay state.

Parameters:

preserve_replay – When True, do not modify the play/pause toggle or replay UI controls. Useful when preparing a replay so we don’t stop playback inadvertently within the same toggle handler.

_can_generate_new_level() bool[source]ΒΆ

Return whether the environment can generate new levels.

_cycle_color(delta: int) None[source]ΒΆ

Advance the selected color with wrap around and do nothing when there are zero colors.

Parameters:

delta – Offset to add to the current selection. Positive or negative values are allowed.

_direction_index(dr: int, dc: int) int | None[source]ΒΆ

Translate a direction vector to an action index or return None when not found.

_attempt_path_step(dr: int, dc: int) None[source]ΒΆ

Attempt a path step in the selected direction if valid.

_backtrack_selected() None[source]ΒΆ

Backtrack one step for the active color and head when possible.

_move_cursor(dr: int, dc: int) None[source]ΒΆ

Move the cursor by (dr, dc) within the grid bounds.

_paint_selected_cell() None[source]ΒΆ

Paint the cell at the cursor with the selected color in cell mode if not already painted.

_clear_selected_cell() None[source]ΒΆ

Clear any path value from the cell at the cursor in cell mode when not an endpoint.

_select_focus_for_cell(row: int, col: int) bool[source]ΒΆ

Select a color and head that best match the given cell and return whether selection changed.

_handle_mouse_cell(row: int, col: int) None[source]ΒΆ

Handle hover at a specific grid cell in path mode and step when adjacent to the active head.

_ensure_color_ready_for_head() None[source]ΒΆ

Ensure the selected color is prepared for drawing with the active head.

Clear the other arm when required to keep the path continuous before the next step.

_reset_environment(seed: int | None = None) None[source]ΒΆ

Reset the environment and reinitialize the viewer, optionally seeding the environment.

_generate_new_level() None[source]ΒΆ

Regenerate the current level when supported by the environment and refresh labels and image.

_after_action() None[source]ΒΆ

Refresh labels and image after an environment action.

_refresh_status() None[source]ΒΆ

Update status indicators, widget states and replay controls.

_refresh_frame() None[source]ΒΆ

Render the latest RGB frame, highlight selection and push it to the image widget.

_on_image_value_change(change: numberlink.notebook_viewer.ObserveChange) None[source]ΒΆ

Update widget properties when image data changes.

_draw_cell_border(frame: numpy.typing.NDArray[numpy.uint8], row: int, col: int, color: RGBInt, thickness: int) None[source]ΒΆ

Draw a rectangular border around a grid cell in the rendered frame.

static _resolve_color(color: RGBInt | None, *, default: RGBInt) RGBInt[source]ΒΆ

Resolve an optional color to an RGB tuple.

Parameters:
  • color – Optional tuple in (R, G, B) order. When None the provided default is used.

  • default – Fallback color in (R, G, B) order used when color is None.

Returns:

Concrete RGB tuple.

_reset_replay_state(*, restore: bool, refresh: bool) None[source]ΒΆ

Clear replay bookkeeping and optionally restore the pre replay snapshot.

_ensure_replay_initialized() bool[source]ΒΆ

Initialize replay state on demand from the environment solution and return readiness.

_on_replay_play_toggled(change: numberlink.notebook_viewer.ObserveChange) None[source]ΒΆ

Handle toggling of the play button to start or pause replay auto-advance.

_start_replay_task() None[source]ΒΆ

Start automatic replay using the Play widget for animation.

_cancel_replay_task() None[source]ΒΆ

Stop the Play widget animation.

_on_play_widget_value_change(change: numberlink.notebook_viewer.ObserveChange) None[source]ΒΆ

Handle Play widget value changes to advance replay step by step.

_replay_step_once() None[source]ΒΆ

Apply a single action from the solution during replay and refresh the frame.

_replay_stop() None[source]ΒΆ

Stop replay and optionally restore the pre replay snapshot before refreshing the UI.

_on_replay_speed_change(change: numberlink.notebook_viewer.ObserveChange) None[source]ΒΆ

Update the replay timer interval from the speed slider.

_snapshot_state() numberlink.types.Snapshot[source]ΒΆ

Capture a snapshot of environment and viewer state for replay restore and return it.

_restore_state(snap: numberlink.types.Snapshot) None[source]ΒΆ

Restore a previously captured snapshot and refresh the UI.

static _build_help_html() str[source]ΒΆ

Build the small help panel content as HTML and return it.

numberlink.notebook_viewer.__all__: list[str] = ['NumberLinkNotebookViewer'][source]ΒΆ