env.encoder
env.encoder
Encode a BoardView into a (26, 2, 12) tensor for the neural network.
Functions
| Name | Description |
|---|---|
| channels_for_network | Channel indices a network expects at inference, from its checkpoint config. |
| contact_pips | Pips each side must travel before contact is impossible. |
| decode_base_planes | Invert the base planes of an encoded observation back to a BoardView. |
| dump_tensor | Render the encoder output for a position as a human-readable string. |
| encode_batch | Encode multiple board positions. Returns shape (N, C, 2, 12). |
| encode_state | Encode a board position as a (C, 2, 12) float32 tensor. |
| resolve_channels | Map a list of feature-group names to sorted channel indices. |
channels_for_network
env.encoder.channels_for_network(config)Channel indices a network expects at inference, from its checkpoint config.
Newer checkpoints store feature_channels directly (the subset chosen at training time). Legacy checkpoints (pre Stage-6) store only in_channels: NUM_CHANNELS (26) is the full Fix-N encoder (None = all channels) and 17 is base-only (no handcrafted features). Any other count is ambiguous and raises. The result is in the form encode_state(..., channels=...) wants, so callers can encode observations that match an arbitrary checkpoint — notably the 17-channel v5/iter_0447 nets now that the encoder defaults to 26.
contact_pips
env.encoder.contact_pips(board_view)Pips each side must travel before contact is impossible.
my_contact = Σ my_pts[i] × max(0, i - min_opp + 1) + my_bar × (25 - min_opp) and symmetrically for the opponent, where min_opp is the opponent’s least-advanced position and max_my my most-advanced one. Checkers on the bar re-enter in the far home board, so they count as maximally contacted: opp_bar > 0 forces min_opp = 0 and my_bar > 0 forces max_my = 23.
Both values are 0.0 exactly once the sides have passed each other — a pure race. The opening position gives my_contact = 167, the full pip count, which is where the /167 normalisation in :data:FEATURE_SCALES comes from; a position with checkers on the bar can exceed it, so callers using this as a [0, 1] dial should clip.
Feeds channels 24/25 of :func:encode_state, and is public so that search can read contact without building a whole (26, 2, 12) tensor (raccoon/search/expectimax.py sizes its filter window from it).
decode_base_planes
env.encoder.decode_base_planes(obs)Invert the base planes of an encoded observation back to a BoardView.
The 17 base channels are lossless: exact checker counts live in the overflow plane ((count-3)/2), bar/off/dice in the broadcast planes. obs may be a base-only (17, 2, 12) tensor or a full (26, 2, 12) one — the handcrafted channels are ignored either way (they are derived quantities). This is what lets stored 17-channel caches be re-encoded to the full Fix-N encoder without re-labeling.
dump_tensor
env.encoder.dump_tensor(board_view, *, precision=3)Render the encoder output for a position as a human-readable string.
Pure debug helper: encodes board_view and pretty-prints each of the NUM_CHANNELS planes alongside a short header. Planes whose 24 cells are all equal are collapsed to a single scalar with a (broadcast) tag — this is detected from the tensor itself, not assumed by index.
encode_batch
env.encoder.encode_batch(board_views, channels=None, normalize=True)Encode multiple board positions. Returns shape (N, C, 2, 12).
channels selects a channel subset (see encode_state); None yields the full 26-channel tensor. normalize (default True) rescales the handcrafted channels into the base planes’ range (see encode_state).
encode_state
env.encoder.encode_state(board_view, channels=None, normalize=True)Encode a board position as a (C, 2, 12) float32 tensor.
Board layout: Top row (row 0): perspective points 13..24 -> columns 0..11 Bottom row (row 1): perspective points 12..1 -> columns 0..11
Channel meanings live in CHANNEL_NAMES so the audit/debug tooling and the encoder can’t drift apart.
All NUM_CHANNELS planes are always computed; channels (a list of channel indices, e.g. from resolve_channels) optionally selects a subset, returning a (len(channels), 2, 12) tensor. None returns the full 26-channel tensor.
normalize (default True, i.e. Fix-N) divides the handcrafted feature channels by FEATURE_SCALES so they share the base planes’ ~[0, 1] range; the base channels are untouched. Applied before any channel slicing. Pass normalize=False to recover the raw magnitudes (the pre-Stage-6 behaviour; needed for feature-math tests and for the Fix-B input-BatchNorm path, which standardises raw inputs itself).
resolve_channels
env.encoder.resolve_channels(features)Map a list of feature-group names to sorted channel indices.
features=None (or a list containing "all") selects every channel, so existing callers that pass nothing are unaffected. "base" is always included. An empty list selects base-only. Unknown group names raise.