hisss.BattleSnakeGame

Contents

hisss.BattleSnakeGame#

class hisss.BattleSnakeGame(cfg, state_p=None)[source]#

Bases: object

Battlesnake game environment backed by a C++ simulation engine.

Wraps a heap-allocated C++ GameState object. Always call close() when the environment is no longer needed — or use it as a context manager — to free the underlying C++ memory. __del__() provides a fallback but is not guaranteed to run promptly.

cfg#

Game configuration used to create this environment.

turns_played#

Number of turns elapsed since the last reset().

is_closed#

Whether close() has already been called.

layer_explanation#

Mapping from channel name to index in the observation tensor returned by get_obs().

__init__(cfg, state_p=None)[source]#

Initialise a new BattleSnakeGame.

Parameters:
  • cfg (BattleSnakeConfig) – Configuration dataclass that controls board size, number of players, food rules, game mode, encoding, and rewards.

  • state_p – Optional pre-existing C++ game-state pointer. When None (the default) a fresh game is created from cfg. Pass an existing pointer only when cloning an environment internally.

Note

post_init_battlesnake_cfg() and validate_battlesnake_cfg() are called automatically when state_p is None.

Methods

__init__(cfg[, state_p])

Initialise a new BattleSnakeGame.

all_player_pos()

Return body positions for every snake.

area_control([weight, food_weight, ...])

available_actions(player)

Return the legal action indices for player in the current state.

available_joint_actions()

Return every legal combination of actions for all players currently at turn.

close()

Free the underlying C++ game-state object.

food_pos()

Return the coordinates of all food items on the board.

food_spawn_turns()

Return the turn each food item spawned, in the same order as food_pos().

get_bool_board_matrix()

Return the board occupancy matrix (constrictor mode only).

get_copy()

Return an independent deep copy of this environment.

get_cum_rewards()

Return the cumulative rewards accumulated since the last reset().

get_hazards()

Return a boolean array indicating hazard tiles.

get_last_action()

Alias for get_last_actions().

get_last_actions()

Return the joint action that was passed to the most recent step().

get_obs([symmetry])

Return observation tensors for all players currently at turn.

get_obs_shape([never_flatten])

Return the shape of a single-player observation tensor.

get_state()

Capture the current game state as a serialisable snapshot.

get_str_repr()

Return an ASCII string representation of the current board.

get_symmetry_count()

Return the total number of distinct board symmetries.

illegal_actions(player)

Return the action indices that are illegal for player.

illegal_joint_actions()

Return every joint-action combination that is not fully legal.

is_player_alive(player)

Return whether player is still alive.

is_player_at_turn(player)

Return whether player must provide an action this turn.

is_terminal()

Return whether the game has ended.

num_food()

Return the number of food items currently on the board.

num_players_alive()

Return the number of players that are still alive.

num_players_at_turn()

Return the number of players who must act this turn.

play_random_steps(steps)

Advance the game by up to steps turns using uniformly random actions.

player_healths()

Return the current health value of each snake.

player_lengths()

Return the length (number of segments) of each snake.

player_pos(player)

Return the body positions of player's snake as (x, y) tuples.

players_alive()

Return the indices of all living players.

players_at_turn()

Return the indices of all players that must act this turn.

players_not_alive()

Return the indices of all dead (eliminated) players.

render()

Print an ASCII representation of the current board to stdout.

reset()

Reinitialise the game to its starting state.

reset_saved_properties()

Clear all intra-turn caches (observations, available actions, player lists).

set_cum_rewards(cum_rewards)

Override the cumulative rewards array.

set_last_actions(last_actions)

Override the recorded last-step joint action.

set_state(state)

Restore the game to a previously captured state.

step(actions)

Advance the game by one turn.

Attributes

num_actions

UP, RIGHT, DOWN, LEFT).

num_players

Total number of players (snakes) in this game, including dead ones.

all_player_pos()[source]#

Return body positions for every snake.

This method calls into C++ for each alive snake and should only be used for debugging or infrequent queries.

Return type:

dict[int, list[tuple[int, int]]]

Returns:

Dict mapping player index to a list of (x, y) tuples (head first). Dead players map to an empty list.

Raises:

ValueError – If the game is closed.

area_control(weight=1.0, food_weight=1.0, hazard_weight=1.0, food_in_hazard_weight=1.0)[source]#
Parameters:
  • () (food_in_hazard_weight) – weight of normal tile

  • () – weight of food tile

  • () – weight of hazard tile

  • () – weight of hazard tile that contains food

Returns:

  • area control for each player

  • food distance for each player (w+h if not reachable)

  • tail distance for each player (w+h if not reachable)

  • bool array indicating if tail is reachable for each player

  • bool array indicating if food is reachable for each player

Return type:

dict[str, ndarray]

available_actions(player)[source]#

Return the legal action indices for player in the current state.

Results are cached for the lifetime of the current turn.

Parameters:

player (int) – Zero-based player index.

Return type:

list[int]

Returns:

List of legal action indices. Returns an empty list if the player is dead.

Raises:

ValueError – If the game is closed or player is out of range.

available_joint_actions()[source]#

Return every legal combination of actions for all players currently at turn. Legal actions may be restricted by actions that would lead to a certain death, depending on the game configuration.

Return type:

list[tuple[int, ...]]

Returns:

List of tuples, one entry per player at turn. Each tuple element is an action index for the corresponding player returned by players_at_turn().

close()[source]#

Free the underlying C++ game-state object.

Must be called when the environment is no longer needed to avoid memory leaks. Calling any other method after close() will raise a ValueError.

food_pos()[source]#

Return the coordinates of all food items on the board.

Return type:

ndarray

Returns:

Integer array of shape (num_food, 2) where each row is [x, y].

Raises:

ValueError – If the game is closed.

food_spawn_turns()[source]#

Return the turn each food item spawned, in the same order as food_pos().

Return type:

ndarray

Returns:

Integer array of shape (num_food,) where each element is the turn the corresponding food item first appeared on the board.

Raises:

ValueError – If the game is closed.

get_bool_board_matrix()[source]#

Return the board occupancy matrix (constrictor mode only).

Return type:

ndarray

Returns:

Int8 array of shape (w, h) encoding which tiles are occupied.

Raises:

ValueError – If the game is not configured for constrictor mode.

get_copy()[source]#

Return an independent deep copy of this environment.

The copy shares the same cfg reference but has its own C++ game-state object, cumulative rewards, and caches. Both the original and the copy must be closed independently.

Return type:

BattleSnakeGame

Returns:

A new BattleSnakeGame with identical state.

get_cum_rewards()[source]#

Return the cumulative rewards accumulated since the last reset().

Return type:

ndarray

Returns:

Float array of shape (num_players,).

get_hazards()[source]#

Return a boolean array indicating hazard tiles.

Return type:

ndarray

Returns:

Bool array of shape (h, w)True where a hazard tile exists (e.g. the shrinking ring in royale mode).

Raises:

ValueError – If the game is closed.

get_last_action()[source]#

Alias for get_last_actions().

Return type:

Optional[tuple[int, ...]]

get_last_actions()[source]#

Return the joint action that was passed to the most recent step().

Return type:

Optional[tuple[int, ...]]

Returns:

Tuple of action indices, or None if no step has been taken yet.

get_obs(symmetry=0)[source]#

Return observation tensors for all players currently at turn.

The observations are stacked along axis 0 in players_at_turn() order. A symmetry transformation (rotation and/or flip, plus an optional enemy-slot permutation) may be applied.

Parameters:

symmetry (Optional[int]) – Integer index selecting the transformation to apply. 0 is the identity. None samples a transformation uniformly at random. Valid range is [0, get_symmetry_count()).

Returns:

  • obs — float32 array of shape (num_players_at_turn, width, height, channels) or (num_players_at_turn, width * height * channels) when flattening is enabled.

  • perm — dict mapping original action indices to transformed action indices.

  • inv_perm — inverse of perm.

Return type:

tuple[ndarray, dict[int, int], dict[int, int]]

Raises:

ValueError – If the game is closed or already in a terminal state.

get_obs_shape(never_flatten=False)[source]#

Return the shape of a single-player observation tensor.

Parameters:

never_flatten – When True, return the spatial shape (width, height, channels) even if the encoding config has flatten=True.

Return type:

tuple[int, ...]

Returns:

Tuple of ints describing the observation shape. Returns a 1-element tuple (n,) when the config requests flattening (and never_flatten is False), otherwise (width, height, channels).

Raises:

ValueError – If the game has been closed.

get_state()[source]#

Capture the current game state as a serialisable snapshot.

The returned BattleSnakeState can be passed to set_state() (on any compatible environment) to restore this exact position.

Return type:

BattleSnakeState

Returns:

A BattleSnakeState describing the current board.

get_str_repr()[source]#

Return an ASCII string representation of the current board.

Return type:

str

Returns:

Multi-line string visualising the board (snakes, food, hazards).

Raises:

ValueError – If the game is closed.

get_symmetry_count()[source]#

Return the total number of distinct board symmetries.

Symmetries combine 8 spatial transformations (4 rotations × 2 flips) with permutations of enemy player slots. When compress_enemies is enabled there is only one enemy slot, so only 8 symmetries exist. Otherwise there are 8 × (num_players 1)! symmetries.

Returns:

Integer count of symmetries.

Raises:

ValueError – If the game is closed.

illegal_actions(player)[source]#

Return the action indices that are illegal for player.

Parameters:

player (int) – Zero-based player index.

Return type:

list[int]

Returns:

List of action indices not present in available_actions().

Raises:

ValueError – If player is out of range.

illegal_joint_actions()[source]#

Return every joint-action combination that is not fully legal.

Return type:

list[tuple[int, ...]]

Returns:

List of tuples that are absent from available_joint_actions().

is_player_alive(player)[source]#

Return whether player is still alive.

Parameters:

player (int) – Zero-based player index.

Return type:

bool

is_player_at_turn(player)[source]#

Return whether player must provide an action this turn.

Parameters:

player (int) – Zero-based player index.

Return type:

bool

Returns:

True if the player is alive and has at least one legal action.

is_terminal()[source]#

Return whether the game has ended.

The game is terminal when fewer than two players are at turn (in a multi-player game) or when no player is at turn (in a single-player game).

Raises:

ValueError – If the game is closed.

Return type:

bool

property num_actions#

UP, RIGHT, DOWN, LEFT).

Type:

Number of actions available to each player (always 4

num_food()[source]#

Return the number of food items currently on the board.

Raises:

ValueError – If the game is closed.

Return type:

int

property num_players: int#

Total number of players (snakes) in this game, including dead ones.

num_players_alive()[source]#

Return the number of players that are still alive.

Return type:

int

num_players_at_turn()[source]#

Return the number of players who must act this turn.

Return type:

int

play_random_steps(steps)[source]#

Advance the game by up to steps turns using uniformly random actions.

Stops early if the game reaches a terminal state before all steps are consumed.

Parameters:

steps (int) – Maximum number of turns to play.

player_healths()[source]#

Return the current health value of each snake.

Return type:

list[int]

Returns:

List of health values of length num_players.

Raises:

ValueError – If the game is closed.

player_lengths()[source]#

Return the length (number of segments) of each snake.

Return type:

list[int]

Returns:

List of length num_players. Dead snakes retain their last known length value from C++.

Raises:

ValueError – If the game is closed.

player_pos(player)[source]#

Return the body positions of player’s snake as (x, y) tuples.

The first element is the head. Note that the body array length (BODY_LEN) may differ from the logical snake length (SNAKE_LEN) during the turn the snake just ate food.

This method calls into C++ on every invocation and should only be used for debugging or infrequent queries.

Parameters:

player (int) – Zero-based player index.

Return type:

list[tuple[int, int]]

Returns:

List of (x, y) coordinate pairs, head first.

Raises:

ValueError – If the game is closed.

players_alive()[source]#

Return the indices of all living players.

Results are cached until the next step().

Return type:

list[int]

Returns:

List of player indices that are still alive.

Raises:

ValueError – If the game is closed.

players_at_turn()[source]#

Return the indices of all players that must act this turn.

A player is at turn if they are alive and have at least one legal action. Results are cached until the next step().

Return type:

list[int]

Returns:

Sorted list of player indices.

Raises:

ValueError – If the game is closed.

players_not_alive()[source]#

Return the indices of all dead (eliminated) players.

Return type:

list[int]

Returns:

List of player indices that are no longer alive.

render()[source]#

Print an ASCII representation of the current board to stdout.

Raises:

ValueError – If the game is closed.

reset()[source]#

Reinitialise the game to its starting state.

Resets cumulative rewards, turn counter, and last actions, then re-creates the C++ game state from the original config.

reset_saved_properties()[source]#

Clear all intra-turn caches (observations, available actions, player lists).

Called automatically after each step() and reset(). Only call this manually if you mutate the game state externally.

set_cum_rewards(cum_rewards)[source]#

Override the cumulative rewards array.

Parameters:

cum_rewards (ndarray) – Float array of shape (num_players,).

set_last_actions(last_actions)[source]#

Override the recorded last-step joint action.

Parameters:

last_actions (Optional[tuple[int, ...]]) – Tuple of action indices, or None to clear.

set_state(state)[source]#

Restore the game to a previously captured state.

Resets cumulative rewards and last actions, then re-initialises the C++ game state from state.

Parameters:

state (BattleSnakeState) – Snapshot obtained from get_state() (on any compatible environment with the same config).

step(actions)[source]#

Advance the game by one turn.

Parameters:

actions (tuple[int, ...]) – Joint action tuple — one action per player currently at turn, in the order returned by players_at_turn(). Actions must come from available_joint_actions().

Return type:

tuple[ndarray, bool, dict]

Returns:

A 3-tuple (rewards, done, info) where rewards is a float64 array of shape (num_players,), done is True when the game has reached a terminal state, and info is an empty dict (reserved for future use).

Raises:
  • Exception – If the game is already in a terminal state.

  • ValueError – If the length of actions does not match the number of players at turn, or if actions is not a legal joint action.