Grid3D

class w9_pathfinding.envs.Grid3D

A 3D grid environment for pathfinding with support for obstacles, weighted traversal, and edge-wrapping.

The grid can be initialized either with an explicit size (width, height and depth) or from a nested list of weights.

Parameters:
  • weights (nested list of float, optional) –

    A grid-shaped array representing movement cost to enter each node. Each value must be a non-negative float or exactly -1.

    • A positive value indicates the movement cost for that node.

    • A value of -1 marks the node as an obstacle (impassable).

  • width (int, optional) – Width of the grid (X-axis). Required if weights is not provided.

  • height (int, optional) – Height of the grid (Y-axis). Required if weights is not provided.

  • depth (int, optional) – Depth of the grid (Z-axis). Required if weights is not provided.

  • passable_borders (bool, default False) – Whether the grid allows wraparound movement across opposite borders (along any axis).

  • pause_weights (nested list of float, optional) –

    A grid-shaped array representing the cost of pausing (waiting in place) at each node. Each value must be a non-negative float or exactly -1.

    • A non-negative value indicates the cost to pause at that node.

    • A value of -1 means pausing is not allowed at that node.

  • edge_collision (bool, default False) – Whether to enable edge collision checks. If set to True, prevents two agents from using the same edge simultaneously, even if they are moving in opposite directions. This helps avoid edge conflicts (e.g. node swapping) in multi-agent pathfinding scenarios.

Examples

Create a 3x3x3 grid with one obstacle in the middle:

>>> grid = Grid3D(width=3, height=3, depth=3)  # all weights will default to 1.0
>>> grid.add_obstacle((1, 1, 1))

Create a 3x4x5 grid with random weights:

>>> import numpy as np
>>> grid = Grid3D(np.random.random(size=(3,4,5)))
add_obstacle(node)

Mark the specified node as an obstacle.

Parameters:

node (tuple of int) – The coordinate to mark as an obstacle.

Raises:

ValueError – If the node is outside the bounds of the grid.

adjacent(v1, v2) bool

Check whether two nodes are directly connected.

Parameters:
  • v1 (node) – First node.

  • v2 (node) – Second node.

Returns:

True if there is a direct edge from v1 to v2.

Return type:

bool

Raises:

ValueError – If either v1 or v2 is not a valid node in the environment.

calculate_cost(path) double

Calculate the total cost of a given path through the environment.

If the path is invalid (e.g. contains non-adjacent nodes), this will return -1.

Parameters:

path (iterable of nodes) – A sequence of nodes representing the path to evaluate.

Returns:

Total cost of traversing the path, or -1 if the path is invalid.

Return type:

float

Raises:

ValueError – If one of the nodes in the path is not a valid node in the environment.

contains(node) bool

Check if the environment contains a given node.

Parameters:

node – The node to check.

Returns:

True if the node is in the environment, False otherwise.

Return type:

bool

depth

The number of layers (or slices) in the grid (Z-axis).

edge_collision

Whether edge collision checks are enabled.

find_components()

Find connected components.

Returns:

List of components, each as a list of nodes.

Return type:

List[List[node]]

get_neighbors(node, include_self=False) list

Get neighboring nodes of a given node, along with the cost of moving to each.

Each neighbor is returned as a tuple of (neighbor_node, cost). For example: [(n1, 1.0), (n2, 2.5)]

Parameters:
  • node – The target node.

  • include_self (bool, default False) – Whether to include the node itself if there is an self loop.

Returns:

List of neighbors with movement costs.

Return type:

List[Tuple[node, float]]

Raises:

ValueError – If the node is not a valid node in the environment.

get_pause_weight(node) double

Get the pause cost at a specific node.

Parameters:

node (tuple of int) – The coordinate to query.

Returns:

The cost of remaining at the specified node.

Return type:

float

Raises:

ValueError – If the node is outside the bounds of the grid.

get_weight(node) double

Get the movement cost to enter a node in the grid.

Parameters:

node (tuple of int) – The coordinate to query.

Returns:

The movement cost to enter the specified node.

Return type:

float

Raises:

ValueError – If the node is outside the bounds of the grid.

has_obstacle(node) bool

Check whether the specified node is marked as an obstacle.

Parameters:

node (tuple of int) – The grid coordinate to check.

Returns:

True if the node is an obstacle; False otherwise.

Return type:

bool

Raises:

ValueError – If the node is outside the bounds of the grid.

height

The number of rows in the grid (Y-axis).

is_valid_path(path) bool

Check if a given path is valid within the environment.

Parameters:

path (iterable of nodes) – A sequence of nodes representing the path

Returns:

True if the path is valid, False otherwise.

Return type:

bool

Raises:

ValueError – If one of the nodes in the path is not a valid node in the environment.

obstacle_map

Get a binary map of obstacles in the grid.

Returns:

A grid-shaped nested structure where each cell contains:

  • 1 if the corresponding node is an obstacle (weight = -1)

  • 0 otherwise

Return type:

array-like

passable_borders

Whether the grid allows wraparound movement across opposite borders (along any axis).

pause_weights

A grid-shaped array representing the cost of pausing (waiting in place) at each node

Notes

This is a read-only snapshot of internal weights; modifying it won’t change the grid.

remove_obstacle(node)

Remove the obstacle status from the specified node.

Parameters:

node (tuple of int) – The coordinate to unmark as an obstacle.

Raises:

ValueError – If the node is outside the bounds of the grid.

shape

Shape of the grid, (depth, height, width).

size

Total number of nodes in the environment.

to_dict()

Convert environment settings to a serializable dictionary.

Returns:

Dictionary of environment configuration options.

Return type:

dict

update_weight(node, new_value)

Update the movement cost (weight) of a specific node in the grid.

Parameters:
  • node (tuple of int) – The coordinate whose weight should be updated.

  • new_value (float) – The new cost value for moving into this node.

Raises:
  • ValueError – If the node is outside the bounds of the grid

  • ValueError – If new_value is negative and not equal to -1.

weights

A grid-shaped array representing movement cost to enter each node.

Notes

This is a read-only snapshot of internal weights; modifying it won’t change the grid.

width

The number of columns in the grid (X-axis).