ethicalgardeners.gridworld.GridWorld

class ethicalgardeners.gridworld.GridWorld(init_method, init_config, width=10, height=10, min_pollution=0, max_pollution=100, pollution_increment=1, num_seeds_returned=1, collisions_on=True, flowers_data: dict = None, random_generator=None, grid=None, agents: list = None, flowers: list = None)[source]

Bases: object

Represents the physical grid world environment for the Ethical Gardeners simulation.

The GridWorld manages a 2D grid of cells. It handles the flowers and agents and manages their placement within the environment. The grid can be initialized from a file, randomly generated, or manually configured.

init_method

Type of initialization (‘from_file’, ‘random’, ‘from_code’)

Type:

str

init_config

Configuration for initialization. If ‘from_file’, this is the file path. If ‘from_code’, this is the grid configuration dictionary. If ‘random’, the obstacle ratio and number of agents.

Type:

dict

width

The width of the grid in cells.

Type:

int

height

The height of the grid in cells.

Type:

int

min_pollution

The minimum level of pollution a cell can have at any time. The cell pollution decreases over time when flowers are planted, but cannot go lower than this minimum value.

Type:

float

max_pollution

The maximum level of pollution a cell can have at any time. The cell pollution increases over time when no flowers are planted, but cannot go higher than this maximum value.

Type:

float

pollution_increment

Amount by which pollution increases in empty cells.

Type:

float

num_seeds_returned

Number of seeds returned when harvesting a flower.

Type:

int

flowers_data

Configuration data for different types of flowers.

Type:

dict

collisions_on

Whether agents can occupy the same cell simultaneously.

Type:

bool

grid

2D array of Cell objects representing the environment.

Type:

list

agents

List of all Agent objects in the environment.

Type:

list

__init__(init_method, init_config, width=10, height=10, min_pollution=0, max_pollution=100, pollution_increment=1, num_seeds_returned=1, collisions_on=True, flowers_data: dict = None, random_generator=None, grid=None, agents: list = None, flowers: list = None)[source]

Create a new grid world environment.

Parameters:
  • init_method (str) – Type of initialization (‘from_file’, ‘random’, ‘from_code’)

  • init_config (dict) – Configuration for initialization. If ‘from_file’, this is the file path. If ‘from_code’, this is the grid configuration dictionary. If ‘random’, the obstacle ratio and number of agents.

  • width (int, optional) – The width of the grid in cells.

  • height (int, optional) – The height of the grid in cells.

  • min_pollution (float, optional) – Minimum allowed pollution level for any cell.

  • max_pollution (float, optional) – Maximum allowed pollution level for any cell.

  • pollution_increment (float, optional) – Amount by which pollution increases in empty cells.

  • num_seeds_returned (int, optional) – Number of seeds returned when harvesting a flower. If -1, the system of seeds will be disabled. If -2, a random number between MIN_SEED_RETURNS and MAX_SEED_RETURNS will be used. If -3, the number of seeds returned will be randomly determined between MIN_SEED_RETURNS and MAX_SEED_RETURNS each time a flower is harvested.

  • flowers_data (dict, optional) – Configuration data for different types of flowers.

  • collisions_on (bool, optional) – Whether agents can occupy the same cell simultaneously.

  • random_generator (numpy.random.RandomState, optional) – Custom random generator instance for reproducibility. If None, uses the default random

  • grid (list, optional) – 2D array of Cell objects representing the environment. If None, initializes an empty grid.

  • agents (list, optional) – List of Agent objects to place in the grid.

  • flowers (list, optional) – List of tuples representing flowers to place in the grid. Each tuple should be of the form (position, flower_type, growth_stage)

Methods

__init__(init_method, init_config[, width, ...])

Create a new grid world environment.

copy()

Create a deep copy of the GridWorld instance.

create_from_config(init_method[, ...])

Create a GridWorld instance based on the specified initialization method and configuration.

get_cell(position)

Gets the cell at the specified position.

init_from_code([init_config, ...])

Initialize the grid directly from code using a configuration dictionary.

init_from_file(init_config[, ...])

Initialize the grid from a file.

init_random([init_config, width, height, ...])

Initialize a random grid with obstacles and agents.

place_agent(agent)

Place an agent in the grid at its current position.

place_flower(position, flower_type[, ...])

Place a flower in the grid at its specified position.

remove_flower(position)

Removes a flower from the specified position in the grid.

reset([random_generator])

Reset the grid world to its initial configuration.

update_cell()

Updates the pollution and flowers of all cells in the grid.

valid_move(new_position)

Checks if an agent can move to a new position based on the action.

valid_position(position)

Checks if a position is valid for an agent to move to.

copy()[source]

Create a deep copy of the GridWorld instance.

Returns:

A new instance of GridWorld with the same properties.

Return type:

GridWorld

classmethod create_from_config(init_method: str, init_config=None, random_generator=None, width=10, height=10, min_pollution=0, max_pollution=100, pollution_increment=1, num_seeds_returned=1, collisions_on=True, flowers_data: dict = None)[source]

Create a GridWorld instance based on the specified initialization method and configuration.

Parameters:
  • init_method (str) – Type of initialization (‘from_file’, ‘random’, ‘from_code’)

  • init_config (dict) – Configuration for initialization. If ‘from_file’, this is the file path. If ‘from_code’, this is the grid configuration dictionary. If ‘random’, the obstacle ratio and number of agents.

  • random_generator (numpy.random.RandomState, optional) – Custom random generator instance for reproducibility.

  • width (int, optional) – Width of the grid (used for “random” initialization).

  • height (int, optional) – Height of the grid (used for “random” initialization).

  • min_pollution (float, optional) – Minimum allowed pollution level for any cell.

  • max_pollution (float, optional) – Maximum allowed pollution level for any cell.

  • pollution_increment (float, optional) – Amount by which pollution increases in empty cells.

  • num_seeds_returned (int, optional) – Number of seeds returned when harvesting a flower.

  • collisions_on (bool, optional) – Whether agents can occupy the same cell simultaneously.

  • flowers_data (dict, optional) – Configuration data for different types of flowers.

get_cell(position)[source]

Gets the cell at the specified position.

Parameters:

position (tuple) – The (x, y) coordinates of the cell to retrieve.

Returns:

The cell at the specified position.

Return type:

Cell

classmethod init_from_code(init_config=None, random_generator=None, width=10, height=10, min_pollution=0, max_pollution=100, pollution_increment=1, num_seeds_returned=1, collisions_on=True)[source]

Initialize the grid directly from code using a configuration dictionary.

This method allows programmatic grid initialization for testing and debugging without having to create external files.

Parameters:
  • init_config (dict, optional) –

    Configuration dictionary with the key “grid_config” specifying the grid configuration. The grid configuration dictionary should have the following structure:

    {
        'width': int,  # Width of the grid
        'height': int,  # Height of the grid
        'cells': [  # List of special cells (other than GROUND)
            {'position': (row, col), 'type': 'OBSTACLE'},
        ],
        'min_pollution': float,  # Minimum pollution level
        'max_pollution': float,  # Maximum pollution level
        'pollution_increment': float,  # Pollution increment
        'num_seeds_returned': int,  # Number of seeds returned
                                    # when harvesting a flower
        'collisions_on': bool,  # Whether agents can occupy the
                                # same cell
        'flowers_data': {  # Optional: custom flower data
            int: {'price': float,
            'pollution_reduction': [float, ...]},
        },
        'agents': [  # List of agents to create (optional:
                     # money and seeds)
            {'position': (row, col), 'money': float,
            'seeds': {0:int, 1:int, ...}},
        ],
        'flowers': [  # List of flowers to create (optional:
                      # growth stage)
            {'position': (row, col), 'type': int,
            'growth_stage': int},
        ]
    }
    

  • width (int, optional) – Width of the grid.

  • height (int, optional) – Height of the grid.

  • min_pollution (float, optional) – Minimum allowed pollution level for any cell.

  • max_pollution (float, optional) – Maximum allowed pollution level for any cell.

  • pollution_increment (float, optional) – Amount by which pollution increases in empty cells.

  • num_seeds_returned (int, optional) – Number of seeds returned when harvesting a flower.

  • collisions_on (bool, optional) – Whether agents can occupy the same cell simultaneously.

  • random_generator (numpy.random.RandomState, optional) – Custom random generator instance for reproducibility.

classmethod init_from_file(init_config, random_generator=None, min_pollution=0, max_pollution=100, pollution_increment=1, num_seeds_returned=1, collisions_on=True)[source]

Initialize the grid from a file.

The file format supports:

  • First line: width height

  • Grid representation: G (ground), O (obstacle), FX_Y (ground with flower type X at growth stage Y), AX (ground with agent ID X)

  • Agent definitions: ID,money,seeds

  • Flowers_data definition: type,price,pollution_reduction

Example:

10 10
G G G O O G G G G G
G F0_2 G G G O G G G G
G O G A0 O G G G G G
G G G G O G G G G G
O O O O O G G G G G
G G G G G G G G G G
G G G G G G G G G G
G G G G G G G G G G
G G G G G G G G G G
G G G G G G G G G G
0,100,5|10|3
0,10,5|2|1
1,5,3|1|0
2,2,1|0
Parameters:
  • init_config (dict) – Configuration dictionary with the key “file_path” specifying the path to the initialization file.

  • random_generator (numpy.random.RandomState, optional) – Custom random generator instance for reproducibility.

  • min_pollution (float, optional) – Minimum allowed pollution level for any cell.

  • max_pollution (float, optional) – Maximum allowed pollution level for any cell.

  • pollution_increment (float, optional) – Amount by which pollution increases in empty cells.

  • num_seeds_returned (int, optional) – Number of seeds returned when harvesting a flower.

  • collisions_on (bool, optional) – Whether agents can occupy the same cell simultaneously.

classmethod init_random(init_config=None, width=10, height=10, min_pollution=0, max_pollution=100, pollution_increment=1, num_seeds_returned=1, collisions_on=True, flowers_data: dict = None, random_generator=None)[source]

Initialize a random grid with obstacles and agents.

Parameters:
  • init_config (dict, optional) – Configuration dictionary with the keys “obstacles_ratio” (float between 0 and 1) and “nb_agent” (int) specifying the ratio of obstacle cells and the number of agents to place in the grid. Defaults to {“obstacles_ratio”: 0.2, “nb_agent”: 1}

  • width (int, optional) – Width of the grid

  • height (int, optional) – Height of the grid

  • min_pollution (float, optional) – Minimum allowed pollution level for any cell.

  • max_pollution (float, optional) – Maximum allowed pollution level for any cell.

  • pollution_increment (float, optional) – Amount by which pollution increases in empty cells.

  • num_seeds_returned (int, optional) – Number of seeds returned when harvesting a flower.

  • collisions_on (bool, optional) – Whether agents can occupy the same cell simultaneously.

  • flowers_data (dict, optional) – Configuration data for different types of flowers.

  • random_generator (numpy.random.RandomState, optional) – Custom random generator instance for reproducibility. If None, uses the default random generator.

Raises:

ValueError – If there are not enough valid positions for the specified number of agents after placing obstacles.

place_agent(agent: Agent)[source]

Place an agent in the grid at its current position.

Parameters:

agent (Agent) – The agent to place in the grid.

Raises:

ValueError – If the agent’s position is invalid or already occupied and collisions are not allowed.

place_flower(position, flower_type: int, growth_stage=0)[source]

Place a flower in the grid at its specified position.

Parameters:
  • position (tuple) – The (x, y) coordinates where the flower will be planted.

  • flower_type (int) – The type of flower to plant.

  • growth_stage (int, optional) – The initial growth stage of the flower (default is 0).

Raises:

ValueError – If the flower’s position is invalid or if the cell already contains a flower.

remove_flower(position)[source]

Removes a flower from the specified position in the grid.

Parameters:

position (tuple) – The (x, y) coordinates of the flower to remove.

Raises:

ValueError – If there is no flower at the specified position.

reset(random_generator=None)[source]

Reset the grid world to its initial configuration.

Warning: This method uses a special approach to reset the instance by creating a new instance and copying its state with an access to self.__dict__. It should work in most cases but take care if you have a special case such as an attribute not being in __dict__.

Parameters:

random_generator (numpy.random.RandomState, optional) – Custom random generator instance for reproducibility. If None, uses the same random generator as the current instance.

update_cell()[source]

Updates the pollution and flowers of all cells in the grid.

For each cell, if it contains a flower, pollution decreases by the flower’s pollution reduction value and make the flower grow. If it does not contain a flower, pollution increases by the pollution increment value.

valid_move(new_position)[source]

Checks if an agent can move to a new position based on the action.

A move is valid if:

  1. The new position is valid.

2. If collisions are enabled, the new position is not occupied by another agent.

Parameters:

new_position (tuple) – The new (x, y) coordinates of the agent after moving.

Returns:

True if the move is valid, False otherwise.

Return type:

bool

valid_position(position)[source]

Checks if a position is valid for an agent to move to.

A position is valid if:

  1. It is within the grid boundaries

  2. It is not an obstacle cell

Parameters:

position (tuple) – The (x, y) coordinates to check.

Returns:

True if the position is valid, False otherwise.

Return type:

bool