From 69760f4d53d5e60bf5936812587b9c339cf18a4c Mon Sep 17 00:00:00 2001 From: coderbeta1 Date: Thu, 22 Feb 2024 23:25:09 +0530 Subject: [PATCH 1/6] Improve boid flocker model --- examples/boid_flockers/Readme.md | 47 ++++--- examples/boid_flockers/app.py | 4 +- .../boid_flockers/SimpleContinuousModule.py | 7 +- examples/boid_flockers/boid_flockers/boid.py | 104 --------------- examples/boid_flockers/boid_flockers/model.py | 124 ++++++++++++++++-- .../boid_flockers/boid_flockers/server.py | 56 ++++++-- .../boid_flockers/simple_continuous_canvas.js | 1 - 7 files changed, 193 insertions(+), 150 deletions(-) delete mode 100644 examples/boid_flockers/boid_flockers/boid.py diff --git a/examples/boid_flockers/Readme.md b/examples/boid_flockers/Readme.md index cb3292b4..c06fe36d 100644 --- a/examples/boid_flockers/Readme.md +++ b/examples/boid_flockers/Readme.md @@ -1,34 +1,47 @@ -# Flockers +# Boids Flockers + +## Summary An implementation of Craig Reynolds's Boids flocker model. Agents (simulated birds) try to fly towards the average position of their neighbors and in the same direction as them, while maintaining a minimum distance. This produces flocking behavior. This model tests Mesa's continuous space feature, and uses numpy arrays to represent vectors. It also demonstrates how to create custom visualization components. +## Installation + +To install the dependencies use pip and the requirements.txt in this directory. e.g. + +``` + $ pip install -r requirements.txt +``` + ## How to Run -Launch the model: +* To launch the visualization interactively, run ``mesa runserver`` in this directory. e.g. + +``` +$ mesa runserver +``` + +or + +Directly run the file ``app.py`` in the terminal. e.g. + ``` - $ python Flocker_Server.py + $ python app.py ``` -Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press Reset, then Run. +* Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press Reset, then Run. ## Files -* [flockers/model.py](flockers/model.py): Core model file; contains the BoidModel class. -* [flockers/boid.py](flockers/boid.py): The Boid agent class. -* [flockers/SimpleContinuousModule.py](flockers/SimpleContinuousModule.py): Defines ``SimpleCanvas``, the Python side of a custom visualization module for drawing agents with continuous positions. -* [flockers/simple_continuous_canvas.js](flockers/simple_continuous_canvas.js): JavaScript side of the ``SimpleCanvas`` visualization module; takes the output generated by the Python ``SimpleCanvas`` element and draws it in the browser window via HTML5 canvas. -* [flockers/server.py](flockers/server.py): Sets up the visualization; uses the SimpleCanvas element defined above +* [boid_flockers/model.py](boid_flockers/model.py): Core model file; contains the Boid Model and Boid Agent class. +* [boid_flockers/SimpleContinuousModule.py](boid_flockers/SimpleContinuousModule.py): Defines ``SimpleCanvas``, the Python side of a custom visualization module for drawing agents with continuous positions. +* [boid_flockers/simple_continuous_canvas.js](boid_flockers/simple_continuous_canvas.js): JavaScript side of the ``SimpleCanvas`` visualization module; takes the output generated by the Python ``SimpleCanvas`` element and draws it in the browser window via HTML5 canvas. +* [boid_flockers/server.py](boid_flockers/server.py): Sets up the visualization; uses the SimpleCanvas element defined above * [run.py](run.py) Launches the visualization. -* [Flocker Test.ipynb](Flocker Test.ipynb): Tests the model in a Jupyter notebook. +* [Flocker_Test.ipynb](Flocker_Test.ipynb): Tests the model in a Jupyter notebook. ## Further Reading -======= -* Launch the visualization -``` -$ mesa runserver -``` -* Visit your browser: http://127.0.0.1:8521/ -* In your browser hit *run* +The following link can be visited for more information on the boid flockers model: +https://cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/modeling-natural-systems/boids.html diff --git a/examples/boid_flockers/app.py b/examples/boid_flockers/app.py index 30b9fa28..5de317fe 100644 --- a/examples/boid_flockers/app.py +++ b/examples/boid_flockers/app.py @@ -16,8 +16,8 @@ def boid_draw(agent): } page = JupyterViz( - BoidFlockers, - model_params, + model_class=BoidFlockers, + model_params=model_params, measures=[], name="BoidFlockers", agent_portrayal=boid_draw, diff --git a/examples/boid_flockers/boid_flockers/SimpleContinuousModule.py b/examples/boid_flockers/boid_flockers/SimpleContinuousModule.py index 3f3da5dd..7d761bac 100644 --- a/examples/boid_flockers/boid_flockers/SimpleContinuousModule.py +++ b/examples/boid_flockers/boid_flockers/SimpleContinuousModule.py @@ -3,11 +3,8 @@ class SimpleCanvas(mesa.visualization.VisualizationElement): local_includes = ["boid_flockers/simple_continuous_canvas.js"] - portrayal_method = None - canvas_height = 500 - canvas_width = 500 - - def __init__(self, portrayal_method, canvas_height=500, canvas_width=500): + + def __init__(self, portrayal_method=None, canvas_height=500, canvas_width=500): """ Instantiate a new SimpleCanvas """ diff --git a/examples/boid_flockers/boid_flockers/boid.py b/examples/boid_flockers/boid_flockers/boid.py deleted file mode 100644 index f427f9dd..00000000 --- a/examples/boid_flockers/boid_flockers/boid.py +++ /dev/null @@ -1,104 +0,0 @@ -import mesa -import numpy as np - - -class Boid(mesa.Agent): - """ - A Boid-style flocker agent. - - The agent follows three behaviors to flock: - - Cohesion: steering towards neighboring agents. - - Separation: avoiding getting too close to any other agent. - - Alignment: try to fly in the same direction as the neighbors. - - Boids have a vision that defines the radius in which they look for their - neighbors to flock with. Their speed (a scalar) and velocity (a vector) - define their movement. Separation is their desired minimum distance from - any other Boid. - """ - - def __init__( - self, - unique_id, - model, - pos, - speed, - velocity, - vision, - separation, - cohere=0.025, - separate=0.25, - match=0.04, - ): - """ - Create a new Boid flocker agent. - - Args: - unique_id: Unique agent identifyer. - pos: Starting position - speed: Distance to move per step. - heading: numpy vector for the Boid's direction of movement. - vision: Radius to look around for nearby Boids. - separation: Minimum distance to maintain from other Boids. - cohere: the relative importance of matching neighbors' positions - separate: the relative importance of avoiding close neighbors - match: the relative importance of matching neighbors' headings - """ - super().__init__(unique_id, model) - self.pos = np.array(pos) - self.speed = speed - self.velocity = velocity - self.vision = vision - self.separation = separation - self.cohere_factor = cohere - self.separate_factor = separate - self.match_factor = match - - def cohere(self, neighbors): - """ - Return the vector toward the center of mass of the local neighbors. - """ - cohere = np.zeros(2) - if neighbors: - for neighbor in neighbors: - cohere += self.model.space.get_heading(self.pos, neighbor.pos) - cohere /= len(neighbors) - return cohere - - def separate(self, neighbors): - """ - Return a vector away from any neighbors closer than separation dist. - """ - me = self.pos - them = (n.pos for n in neighbors) - separation_vector = np.zeros(2) - for other in them: - if self.model.space.get_distance(me, other) < self.separation: - separation_vector -= self.model.space.get_heading(me, other) - return separation_vector - - def match_heading(self, neighbors): - """ - Return a vector of the neighbors' average heading. - """ - match_vector = np.zeros(2) - if neighbors: - for neighbor in neighbors: - match_vector += neighbor.velocity - match_vector /= len(neighbors) - return match_vector - - def step(self): - """ - Get the Boid's neighbors, compute the new vector, and move accordingly. - """ - - neighbors = self.model.space.get_neighbors(self.pos, self.vision, False) - self.velocity += ( - self.cohere(neighbors) * self.cohere_factor - + self.separate(neighbors) * self.separate_factor - + self.match_heading(neighbors) * self.match_factor - ) / 2 - self.velocity /= np.linalg.norm(self.velocity) - new_pos = self.pos + self.velocity * self.speed - self.model.space.move_agent(self, new_pos) diff --git a/examples/boid_flockers/boid_flockers/model.py b/examples/boid_flockers/boid_flockers/model.py index 22e9dce6..07c11f8b 100644 --- a/examples/boid_flockers/boid_flockers/model.py +++ b/examples/boid_flockers/boid_flockers/model.py @@ -8,8 +8,106 @@ import mesa import numpy as np -from .boid import Boid +class Boid(mesa.Agent): + """ + A Boid-style flocker agent. + + The agent follows three behaviors to flock: + - Cohesion: steering towards neighboring agents. + - Separation: avoiding getting too close to any other agent. + - Alignment: try to fly in the same direction as the neighbors. + + Boids have a vision that defines the radius in which they look for their + neighbors to flock with. Their speed (a scalar) and direction (a vector) + define their movement. Separation is their desired minimum distance from + any other Boid. + """ + + def __init__( + self, + unique_id, + model, + pos, + speed, + direction, + vision, + separation, + cohere=0.025, + separate=0.25, + match=0.04, + ): + """ + Create a new Boid flocker agent. + Args: + unique_id: Unique agent identifyer. + pos: Starting position + speed: Distance to move per step. + direction: numpy vector for the Boid's direction of movement. + vision: Radius to look around for nearby Boids. + separation: Minimum distance to maintain from other Boids. + cohere: the relative importance of matching neighbors' positions + separate: the relative importance of avoiding close neighbors + match: the relative importance of matching neighbors' headings + """ + super().__init__(unique_id, model) + self.pos = np.array(pos) + self.speed = speed + self.direction = direction + self.vision = vision + self.separation = separation + self.cohere_factor = cohere + self.separate_factor = separate + self.match_factor = match + + def cohere(self, neighbors): + """ + Return the vector toward the center of mass of the local neighbors. + """ + cohere = np.zeros(2) + if neighbors: + for neighbor in neighbors: + cohere += self.model.space.get_heading(self.pos, neighbor.pos) + cohere /= len(neighbors) + return cohere + + def separate(self, neighbors): + """ + Return a vector away from any neighbors closer than separation dist. + """ + me = self.pos + them = (n.pos for n in neighbors) + separation_vector = np.zeros(2) + for other in them: + if self.model.space.get_distance(me, other) < self.separation: + separation_vector -= self.model.space.get_heading(me, other) + return separation_vector + + def match_heading(self, neighbors): + """ + Return a vector of the neighbors' average heading. + """ + match_vector = np.zeros(2) + if neighbors: + for neighbor in neighbors: + match_vector += neighbor.direction + match_vector /= len(neighbors) + return match_vector + + def step(self): + """ + Get the Boid's neighbors, compute the new vector, and move accordingly. + """ + + neighbors = self.model.space.get_neighbors(self.pos, self.vision, False) + self.direction += ( + self.cohere(neighbors) * self.cohere_factor + + self.separate(neighbors) * self.separate_factor + + self.match_heading(neighbors) * self.match_factor + ) / 2 + self.direction /= np.linalg.norm(self.direction) + new_pos = self.pos + self.direction * self.speed + self.model.space.move_agent(self, new_pos) class BoidFlockers(mesa.Model): """ @@ -39,7 +137,8 @@ def __init__( separation: What's the minimum distance each Boid will attempt to keep from any other cohere, separate, match: factors for the relative importance of - the three drives.""" + the three drives. + """ super().__init__() self.population = population self.vision = vision @@ -49,8 +148,7 @@ def __init__( self.space = mesa.space.ContinuousSpace(width, height, True) self.factors = {"cohere": cohere, "separate": separate, "match": match} self.make_agents() - self.running = True - + def make_agents(self): """ Create self.population agents, with random positions and starting headings. @@ -59,15 +157,15 @@ def make_agents(self): x = self.random.random() * self.space.x_max y = self.random.random() * self.space.y_max pos = np.array((x, y)) - velocity = np.random.random(2) * 2 - 1 + direction = np.random.random(2) * 2 - 1 boid = Boid( - i, - self, - pos, - self.speed, - velocity, - self.vision, - self.separation, + unique_id=i, + model=self, + pos=pos, + speed=self.speed, + direction=direction, + vision=self.vision, + separation=self.separation, **self.factors, ) self.space.place_agent(boid, pos) @@ -75,3 +173,5 @@ def make_agents(self): def step(self): self.schedule.step() + + diff --git a/examples/boid_flockers/boid_flockers/server.py b/examples/boid_flockers/boid_flockers/server.py index 4906df69..105bb804 100644 --- a/examples/boid_flockers/boid_flockers/server.py +++ b/examples/boid_flockers/boid_flockers/server.py @@ -5,19 +5,57 @@ def boid_draw(agent): - return {"Shape": "circle", "r": 2, "Filled": "true", "Color": "Red"} + neighbors = agent.model.space.get_neighbors(agent.pos, agent.vision, False) + if len(neighbors)<=1: + return {"Shape": "circle", "r": 2, "Filled": "true", "Color": "Red"} + elif len(neighbors)>=2: + return {"Shape": "circle", "r": 2, "Filled": "true", "Color": "Green"} - -boid_canvas = SimpleCanvas(boid_draw, 500, 500) +boid_canvas = SimpleCanvas( + portrayal_method=boid_draw, + canvas_height=500, + canvas_width=500 + ) model_params = { - "population": 100, + "population": mesa.visualization.Slider( + name="Number of boids", + value=100, + min_value=10, + max_value=200, + step=10, + description="Choose how many agents to include in the model", + ), "width": 100, "height": 100, - "speed": 5, - "vision": 10, - "separation": 2, + "speed": mesa.visualization.Slider( + name="Speed of Boids", + value=5, + min_value=1, + max_value=20, + step=1, + description="How fast should the Boids move", + ), + "vision": mesa.visualization.Slider( + name="Vision of Bird (radius)", + value=10, + min_value=1, + max_value=50, + step=1, + description="How far around should each Boid look for its neighbors", + ), + "separation": mesa.visualization.Slider( + name="Minimum Separation", + value=2, + min_value=1, + max_value=20, + step=1, + description="What is the minimum distance each Boid will attempt to keep from any other", + ), } server = mesa.visualization.ModularServer( - BoidFlockers, [boid_canvas], "Boids", model_params -) + model_cls=BoidFlockers, + visualization_elements=[boid_canvas], + name="Boid Flocking Model", + model_params=model_params +) \ No newline at end of file diff --git a/examples/boid_flockers/boid_flockers/simple_continuous_canvas.js b/examples/boid_flockers/boid_flockers/simple_continuous_canvas.js index 20c0ded8..812cadce 100644 --- a/examples/boid_flockers/boid_flockers/simple_continuous_canvas.js +++ b/examples/boid_flockers/boid_flockers/simple_continuous_canvas.js @@ -6,7 +6,6 @@ const ContinuousVisualization = function(width, height, context) { if (p.Shape == "circle") this.drawCircle(p.x, p.y, p.r, p.Color, p.Filled); }; - }; this.drawCircle = function(x, y, radius, color, fill) { From b5364109908f4a80f9aa6a77e05d6ea36319addd Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Fri, 23 Feb 2024 14:51:30 +0530 Subject: [PATCH 2/6] Update Readme.md --- examples/boid_flockers/Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/boid_flockers/Readme.md b/examples/boid_flockers/Readme.md index c06fe36d..e3bc5c98 100644 --- a/examples/boid_flockers/Readme.md +++ b/examples/boid_flockers/Readme.md @@ -24,10 +24,10 @@ $ mesa runserver or -Directly run the file ``app.py`` in the terminal. e.g. +Directly run the file ``run.py`` in the terminal. e.g. ``` - $ python app.py + $ python run.py ``` * Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press Reset, then Run. From 4c5b702246327422466771e511433d63fca6115b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:09:37 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/boid_flockers/Readme.md | 2 +- .../boid_flockers/SimpleContinuousModule.py | 2 +- examples/boid_flockers/boid_flockers/model.py | 6 +++--- .../boid_flockers/boid_flockers/server.py | 21 +++++++++---------- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/examples/boid_flockers/Readme.md b/examples/boid_flockers/Readme.md index e3bc5c98..d1f4a987 100644 --- a/examples/boid_flockers/Readme.md +++ b/examples/boid_flockers/Readme.md @@ -22,7 +22,7 @@ To install the dependencies use pip and the requirements.txt in this directory. $ mesa runserver ``` -or +or Directly run the file ``run.py`` in the terminal. e.g. diff --git a/examples/boid_flockers/boid_flockers/SimpleContinuousModule.py b/examples/boid_flockers/boid_flockers/SimpleContinuousModule.py index 7d761bac..eabf077c 100644 --- a/examples/boid_flockers/boid_flockers/SimpleContinuousModule.py +++ b/examples/boid_flockers/boid_flockers/SimpleContinuousModule.py @@ -3,7 +3,7 @@ class SimpleCanvas(mesa.visualization.VisualizationElement): local_includes = ["boid_flockers/simple_continuous_canvas.js"] - + def __init__(self, portrayal_method=None, canvas_height=500, canvas_width=500): """ Instantiate a new SimpleCanvas diff --git a/examples/boid_flockers/boid_flockers/model.py b/examples/boid_flockers/boid_flockers/model.py index 07c11f8b..14d8c9ae 100644 --- a/examples/boid_flockers/boid_flockers/model.py +++ b/examples/boid_flockers/boid_flockers/model.py @@ -8,6 +8,7 @@ import mesa import numpy as np + class Boid(mesa.Agent): """ A Boid-style flocker agent. @@ -109,6 +110,7 @@ def step(self): new_pos = self.pos + self.direction * self.speed self.model.space.move_agent(self, new_pos) + class BoidFlockers(mesa.Model): """ Flocker model class. Handles agent creation, placement and scheduling. @@ -148,7 +150,7 @@ def __init__( self.space = mesa.space.ContinuousSpace(width, height, True) self.factors = {"cohere": cohere, "separate": separate, "match": match} self.make_agents() - + def make_agents(self): """ Create self.population agents, with random positions and starting headings. @@ -173,5 +175,3 @@ def make_agents(self): def step(self): self.schedule.step() - - diff --git a/examples/boid_flockers/boid_flockers/server.py b/examples/boid_flockers/boid_flockers/server.py index 105bb804..3764ca2d 100644 --- a/examples/boid_flockers/boid_flockers/server.py +++ b/examples/boid_flockers/boid_flockers/server.py @@ -6,16 +6,15 @@ def boid_draw(agent): neighbors = agent.model.space.get_neighbors(agent.pos, agent.vision, False) - if len(neighbors)<=1: + if len(neighbors) <= 1: return {"Shape": "circle", "r": 2, "Filled": "true", "Color": "Red"} - elif len(neighbors)>=2: + elif len(neighbors) >= 2: return {"Shape": "circle", "r": 2, "Filled": "true", "Color": "Green"} + boid_canvas = SimpleCanvas( - portrayal_method=boid_draw, - canvas_height=500, - canvas_width=500 - ) + portrayal_method=boid_draw, canvas_height=500, canvas_width=500 +) model_params = { "population": mesa.visualization.Slider( name="Number of boids", @@ -54,8 +53,8 @@ def boid_draw(agent): } server = mesa.visualization.ModularServer( - model_cls=BoidFlockers, - visualization_elements=[boid_canvas], - name="Boid Flocking Model", - model_params=model_params -) \ No newline at end of file + model_cls=BoidFlockers, + visualization_elements=[boid_canvas], + name="Boid Flocking Model", + model_params=model_params, +) From 4c2d1e9c5af5a30950b2417ce537da564b61ee27 Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Sat, 24 Feb 2024 18:15:06 +0530 Subject: [PATCH 4/6] Update model.py --- examples/boid_flockers/boid_flockers/model.py | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/examples/boid_flockers/boid_flockers/model.py b/examples/boid_flockers/boid_flockers/model.py index 14d8c9ae..1f6ddb49 100644 --- a/examples/boid_flockers/boid_flockers/model.py +++ b/examples/boid_flockers/boid_flockers/model.py @@ -8,7 +8,6 @@ import mesa import numpy as np - class Boid(mesa.Agent): """ A Boid-style flocker agent. @@ -60,39 +59,40 @@ def __init__( self.cohere_factor = cohere self.separate_factor = separate self.match_factor = match + self.neighbors = None - def cohere(self, neighbors): + def cohere(self): """ Return the vector toward the center of mass of the local neighbors. """ cohere = np.zeros(2) - if neighbors: - for neighbor in neighbors: + if self.neighbors: + for neighbor in self.neighbors: cohere += self.model.space.get_heading(self.pos, neighbor.pos) - cohere /= len(neighbors) + cohere /= len(self.neighbors) return cohere - def separate(self, neighbors): + def separate(self): """ Return a vector away from any neighbors closer than separation dist. """ me = self.pos - them = (n.pos for n in neighbors) + them = (n.pos for n in self.neighbors) separation_vector = np.zeros(2) for other in them: if self.model.space.get_distance(me, other) < self.separation: separation_vector -= self.model.space.get_heading(me, other) return separation_vector - def match_heading(self, neighbors): + def match_heading(self): """ Return a vector of the neighbors' average heading. """ match_vector = np.zeros(2) - if neighbors: - for neighbor in neighbors: + if self.neighbors: + for neighbor in self.neighbors: match_vector += neighbor.direction - match_vector /= len(neighbors) + match_vector /= len(self.neighbors) return match_vector def step(self): @@ -100,17 +100,16 @@ def step(self): Get the Boid's neighbors, compute the new vector, and move accordingly. """ - neighbors = self.model.space.get_neighbors(self.pos, self.vision, False) + self.neighbors = self.model.space.get_neighbors(self.pos, self.vision, False) self.direction += ( - self.cohere(neighbors) * self.cohere_factor - + self.separate(neighbors) * self.separate_factor - + self.match_heading(neighbors) * self.match_factor + self.cohere() * self.cohere_factor + + self.separate() * self.separate_factor + + self.match_heading() * self.match_factor ) / 2 self.direction /= np.linalg.norm(self.direction) new_pos = self.pos + self.direction * self.speed self.model.space.move_agent(self, new_pos) - class BoidFlockers(mesa.Model): """ Flocker model class. Handles agent creation, placement and scheduling. From 6233f74f81633dcf432e94204ad48783b3e3ece8 Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Sat, 24 Feb 2024 18:17:02 +0530 Subject: [PATCH 5/6] Update server.py --- examples/boid_flockers/boid_flockers/server.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/boid_flockers/boid_flockers/server.py b/examples/boid_flockers/boid_flockers/server.py index 3764ca2d..90d534ca 100644 --- a/examples/boid_flockers/boid_flockers/server.py +++ b/examples/boid_flockers/boid_flockers/server.py @@ -5,10 +5,14 @@ def boid_draw(agent): - neighbors = agent.model.space.get_neighbors(agent.pos, agent.vision, False) - if len(neighbors) <= 1: + if not agent.neighbors: # Only for the first Frame + neighbors = len(agent.model.space.get_neighbors(agent.pos, agent.vision, False)) + else: + neighbors = len(agent.neighbors) + + if neighbors <= 1: return {"Shape": "circle", "r": 2, "Filled": "true", "Color": "Red"} - elif len(neighbors) >= 2: + elif neighbors >= 2: return {"Shape": "circle", "r": 2, "Filled": "true", "Color": "Green"} From 59dd129745723304390bad2e4d35286d6021b720 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 24 Feb 2024 17:16:55 +0000 Subject: [PATCH 6/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/boid_flockers/boid_flockers/model.py | 2 ++ examples/boid_flockers/boid_flockers/server.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/boid_flockers/boid_flockers/model.py b/examples/boid_flockers/boid_flockers/model.py index 1f6ddb49..ff443b52 100644 --- a/examples/boid_flockers/boid_flockers/model.py +++ b/examples/boid_flockers/boid_flockers/model.py @@ -8,6 +8,7 @@ import mesa import numpy as np + class Boid(mesa.Agent): """ A Boid-style flocker agent. @@ -110,6 +111,7 @@ def step(self): new_pos = self.pos + self.direction * self.speed self.model.space.move_agent(self, new_pos) + class BoidFlockers(mesa.Model): """ Flocker model class. Handles agent creation, placement and scheduling. diff --git a/examples/boid_flockers/boid_flockers/server.py b/examples/boid_flockers/boid_flockers/server.py index 90d534ca..190c6533 100644 --- a/examples/boid_flockers/boid_flockers/server.py +++ b/examples/boid_flockers/boid_flockers/server.py @@ -5,11 +5,11 @@ def boid_draw(agent): - if not agent.neighbors: # Only for the first Frame + if not agent.neighbors: # Only for the first Frame neighbors = len(agent.model.space.get_neighbors(agent.pos, agent.vision, False)) else: neighbors = len(agent.neighbors) - + if neighbors <= 1: return {"Shape": "circle", "r": 2, "Filled": "true", "Color": "Red"} elif neighbors >= 2: