Add observation_function for full custom control over the observation
Lets a game define how its state becomes an observation as a plain Python function (module:attr), used identically by GameEnvironment (training) and TrainedPolicy (inference) instead of two independently maintained encoding paths. Removes the egocentric/egocentric_player/ egocentric_radius flags — cropping is now something an observation_function does itself by calling egocentric_board(), and extras_size is discovered from one sampled observation instead of being configured via observe_state_sizes.
This commit is contained in:
@@ -64,25 +64,24 @@ def encode_observation(
|
||||
state: dict,
|
||||
metadata: GameMetadata,
|
||||
observe_state: list[str],
|
||||
player_pos: tuple[int, int] | None = None,
|
||||
egocentric_radius: int | None = None,
|
||||
board: bool = True,
|
||||
) -> np.ndarray:
|
||||
"""Encode board and/or selected state values into a flat 1D observation vector.
|
||||
|
||||
When *board* is True the board is encoded and prepended to the vector. If
|
||||
player_pos and egocentric_radius are given the board is first cropped to a
|
||||
(2r+1)×(2r+1) window centred on the player. For spatial games the board is
|
||||
encoded channel-first (C, H, W) then flattened; for non-spatial games it is
|
||||
encoded (H, W, C) then flattened. The state vector is appended at the end.
|
||||
When *board* is True the board is encoded and prepended to the vector. For
|
||||
spatial games the board is encoded channel-first (C, H, W) then flattened;
|
||||
for non-spatial games it is encoded (H, W, C) then flattened. The state
|
||||
vector is appended at the end.
|
||||
|
||||
When *board* is False only the observe_state features are returned.
|
||||
|
||||
For cropped (egocentric) boards, write a custom observation_function that
|
||||
calls egocentric_board() and encode_board() directly instead of using this
|
||||
function.
|
||||
"""
|
||||
if board:
|
||||
if not metadata.character_set:
|
||||
raise ValueError("character_set must be set before encoding observations")
|
||||
if player_pos is not None and egocentric_radius is not None:
|
||||
board_chars = egocentric_board(board_chars, player_pos, egocentric_radius)
|
||||
board_enc = encode_board(board_chars, metadata.character_set) # (H, W, C)
|
||||
if metadata.spatial:
|
||||
board_vec = board_enc.transpose(2, 0, 1).flatten()
|
||||
|
||||
Reference in New Issue
Block a user