We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Grid move_agent to same position
Grid's move_agent method errors out when trying to move the agent to the same position.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mesa/space.py`
Content:
```
1 '''
2 Mesa Space Module
3 =================================
4 
5 Objects used to add a spatial component to a model.
6 
7 Grid: base grid, a simple list-of-lists.
8 SingleGrid: grid which strictly enforces one object per cell.
9 MultiGrid: extension to Grid where each cell is a set of objects.
10 
11 '''
12 # Instruction for PyLint to suppress variable name errors, since we have a
13 # good reason to use one-character variable names for x and y.
14 # pylint: disable=invalid-name
15 
16 import itertools
17 import random
18 
19 
20 RANDOM = -1
21 
22 X = 0
23 Y = 1
24 
25 
26 class Grid(object):
27     '''
28     Base class for a square grid.
29 
30     Grid cells are indexed by [y][x], where [0][0] is assumed to be -- top-left
31     and [height-1][width-1] is the bottom-right. If a grid is toroidal, the top
32     and bottom, and left and right, edges wrap to each other
33 
34     Properties:
35         width, height: The grid's width and height.
36         torus: Boolean which determines whether to treat the grid as a torus.
37 
38         grid: Internal list-of-lists which holds the grid cells themselves.
39         default_val: Lambda function to populate each grid cell with None.
40 
41     Methods:
42         get_neighbors: Returns the objects surrounding a given cell.
43         get_neighborhood: Returns the cells surrounding a given cell.
44         get_cell_list_contents: Returns the contents of a list of cells
45             ((x,y) tuples)
46     '''
47 
48     default_val = lambda s: None
49 
50     class CoordIter:
51         """
52         An iterator that returns the coordinates of a cell along with its
53         contents.
54         """
55 
56         def __init__(self, grid):
57             self.grid = grid
58             self.x = 0
59             self.y = 0
60 
61         def __iter__(self):
62             return self
63 
64         def __next__(self):
65             while self.y < self.grid.height:
66                 while self.x < self.grid.width:
67                     ret = [self.grid[self.y][self.x],
68                            self.x, self.y]
69                     self.x += 1
70                     return ret
71                 self.x = 0
72                 self.y += 1
73             else:
74                 raise StopIteration()
75 
76     def __init__(self, height, width, torus):
77         '''
78         Create a new grid.
79 
80         Args:
81             height, width: The height and width of the grid
82             torus: Boolean whether the grid wraps or not.
83         '''
84         self.height = height
85         self.width = width
86         self.torus = torus
87 
88         self.grid = []
89         self.empties = []
90 
91         for y in range(self.height):
92             row = []
93             for x in range(self.width):
94                 row.append(self.default_val())
95             self.grid.append(row)
96 
97     def __getitem__(self, index):
98         return self.grid[index]
99 
100     def __iter__(self):
101         # create an iterator that chains the
102         #  rows of grid together as if one list:
103         return itertools.chain(*self.grid)
104 
105     def coord_iter(self):
106         """
107         An iterator that returns coordinates as well as cell contents.
108         """
109         return Grid.CoordIter(self)
110 
111     def neighbor_iter(self, x, y, moore=True, torus=False):
112         """
113         Iterate over our neighbors.
114         """
115         neighbors = self.get_neighbors(x, y, moore=moore)
116         return iter(neighbors)
117 
118     def get_neighborhood(self, x, y, moore,
119                          include_center=False, radius=1):
120         """
121         Return a list of cells that are in the
122         neighborhood of a certain point.
123 
124         Args:
125             x, y: Coordinates for the neighborhood to get.
126             moore: If True, return Moore neighborhood
127                         (including diagonals)
128                    If False, return Von Neumann neighborhood
129                         (exclude diagonals)
130             include_center: If True, return the (x, y) cell as well.
131                             Otherwise, return surrounding cells only.
132             radius: radius, in cells, of neighborhood to get.
133 
134         Returns:
135             A list of coordinate tuples representing the neighborhood;
136                 With radius 1, at most 9 if
137                 Moore, 5 if Von Neumann
138                 (8 and 4 if not including the center).
139         """
140         coordinates = set()
141         for dy in range(-radius, radius + 1):
142             for dx in range(-radius, radius + 1):
143                 if dx == 0 and dy == 0 and not include_center:
144                     continue
145                 if not moore:
146                     # Skip diagonals in Von Neumann neighborhood.
147                     if dy != 0 and dx != 0:
148                         continue
149 
150                 px = self.torus_adj(x + dx, self.width)
151                 py = self.torus_adj(y + dy, self.height)
152 
153                 # Skip if new coords out of bounds.
154                 if(self.out_of_bounds(px, py)):
155                     continue
156 
157                 coordinates.add((px, py))
158         return list(coordinates)
159 
160     def get_neighbors(self, x, y, moore,
161                       include_center=False, radius=1):
162         """
163         Return a list of neighbors to a certain point.
164 
165         Args:
166             x, y: Coordinates for the neighborhood to get.
167             moore: If True, return Moore neighborhood
168                     (including diagonals)
169                    If False, return Von Neumann neighborhood
170                      (exclude diagonals)
171             include_center: If True, return the (x, y) cell as well.
172                             Otherwise,
173                             return surrounding cells only.
174             radius: radius, in cells, of neighborhood to get.
175 
176         Returns:
177             A list of non-None objects in the given neighborhood;
178             at most 9 if Moore, 5 if Von-Neumann
179             (8 and 4 if not including the center).
180         """
181         neighborhood = self.get_neighborhood(x, y, moore,
182                                              include_center,
183                                              radius)
184         return self.get_cell_list_contents(neighborhood)
185 
186     def torus_adj(self, coord, dim_len):
187         """
188         Convert coordinate, handling torus looping.
189         """
190         if self.torus:
191             coord %= dim_len
192         return coord
193 
194     def out_of_bounds(self, x, y):
195         """
196         Is point x, y off the grid?
197         """
198         return(x < 0 or x >= self.width
199                or y < 0 or y >= self.height)
200 
201     def get_cell_list_contents(self, cell_list):
202         '''
203         Args:
204             cell_list: Array-like of (x, y) tuples
205 
206         Returns:
207             A list of the contents of the cells identified in cell_list
208         '''
209         contents = []
210         for x, y in cell_list:
211             self._add_members(contents, x, y)
212         return contents
213 
214     def move_agent(self, agent, pos):
215         '''
216         Move an agent from its current position to a new position.
217 
218         Args:
219             agent: Agent object to move. Assumed to have its current location
220                    stored in a 'pos' tuple.
221             pos: Tuple of new position to move the agent to.
222         '''
223 
224         self._place_agent(pos, agent)
225         self._remove_agent(agent.pos, agent)
226         agent.pos = pos
227 
228     def place_agent(self, agent, pos):
229         '''
230         Position an agent on the grid, and set its pos variable.
231         '''
232         self._place_agent(pos, agent)
233         agent.pos = pos
234 
235     def _place_agent(self, coords, agent):
236         '''
237         Place the agent at the correct location.
238         '''
239         x, y = coords
240         self.grid[y][x] = agent
241 
242     def _remove_agent(self, coords, agent):
243         '''
244         Remove the agent from the given location.
245         '''
246         x, y = coords
247         self.grid[y][x] = None
248 
249     def _add_members(self, target_list, x, y):
250         '''
251         Helper method to append the contents of a cell to the given list.
252         Override for other grid types.
253         '''
254         if self.grid[y][x] is not None:
255             target_list.append(self.grid[y][x])
256 
257     def is_cell_empty(self, coords):
258         x, y = coords
259         return True if self.grid[y][x] == self.default_val() else False
260 
261 
262 class SingleGrid(Grid):
263     '''
264     Grid where each cell contains exactly at most one object.
265     '''
266 
267     def __init__(self, height, width, torus):
268         '''
269         Create a new single-item grid.
270 
271         Args:
272             height, width: The height and width of the grid
273             torus: Boolean whether the grid wraps or not.
274         '''
275         super().__init__(height, width, torus)
276         # Add all cells to the empties list.
277         self.empties = list(itertools.product(
278                             *(range(self.width), range(self.height))))
279 
280     def move_to_empty(self, agent):
281         """
282         Moves agent to a random empty cell, vacating agent's old cell.
283         """
284         coords = agent.pos
285         new_coords = self.find_empty()
286         if new_coords is None:
287             raise Exception("ERROR: No empty cells")
288         else:
289             self._place_agent(new_coords, agent)
290             agent.pos = new_coords
291             self._remove_agent(coords, agent)
292 
293     def find_empty(self):
294         '''
295         Pick a random empty cell.
296         '''
297         if self.exists_empty_cells():
298             coords = random.choice(self.empties)
299             return coords
300         else:
301             return None
302 
303     def exists_empty_cells(self):
304         """
305         Return True if any cells empty else False.
306         """
307         return len(self.empties) > 0
308 
309     def position_agent(self, agent, x=RANDOM, y=RANDOM):
310         """
311         Position an agent on the grid.
312         This is used when first placing agents! Use 'move_to_empty()'
313         when you want agents to jump to an empty cell.
314         Use 'swap_pos()' to swap agents positions.
315         If x or y are positive, they are used, but if RANDOM,
316         we get a random position.
317         Ensure this random position is not occupied (in Grid).
318         """
319         if x == RANDOM or y == RANDOM:
320             coords = self.find_empty()
321             if coords is None:
322                 raise Exception("ERROR: Grid full")
323         else:
324             coords = (x, y)
325         agent.pos = coords
326         self._place_agent(coords, agent)
327 
328     def _place_agent(self, coords, agent):
329         if self.is_cell_empty(coords):
330             super()._place_agent(coords, agent)
331             self.empties.remove(coords)
332         else:
333             raise Exception("Cell not empty")
334 
335     def _remove_agent(self, coords, agent):
336         super()._remove_agent(coords, agent)
337         self.empties.append(coords)
338 
339 
340 class MultiGrid(Grid):
341     '''
342     Grid where each cell can contain more than one object.
343 
344     Grid cells are indexed by [y][x], where [0][0] is assumed to be -- top-left
345     and [height-1][width-1] is the bottom-right. If a grid is toroidal, the top
346     and bottom, and left and right, edges wrap to each other.
347 
348     Each grid cell holds a set object.
349 
350     Properties:
351         width, height: The grid's width and height.
352 
353         torus: Boolean which determines whether to treat the grid as a torus.
354 
355         grid: Internal list-of-lists which holds the grid cells themselves.
356         default_val: Lambda function to populate grid cells with an empty set.
357 
358     Methods:
359         get_neighbors: Returns the objects surrounding a given cell.
360     '''
361 
362     default_val = lambda s: set()
363 
364     def _place_agent(self, coords, agent):
365         '''
366         Place the agent at the correct location.
367         '''
368         x, y = coords
369         self.grid[y][x].add(agent)
370 
371     def _remove_agent(self, coords, agent):
372         '''
373         Remove the agent from the given location.
374         '''
375         x, y = coords
376         self.grid[y][x].remove(agent)
377 
378     def _add_members(self, target_list, x, y):
379         '''
380         Helper method to add all objects in the given cell to the target_list.
381         '''
382         for a in self.grid[y][x]:
383             target_list.append(a)
384
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mesa/space.py b/mesa/space.py
--- a/mesa/space.py
+++ b/mesa/space.py
@@ -220,9 +220,8 @@
                    stored in a 'pos' tuple.
             pos: Tuple of new position to move the agent to.
         '''
-
-        self._place_agent(pos, agent)
         self._remove_agent(agent.pos, agent)
+        self._place_agent(pos, agent)
         agent.pos = pos
 
     def place_agent(self, agent, pos):

{"golden_diff": "diff --git a/mesa/space.py b/mesa/space.py\n--- a/mesa/space.py\n+++ b/mesa/space.py\n@@ -220,9 +220,8 @@\n                    stored in a 'pos' tuple.\n             pos: Tuple of new position to move the agent to.\n         '''\n-\n-        self._place_agent(pos, agent)\n         self._remove_agent(agent.pos, agent)\n+        self._place_agent(pos, agent)\n         agent.pos = pos\n \n     def place_agent(self, agent, pos):\n", "issue": "Grid move_agent to same position\nGrid's move_agent method errors out when trying to move the agent to the same position.\n\n", "before_files": [{"content": "'''\nMesa Space Module\n=================================\n\nObjects used to add a spatial component to a model.\n\nGrid: base grid, a simple list-of-lists.\nSingleGrid: grid which strictly enforces one object per cell.\nMultiGrid: extension to Grid where each cell is a set of objects.\n\n'''\n# Instruction for PyLint to suppress variable name errors, since we have a\n# good reason to use one-character variable names for x and y.\n# pylint: disable=invalid-name\n\nimport itertools\nimport random\n\n\nRANDOM = -1\n\nX = 0\nY = 1\n\n\nclass Grid(object):\n    '''\n    Base class for a square grid.\n\n    Grid cells are indexed by [y][x], where [0][0] is assumed to be -- top-left\n    and [height-1][width-1] is the bottom-right. If a grid is toroidal, the top\n    and bottom, and left and right, edges wrap to each other\n\n    Properties:\n        width, height: The grid's width and height.\n        torus: Boolean which determines whether to treat the grid as a torus.\n\n        grid: Internal list-of-lists which holds the grid cells themselves.\n        default_val: Lambda function to populate each grid cell with None.\n\n    Methods:\n        get_neighbors: Returns the objects surrounding a given cell.\n        get_neighborhood: Returns the cells surrounding a given cell.\n        get_cell_list_contents: Returns the contents of a list of cells\n            ((x,y) tuples)\n    '''\n\n    default_val = lambda s: None\n\n    class CoordIter:\n        \"\"\"\n        An iterator that returns the coordinates of a cell along with its\n        contents.\n        \"\"\"\n\n        def __init__(self, grid):\n            self.grid = grid\n            self.x = 0\n            self.y = 0\n\n        def __iter__(self):\n            return self\n\n        def __next__(self):\n            while self.y < self.grid.height:\n                while self.x < self.grid.width:\n                    ret = [self.grid[self.y][self.x],\n                           self.x, self.y]\n                    self.x += 1\n                    return ret\n                self.x = 0\n                self.y += 1\n            else:\n                raise StopIteration()\n\n    def __init__(self, height, width, torus):\n        '''\n        Create a new grid.\n\n        Args:\n            height, width: The height and width of the grid\n            torus: Boolean whether the grid wraps or not.\n        '''\n        self.height = height\n        self.width = width\n        self.torus = torus\n\n        self.grid = []\n        self.empties = []\n\n        for y in range(self.height):\n            row = []\n            for x in range(self.width):\n                row.append(self.default_val())\n            self.grid.append(row)\n\n    def __getitem__(self, index):\n        return self.grid[index]\n\n    def __iter__(self):\n        # create an iterator that chains the\n        #  rows of grid together as if one list:\n        return itertools.chain(*self.grid)\n\n    def coord_iter(self):\n        \"\"\"\n        An iterator that returns coordinates as well as cell contents.\n        \"\"\"\n        return Grid.CoordIter(self)\n\n    def neighbor_iter(self, x, y, moore=True, torus=False):\n        \"\"\"\n        Iterate over our neighbors.\n        \"\"\"\n        neighbors = self.get_neighbors(x, y, moore=moore)\n        return iter(neighbors)\n\n    def get_neighborhood(self, x, y, moore,\n                         include_center=False, radius=1):\n        \"\"\"\n        Return a list of cells that are in the\n        neighborhood of a certain point.\n\n        Args:\n            x, y: Coordinates for the neighborhood to get.\n            moore: If True, return Moore neighborhood\n                        (including diagonals)\n                   If False, return Von Neumann neighborhood\n                        (exclude diagonals)\n            include_center: If True, return the (x, y) cell as well.\n                            Otherwise, return surrounding cells only.\n            radius: radius, in cells, of neighborhood to get.\n\n        Returns:\n            A list of coordinate tuples representing the neighborhood;\n                With radius 1, at most 9 if\n                Moore, 5 if Von Neumann\n                (8 and 4 if not including the center).\n        \"\"\"\n        coordinates = set()\n        for dy in range(-radius, radius + 1):\n            for dx in range(-radius, radius + 1):\n                if dx == 0 and dy == 0 and not include_center:\n                    continue\n                if not moore:\n                    # Skip diagonals in Von Neumann neighborhood.\n                    if dy != 0 and dx != 0:\n                        continue\n\n                px = self.torus_adj(x + dx, self.width)\n                py = self.torus_adj(y + dy, self.height)\n\n                # Skip if new coords out of bounds.\n                if(self.out_of_bounds(px, py)):\n                    continue\n\n                coordinates.add((px, py))\n        return list(coordinates)\n\n    def get_neighbors(self, x, y, moore,\n                      include_center=False, radius=1):\n        \"\"\"\n        Return a list of neighbors to a certain point.\n\n        Args:\n            x, y: Coordinates for the neighborhood to get.\n            moore: If True, return Moore neighborhood\n                    (including diagonals)\n                   If False, return Von Neumann neighborhood\n                     (exclude diagonals)\n            include_center: If True, return the (x, y) cell as well.\n                            Otherwise,\n                            return surrounding cells only.\n            radius: radius, in cells, of neighborhood to get.\n\n        Returns:\n            A list of non-None objects in the given neighborhood;\n            at most 9 if Moore, 5 if Von-Neumann\n            (8 and 4 if not including the center).\n        \"\"\"\n        neighborhood = self.get_neighborhood(x, y, moore,\n                                             include_center,\n                                             radius)\n        return self.get_cell_list_contents(neighborhood)\n\n    def torus_adj(self, coord, dim_len):\n        \"\"\"\n        Convert coordinate, handling torus looping.\n        \"\"\"\n        if self.torus:\n            coord %= dim_len\n        return coord\n\n    def out_of_bounds(self, x, y):\n        \"\"\"\n        Is point x, y off the grid?\n        \"\"\"\n        return(x < 0 or x >= self.width\n               or y < 0 or y >= self.height)\n\n    def get_cell_list_contents(self, cell_list):\n        '''\n        Args:\n            cell_list: Array-like of (x, y) tuples\n\n        Returns:\n            A list of the contents of the cells identified in cell_list\n        '''\n        contents = []\n        for x, y in cell_list:\n            self._add_members(contents, x, y)\n        return contents\n\n    def move_agent(self, agent, pos):\n        '''\n        Move an agent from its current position to a new position.\n\n        Args:\n            agent: Agent object to move. Assumed to have its current location\n                   stored in a 'pos' tuple.\n            pos: Tuple of new position to move the agent to.\n        '''\n\n        self._place_agent(pos, agent)\n        self._remove_agent(agent.pos, agent)\n        agent.pos = pos\n\n    def place_agent(self, agent, pos):\n        '''\n        Position an agent on the grid, and set its pos variable.\n        '''\n        self._place_agent(pos, agent)\n        agent.pos = pos\n\n    def _place_agent(self, coords, agent):\n        '''\n        Place the agent at the correct location.\n        '''\n        x, y = coords\n        self.grid[y][x] = agent\n\n    def _remove_agent(self, coords, agent):\n        '''\n        Remove the agent from the given location.\n        '''\n        x, y = coords\n        self.grid[y][x] = None\n\n    def _add_members(self, target_list, x, y):\n        '''\n        Helper method to append the contents of a cell to the given list.\n        Override for other grid types.\n        '''\n        if self.grid[y][x] is not None:\n            target_list.append(self.grid[y][x])\n\n    def is_cell_empty(self, coords):\n        x, y = coords\n        return True if self.grid[y][x] == self.default_val() else False\n\n\nclass SingleGrid(Grid):\n    '''\n    Grid where each cell contains exactly at most one object.\n    '''\n\n    def __init__(self, height, width, torus):\n        '''\n        Create a new single-item grid.\n\n        Args:\n            height, width: The height and width of the grid\n            torus: Boolean whether the grid wraps or not.\n        '''\n        super().__init__(height, width, torus)\n        # Add all cells to the empties list.\n        self.empties = list(itertools.product(\n                            *(range(self.width), range(self.height))))\n\n    def move_to_empty(self, agent):\n        \"\"\"\n        Moves agent to a random empty cell, vacating agent's old cell.\n        \"\"\"\n        coords = agent.pos\n        new_coords = self.find_empty()\n        if new_coords is None:\n            raise Exception(\"ERROR: No empty cells\")\n        else:\n            self._place_agent(new_coords, agent)\n            agent.pos = new_coords\n            self._remove_agent(coords, agent)\n\n    def find_empty(self):\n        '''\n        Pick a random empty cell.\n        '''\n        if self.exists_empty_cells():\n            coords = random.choice(self.empties)\n            return coords\n        else:\n            return None\n\n    def exists_empty_cells(self):\n        \"\"\"\n        Return True if any cells empty else False.\n        \"\"\"\n        return len(self.empties) > 0\n\n    def position_agent(self, agent, x=RANDOM, y=RANDOM):\n        \"\"\"\n        Position an agent on the grid.\n        This is used when first placing agents! Use 'move_to_empty()'\n        when you want agents to jump to an empty cell.\n        Use 'swap_pos()' to swap agents positions.\n        If x or y are positive, they are used, but if RANDOM,\n        we get a random position.\n        Ensure this random position is not occupied (in Grid).\n        \"\"\"\n        if x == RANDOM or y == RANDOM:\n            coords = self.find_empty()\n            if coords is None:\n                raise Exception(\"ERROR: Grid full\")\n        else:\n            coords = (x, y)\n        agent.pos = coords\n        self._place_agent(coords, agent)\n\n    def _place_agent(self, coords, agent):\n        if self.is_cell_empty(coords):\n            super()._place_agent(coords, agent)\n            self.empties.remove(coords)\n        else:\n            raise Exception(\"Cell not empty\")\n\n    def _remove_agent(self, coords, agent):\n        super()._remove_agent(coords, agent)\n        self.empties.append(coords)\n\n\nclass MultiGrid(Grid):\n    '''\n    Grid where each cell can contain more than one object.\n\n    Grid cells are indexed by [y][x], where [0][0] is assumed to be -- top-left\n    and [height-1][width-1] is the bottom-right. If a grid is toroidal, the top\n    and bottom, and left and right, edges wrap to each other.\n\n    Each grid cell holds a set object.\n\n    Properties:\n        width, height: The grid's width and height.\n\n        torus: Boolean which determines whether to treat the grid as a torus.\n\n        grid: Internal list-of-lists which holds the grid cells themselves.\n        default_val: Lambda function to populate grid cells with an empty set.\n\n    Methods:\n        get_neighbors: Returns the objects surrounding a given cell.\n    '''\n\n    default_val = lambda s: set()\n\n    def _place_agent(self, coords, agent):\n        '''\n        Place the agent at the correct location.\n        '''\n        x, y = coords\n        self.grid[y][x].add(agent)\n\n    def _remove_agent(self, coords, agent):\n        '''\n        Remove the agent from the given location.\n        '''\n        x, y = coords\n        self.grid[y][x].remove(agent)\n\n    def _add_members(self, target_list, x, y):\n        '''\n        Helper method to add all objects in the given cell to the target_list.\n        '''\n        for a in self.grid[y][x]:\n            target_list.append(a)\n", "path": "mesa/space.py"}], "after_files": [{"content": "'''\nMesa Space Module\n=================================\n\nObjects used to add a spatial component to a model.\n\nGrid: base grid, a simple list-of-lists.\nSingleGrid: grid which strictly enforces one object per cell.\nMultiGrid: extension to Grid where each cell is a set of objects.\n\n'''\n# Instruction for PyLint to suppress variable name errors, since we have a\n# good reason to use one-character variable names for x and y.\n# pylint: disable=invalid-name\n\nimport itertools\nimport random\n\n\nRANDOM = -1\n\nX = 0\nY = 1\n\n\nclass Grid(object):\n    '''\n    Base class for a square grid.\n\n    Grid cells are indexed by [y][x], where [0][0] is assumed to be -- top-left\n    and [height-1][width-1] is the bottom-right. If a grid is toroidal, the top\n    and bottom, and left and right, edges wrap to each other\n\n    Properties:\n        width, height: The grid's width and height.\n        torus: Boolean which determines whether to treat the grid as a torus.\n\n        grid: Internal list-of-lists which holds the grid cells themselves.\n        default_val: Lambda function to populate each grid cell with None.\n\n    Methods:\n        get_neighbors: Returns the objects surrounding a given cell.\n        get_neighborhood: Returns the cells surrounding a given cell.\n        get_cell_list_contents: Returns the contents of a list of cells\n            ((x,y) tuples)\n    '''\n\n    default_val = lambda s: None\n\n    class CoordIter:\n        \"\"\"\n        An iterator that returns the coordinates of a cell along with its\n        contents.\n        \"\"\"\n\n        def __init__(self, grid):\n            self.grid = grid\n            self.x = 0\n            self.y = 0\n\n        def __iter__(self):\n            return self\n\n        def __next__(self):\n            while self.y < self.grid.height:\n                while self.x < self.grid.width:\n                    ret = [self.grid[self.y][self.x],\n                           self.x, self.y]\n                    self.x += 1\n                    return ret\n                self.x = 0\n                self.y += 1\n            else:\n                raise StopIteration()\n\n    def __init__(self, height, width, torus):\n        '''\n        Create a new grid.\n\n        Args:\n            height, width: The height and width of the grid\n            torus: Boolean whether the grid wraps or not.\n        '''\n        self.height = height\n        self.width = width\n        self.torus = torus\n\n        self.grid = []\n        self.empties = []\n\n        for y in range(self.height):\n            row = []\n            for x in range(self.width):\n                row.append(self.default_val())\n            self.grid.append(row)\n\n    def __getitem__(self, index):\n        return self.grid[index]\n\n    def __iter__(self):\n        # create an iterator that chains the\n        #  rows of grid together as if one list:\n        return itertools.chain(*self.grid)\n\n    def coord_iter(self):\n        \"\"\"\n        An iterator that returns coordinates as well as cell contents.\n        \"\"\"\n        return Grid.CoordIter(self)\n\n    def neighbor_iter(self, x, y, moore=True, torus=False):\n        \"\"\"\n        Iterate over our neighbors.\n        \"\"\"\n        neighbors = self.get_neighbors(x, y, moore=moore)\n        return iter(neighbors)\n\n    def get_neighborhood(self, x, y, moore,\n                         include_center=False, radius=1):\n        \"\"\"\n        Return a list of cells that are in the\n        neighborhood of a certain point.\n\n        Args:\n            x, y: Coordinates for the neighborhood to get.\n            moore: If True, return Moore neighborhood\n                        (including diagonals)\n                   If False, return Von Neumann neighborhood\n                        (exclude diagonals)\n            include_center: If True, return the (x, y) cell as well.\n                            Otherwise, return surrounding cells only.\n            radius: radius, in cells, of neighborhood to get.\n\n        Returns:\n            A list of coordinate tuples representing the neighborhood;\n                With radius 1, at most 9 if\n                Moore, 5 if Von Neumann\n                (8 and 4 if not including the center).\n        \"\"\"\n        coordinates = set()\n        for dy in range(-radius, radius + 1):\n            for dx in range(-radius, radius + 1):\n                if dx == 0 and dy == 0 and not include_center:\n                    continue\n                if not moore:\n                    # Skip diagonals in Von Neumann neighborhood.\n                    if dy != 0 and dx != 0:\n                        continue\n\n                px = self.torus_adj(x + dx, self.width)\n                py = self.torus_adj(y + dy, self.height)\n\n                # Skip if new coords out of bounds.\n                if(self.out_of_bounds(px, py)):\n                    continue\n\n                coordinates.add((px, py))\n        return list(coordinates)\n\n    def get_neighbors(self, x, y, moore,\n                      include_center=False, radius=1):\n        \"\"\"\n        Return a list of neighbors to a certain point.\n\n        Args:\n            x, y: Coordinates for the neighborhood to get.\n            moore: If True, return Moore neighborhood\n                    (including diagonals)\n                   If False, return Von Neumann neighborhood\n                     (exclude diagonals)\n            include_center: If True, return the (x, y) cell as well.\n                            Otherwise,\n                            return surrounding cells only.\n            radius: radius, in cells, of neighborhood to get.\n\n        Returns:\n            A list of non-None objects in the given neighborhood;\n            at most 9 if Moore, 5 if Von-Neumann\n            (8 and 4 if not including the center).\n        \"\"\"\n        neighborhood = self.get_neighborhood(x, y, moore,\n                                             include_center,\n                                             radius)\n        return self.get_cell_list_contents(neighborhood)\n\n    def torus_adj(self, coord, dim_len):\n        \"\"\"\n        Convert coordinate, handling torus looping.\n        \"\"\"\n        if self.torus:\n            coord %= dim_len\n        return coord\n\n    def out_of_bounds(self, x, y):\n        \"\"\"\n        Is point x, y off the grid?\n        \"\"\"\n        return(x < 0 or x >= self.width\n               or y < 0 or y >= self.height)\n\n    def get_cell_list_contents(self, cell_list):\n        '''\n        Args:\n            cell_list: Array-like of (x, y) tuples\n\n        Returns:\n            A list of the contents of the cells identified in cell_list\n        '''\n        contents = []\n        for x, y in cell_list:\n            self._add_members(contents, x, y)\n        return contents\n\n    def move_agent(self, agent, pos):\n        '''\n        Move an agent from its current position to a new position.\n\n        Args:\n            agent: Agent object to move. Assumed to have its current location\n                   stored in a 'pos' tuple.\n            pos: Tuple of new position to move the agent to.\n        '''\n        self._remove_agent(agent.pos, agent)\n        self._place_agent(pos, agent)\n        agent.pos = pos\n\n    def place_agent(self, agent, pos):\n        '''\n        Position an agent on the grid, and set its pos variable.\n        '''\n        self._place_agent(pos, agent)\n        agent.pos = pos\n\n    def _place_agent(self, coords, agent):\n        '''\n        Place the agent at the correct location.\n        '''\n        x, y = coords\n        self.grid[y][x] = agent\n\n    def _remove_agent(self, coords, agent):\n        '''\n        Remove the agent from the given location.\n        '''\n        x, y = coords\n        self.grid[y][x] = None\n\n    def _add_members(self, target_list, x, y):\n        '''\n        Helper method to append the contents of a cell to the given list.\n        Override for other grid types.\n        '''\n        if self.grid[y][x] is not None:\n            target_list.append(self.grid[y][x])\n\n    def is_cell_empty(self, coords):\n        x, y = coords\n        return True if self.grid[y][x] == self.default_val() else False\n\n\nclass SingleGrid(Grid):\n    '''\n    Grid where each cell contains exactly at most one object.\n    '''\n\n    def __init__(self, height, width, torus):\n        '''\n        Create a new single-item grid.\n\n        Args:\n            height, width: The height and width of the grid\n            torus: Boolean whether the grid wraps or not.\n        '''\n        super().__init__(height, width, torus)\n        # Add all cells to the empties list.\n        self.empties = list(itertools.product(\n                            *(range(self.width), range(self.height))))\n\n    def move_to_empty(self, agent):\n        \"\"\"\n        Moves agent to a random empty cell, vacating agent's old cell.\n        \"\"\"\n        coords = agent.pos\n        new_coords = self.find_empty()\n        if new_coords is None:\n            raise Exception(\"ERROR: No empty cells\")\n        else:\n            self._place_agent(new_coords, agent)\n            agent.pos = new_coords\n            self._remove_agent(coords, agent)\n\n    def find_empty(self):\n        '''\n        Pick a random empty cell.\n        '''\n        if self.exists_empty_cells():\n            coords = random.choice(self.empties)\n            return coords\n        else:\n            return None\n\n    def exists_empty_cells(self):\n        \"\"\"\n        Return True if any cells empty else False.\n        \"\"\"\n        return len(self.empties) > 0\n\n    def position_agent(self, agent, x=RANDOM, y=RANDOM):\n        \"\"\"\n        Position an agent on the grid.\n        This is used when first placing agents! Use 'move_to_empty()'\n        when you want agents to jump to an empty cell.\n        Use 'swap_pos()' to swap agents positions.\n        If x or y are positive, they are used, but if RANDOM,\n        we get a random position.\n        Ensure this random position is not occupied (in Grid).\n        \"\"\"\n        if x == RANDOM or y == RANDOM:\n            coords = self.find_empty()\n            if coords is None:\n                raise Exception(\"ERROR: Grid full\")\n        else:\n            coords = (x, y)\n        agent.pos = coords\n        self._place_agent(coords, agent)\n\n    def _place_agent(self, coords, agent):\n        if self.is_cell_empty(coords):\n            super()._place_agent(coords, agent)\n            self.empties.remove(coords)\n        else:\n            raise Exception(\"Cell not empty\")\n\n    def _remove_agent(self, coords, agent):\n        super()._remove_agent(coords, agent)\n        self.empties.append(coords)\n\n\nclass MultiGrid(Grid):\n    '''\n    Grid where each cell can contain more than one object.\n\n    Grid cells are indexed by [y][x], where [0][0] is assumed to be -- top-left\n    and [height-1][width-1] is the bottom-right. If a grid is toroidal, the top\n    and bottom, and left and right, edges wrap to each other.\n\n    Each grid cell holds a set object.\n\n    Properties:\n        width, height: The grid's width and height.\n\n        torus: Boolean which determines whether to treat the grid as a torus.\n\n        grid: Internal list-of-lists which holds the grid cells themselves.\n        default_val: Lambda function to populate grid cells with an empty set.\n\n    Methods:\n        get_neighbors: Returns the objects surrounding a given cell.\n    '''\n\n    default_val = lambda s: set()\n\n    def _place_agent(self, coords, agent):\n        '''\n        Place the agent at the correct location.\n        '''\n        x, y = coords\n        self.grid[y][x].add(agent)\n\n    def _remove_agent(self, coords, agent):\n        '''\n        Remove the agent from the given location.\n        '''\n        x, y = coords\n        self.grid[y][x].remove(agent)\n\n    def _add_members(self, target_list, x, y):\n        '''\n        Helper method to add all objects in the given cell to the target_list.\n        '''\n        for a in self.grid[y][x]:\n            target_list.append(a)\n", "path": "mesa/space.py"}]}