diff --git a/benchmarks/BoltzmannWealth/boltzmann_wealth.py b/benchmarks/BoltzmannWealth/boltzmann_wealth.py index 2d863efcb8d..98b02bcbf8d 100644 --- a/benchmarks/BoltzmannWealth/boltzmann_wealth.py +++ b/benchmarks/BoltzmannWealth/boltzmann_wealth.py @@ -4,6 +4,7 @@ """ import mesa +import mesa.spaces as spaces def compute_gini(model): @@ -42,17 +43,18 @@ def __init__(self, seed=None, n=100, width=10, height=10): """ super().__init__(seed=seed) self.num_agents = n - self.grid = mesa.space.MultiGrid(width, height, True) + self.grid = spaces.OrthogonalMooreGrid((width, height)) + self.schedule = mesa.time.RandomActivation(self) self.datacollector = mesa.DataCollector( model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"} ) # Create agents for _ in range(self.num_agents): - a = MoneyAgent(self) + agent = MoneyAgent(self) # Add the agent to a random grid cell - x = self.random.randrange(self.grid.width) - y = self.random.randrange(self.grid.height) - self.grid.place_agent(a, (x, y)) + x = self.random.randrange(width) + y = self.random.randrange(height) + agent.move_to(self.grid[(x, y)]) self.running = True self.datacollector.collect(self) @@ -74,7 +76,7 @@ def run_model(self, n): self.step() -class MoneyAgent(mesa.Agent): +class MoneyAgent(mesa.spaces.CellAgent): """An agent with fixed initial wealth.""" def __init__(self, model): @@ -86,20 +88,8 @@ def __init__(self, model): super().__init__(model) self.wealth = 1 - def move(self): - """Move the agent to a random neighboring cell.""" - possible_steps = self.model.grid.get_neighborhood( - self.pos, moore=True, include_center=False - ) - new_position = self.random.choice(possible_steps) - self.model.grid.move_agent(self, new_position) - def give_money(self): - """Give money to a random cell mate.""" - cellmates = self.model.grid.get_cell_list_contents([self.pos]) - cellmates.pop( - cellmates.index(self) - ) # Ensure agent is not giving money to itself + cellmates = [agent for agent in self.cell.agents if agent is not self] if len(cellmates) > 0: other = self.random.choice(cellmates) other.wealth += 1 @@ -107,6 +97,12 @@ def give_money(self): def step(self): """Run the agent for 1 step.""" - self.move() + self.move_to(self.cell.neighborhood().select_random_cell()) if self.wealth > 0: self.give_money() + + +if __name__ == "__main__": + model = BoltzmannWealth() + for _ in range(10): + model.step() diff --git a/benchmarks/Schelling/schelling.py b/benchmarks/Schelling/schelling.py index 2b6614daac7..4378bc061ba 100644 --- a/benchmarks/Schelling/schelling.py +++ b/benchmarks/Schelling/schelling.py @@ -3,7 +3,7 @@ from __future__ import annotations from mesa import Model -from mesa.experimental.cell_space import Cell, CellAgent, OrthogonalMooreGrid +from mesa.spaces import CellAgent, OrthogonalMooreGrid class SchellingAgent(CellAgent): diff --git a/benchmarks/WolfSheep/wolf_sheep.py b/benchmarks/WolfSheep/wolf_sheep.py index f085ce429df..a6a4a83d760 100644 --- a/benchmarks/WolfSheep/wolf_sheep.py +++ b/benchmarks/WolfSheep/wolf_sheep.py @@ -10,8 +10,8 @@ import math from mesa import Model -from mesa.experimental.cell_space import CellAgent, FixedAgent, OrthogonalVonNeumannGrid from mesa.experimental.devs import ABMSimulator +from mesa.spaces import CellAgent, OrthogonalVonNeumannGrid class Animal(CellAgent): diff --git a/mesa/__init__.py b/mesa/__init__.py index 6214d18dacd..53e886f3eb0 100644 --- a/mesa/__init__.py +++ b/mesa/__init__.py @@ -5,7 +5,9 @@ import datetime -import mesa.space as space +import mesa.space as old_space + +# import mesa.spaces as spaces import mesa.time as time from mesa.agent import Agent from mesa.batchrunner import batch_run @@ -16,7 +18,8 @@ "Model", "Agent", "time", - "space", + "old_space", + "spaces", "DataCollector", "batch_run", "experimental", diff --git a/mesa/experimental/__init__.py b/mesa/experimental/__init__.py index a48c498f6f9..351500b16a6 100644 --- a/mesa/experimental/__init__.py +++ b/mesa/experimental/__init__.py @@ -1,7 +1,5 @@ """Experimental init.""" -from mesa.experimental import cell_space - from .solara_viz import JupyterViz, Slider, SolaraViz, make_text -__all__ = ["cell_space", "JupyterViz", "SolaraViz", "make_text", "Slider"] +__all__ = ["JupyterViz", "SolaraViz", "make_text", "Slider"] diff --git a/mesa/experimental/cell_space/__init__.py b/mesa/experimental/cell_space/__init__.py deleted file mode 100644 index 69386a4cacf..00000000000 --- a/mesa/experimental/cell_space/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Cell spaces. - -Cell spaces offer an alternative API for discrete spaces. It is experimental and under development. The API is more -expressive that the default grids available in `mesa.space`. - -""" - -from mesa.experimental.cell_space.cell import Cell -from mesa.experimental.cell_space.cell_agent import ( - CellAgent, - FixedAgent, - Grid2DMovingAgent, -) -from mesa.experimental.cell_space.cell_collection import CellCollection -from mesa.experimental.cell_space.discrete_space import DiscreteSpace -from mesa.experimental.cell_space.grid import ( - Grid, - HexGrid, - OrthogonalMooreGrid, - OrthogonalVonNeumannGrid, -) -from mesa.experimental.cell_space.network import Network -from mesa.experimental.cell_space.voronoi import VoronoiGrid - -__all__ = [ - "CellCollection", - "Cell", - "CellAgent", - "Grid2DMovingAgent", - "FixedAgent", - "DiscreteSpace", - "Grid", - "HexGrid", - "OrthogonalMooreGrid", - "OrthogonalVonNeumannGrid", - "Network", - "VoronoiGrid", -] diff --git a/mesa/experimental/components/matplotlib.py b/mesa/experimental/components/matplotlib.py index bb3b9854193..a4656cf11e7 100644 --- a/mesa/experimental/components/matplotlib.py +++ b/mesa/experimental/components/matplotlib.py @@ -8,7 +8,6 @@ from matplotlib.ticker import MaxNLocator import mesa -from mesa.experimental.cell_space import VoronoiGrid @solara.component diff --git a/mesa/spaces/__init__.py b/mesa/spaces/__init__.py new file mode 100644 index 00000000000..44ae0a5b6e7 --- /dev/null +++ b/mesa/spaces/__init__.py @@ -0,0 +1,25 @@ +from mesa.spaces.cell import Cell +from mesa.spaces.cell_agent import CellAgent +from mesa.spaces.cell_collection import CellCollection +from mesa.spaces.discrete_space import DiscreteSpace +from mesa.spaces.grid import ( + Grid, + HexGrid, + OrthogonalMooreGrid, + OrthogonalVonNeumannGrid, +) +from mesa.spaces.network import Network +from mesa.spaces.voronoi import VoronoiGrid + +__all__ = [ + "CellCollection", + "Cell", + "CellAgent", + "DiscreteSpace", + "Grid", + "HexGrid", + "OrthogonalMooreGrid", + "OrthogonalVonNeumannGrid", + "Network", + "VoronoiGrid", +] diff --git a/mesa/experimental/cell_space/cell.py b/mesa/spaces/cell.py similarity index 98% rename from mesa/experimental/cell_space/cell.py rename to mesa/spaces/cell.py index 6c92afbe162..fd7fe8005aa 100644 --- a/mesa/experimental/cell_space/cell.py +++ b/mesa/spaces/cell.py @@ -7,8 +7,11 @@ from random import Random from typing import TYPE_CHECKING, Any -from mesa.experimental.cell_space.cell_agent import CellAgent -from mesa.experimental.cell_space.cell_collection import CellCollection +from mesa.spaces.cell_collection import CellCollection + +if TYPE_CHECKING: + from mesa.spaces.cell_agent import CellAgent + from mesa.space import PropertyLayer if TYPE_CHECKING: diff --git a/mesa/experimental/cell_space/cell_agent.py b/mesa/spaces/cell_agent.py similarity index 95% rename from mesa/experimental/cell_space/cell_agent.py rename to mesa/spaces/cell_agent.py index 5dc967ee76d..c56fccbf7af 100644 --- a/mesa/experimental/cell_space/cell_agent.py +++ b/mesa/spaces/cell_agent.py @@ -7,7 +7,7 @@ from mesa.agent import Agent if TYPE_CHECKING: - from mesa.experimental.cell_space import Cell + from mesa.spaces.cell import Cell class HasCellProtocol(Protocol): @@ -127,7 +127,3 @@ def move(self, direction: str, distance: int = 1): if direction not in self.DIRECTION_MAP: raise ValueError(f"Invalid direction: {direction}") - - move_vector = self.DIRECTION_MAP[direction] - for _ in range(distance): - self.move_relative(move_vector) diff --git a/mesa/experimental/cell_space/cell_collection.py b/mesa/spaces/cell_collection.py similarity index 96% rename from mesa/experimental/cell_space/cell_collection.py rename to mesa/spaces/cell_collection.py index a8c36f5198f..21d47386b24 100644 --- a/mesa/experimental/cell_space/cell_collection.py +++ b/mesa/spaces/cell_collection.py @@ -9,8 +9,8 @@ from typing import TYPE_CHECKING, Generic, TypeVar if TYPE_CHECKING: - from mesa.experimental.cell_space.cell import Cell - from mesa.experimental.cell_space.cell_agent import CellAgent + from mesa.spaces.cell import Cell + from mesa.spaces.cell_agent import CellAgent T = TypeVar("T", bound="Cell") diff --git a/mesa/experimental/cell_space/discrete_space.py b/mesa/spaces/discrete_space.py similarity index 97% rename from mesa/experimental/cell_space/discrete_space.py rename to mesa/spaces/discrete_space.py index 1cfaedeb167..07aabf701d5 100644 --- a/mesa/experimental/cell_space/discrete_space.py +++ b/mesa/spaces/discrete_space.py @@ -7,9 +7,9 @@ from random import Random from typing import Any, Generic, TypeVar -from mesa.experimental.cell_space.cell import Cell -from mesa.experimental.cell_space.cell_collection import CellCollection from mesa.space import PropertyLayer +from mesa.spaces.cell import Cell +from mesa.spaces.cell_collection import CellCollection T = TypeVar("T", bound=Cell) diff --git a/mesa/experimental/cell_space/grid.py b/mesa/spaces/grid.py similarity index 99% rename from mesa/experimental/cell_space/grid.py rename to mesa/spaces/grid.py index 4d525964f83..c69df28179e 100644 --- a/mesa/experimental/cell_space/grid.py +++ b/mesa/spaces/grid.py @@ -7,7 +7,7 @@ from random import Random from typing import Generic, TypeVar -from mesa.experimental.cell_space import Cell, DiscreteSpace +from mesa.spaces import Cell, DiscreteSpace T = TypeVar("T", bound=Cell) diff --git a/mesa/experimental/cell_space/network.py b/mesa/spaces/network.py similarity index 90% rename from mesa/experimental/cell_space/network.py rename to mesa/spaces/network.py index 551305267af..1a406fc0137 100644 --- a/mesa/experimental/cell_space/network.py +++ b/mesa/spaces/network.py @@ -3,8 +3,8 @@ from random import Random from typing import Any -from mesa.experimental.cell_space.cell import Cell -from mesa.experimental.cell_space.discrete_space import DiscreteSpace +from mesa.spaces.cell import Cell +from mesa.spaces.discrete_space import DiscreteSpace class Network(DiscreteSpace[Cell]): diff --git a/mesa/experimental/cell_space/voronoi.py b/mesa/spaces/voronoi.py similarity index 98% rename from mesa/experimental/cell_space/voronoi.py rename to mesa/spaces/voronoi.py index 2cde122cbb6..87ee5bdf84b 100644 --- a/mesa/experimental/cell_space/voronoi.py +++ b/mesa/spaces/voronoi.py @@ -6,8 +6,8 @@ import numpy as np -from mesa.experimental.cell_space.cell import Cell -from mesa.experimental.cell_space.discrete_space import DiscreteSpace +from mesa.spaces.cell import Cell +from mesa.spaces.discrete_space import DiscreteSpace class Delaunay: diff --git a/mesa/visualization/components/matplotlib.py b/mesa/visualization/components/matplotlib.py index 771978c1cd7..fd5f0e24761 100644 --- a/mesa/visualization/components/matplotlib.py +++ b/mesa/visualization/components/matplotlib.py @@ -11,8 +11,8 @@ from matplotlib.figure import Figure import mesa -from mesa.experimental.cell_space import VoronoiGrid from mesa.space import PropertyLayer +from mesa.spaces import VoronoiGrid from mesa.visualization.utils import update_counter diff --git a/tests/test_cell_space.py b/tests/test_cell_space.py index 4d52e159045..084b1f73386 100644 --- a/tests/test_cell_space.py +++ b/tests/test_cell_space.py @@ -6,7 +6,8 @@ import pytest from mesa import Model -from mesa.experimental.cell_space import ( +from mesa.space import PropertyLayer +from mesa.spaces import ( Cell, CellAgent, CellCollection, @@ -18,7 +19,6 @@ OrthogonalVonNeumannGrid, VoronoiGrid, ) -from mesa.space import PropertyLayer def test_orthogonal_grid_neumann(): diff --git a/tests/test_solara_viz.py b/tests/test_solara_viz.py index a0d2b449399..9ef282c2d4d 100644 --- a/tests/test_solara_viz.py +++ b/tests/test_solara_viz.py @@ -128,7 +128,7 @@ def drawer(model): # check voronoi space drawer voronoi_model = mesa.Model() - voronoi_model.grid = mesa.experimental.cell_space.VoronoiGrid( + voronoi_model.grid = mesa.spaces.VoronoiGrid( centroids_coordinates=[(0, 1), (0, 0), (1, 0)], ) solara.render(