Repository: tmcclintock/donjuan

Issue:
Create shift functions
Create `Room.shift_up`, `Room.shift_down`, `Room.shift_left`, and `Room.shift_right` to shift the coordinates of all `Cell`s in a `Room` at once.

These same functions can be copied for `Hallway` objects once those are implemented.

Discussion:

Patch:
diff --git a/donjuan/cell.py b/donjuan/cell.py
index 2f0bcb3..276c7b1 100644
--- a/donjuan/cell.py
+++ b/donjuan/cell.py
@@ -24,22 +24,31 @@ class Cell(ABC):
         self.filled = filled
         self.door_space = door_space
         self.contents = contents or []
-        self._coordinates = coordinates
+        if coordinates is None:
+            self._coordinates = [0, 0]
+        else:
+            self._coordinates = list(coordinates)
 
-    def set_coordinates(self, x: int, y: int) -> None:
-        self._coordinates = (int(x), int(y))
+    def set_coordinates(self, y: int, x: int) -> None:
+        self._coordinates = [int(y), int(x)]
+
+    def set_x(self, x: int) -> None:
+        self._coordinates[1] = int(x)
+
+    def set_y(self, y: int) -> None:
+        self._coordinates[0] = int(y)
 
     @property
     def coordinates(self) -> Tuple[int, int]:
-        return self._coordinates
+        return tuple(self._coordinates)
 
     @property
     def x(self) -> int:
-        return self._coordinates[0]
+        return self._coordinates[1]
 
     @property
     def y(self) -> int:
-        return self._coordinates[1]
+        return self._coordinates[0]
 
     @property
     def n_sides(self) -> int:
diff --git a/donjuan/room.py b/donjuan/room.py
index 8e36b52..7c2dfd6 100644
--- a/donjuan/room.py
+++ b/donjuan/room.py
@@ -7,8 +7,6 @@ from donjuan import Cell
 class Room:
     def __init__(self, cells: Optional[List[List[Cell]]] = None):
         self._cells = cells or [[]]
-        for cell in chain.from_iterable(self._cells):
-            assert cell.coordinates is not None, "room cell must have coordinates"
 
     @property
     def cells(self) -> List[List[Cell]]:
@@ -34,3 +32,25 @@ class Room:
                     return True
         # No overlap
         return False
+
+    def shift_vertical(self, n: int) -> None:
+        """
+        Change the ``y`` coordinates of all :attr:`cells` by ``n``.
+
+        Args:
+            n (int): number to increment vertical position of cells
+        """
+        for c in chain.from_iterable(self.cells):
+            c.set_y(c.y + int(n))
+        return
+
+    def shift_horizontal(self, n: int) -> None:
+        """
+        Change the ``x`` coordinates of all :attr:`cells` by ``n``.
+
+        Args:
+            n (int): number to increment horizontal position of cells
+        """
+        for c in chain.from_iterable(self.cells):
+            c.set_x(c.x + int(n))
+        return


Test patch:
diff --git a/tests/cell_test.py b/tests/cell_test.py
index 0dbee62..0f0e732 100644
--- a/tests/cell_test.py
+++ b/tests/cell_test.py
@@ -24,11 +24,11 @@ class SquareCellTest(TestCase):
 
     def test_coordinates(self):
         c = SquareCell()
-        assert c.coordinates is None
+        assert c.coordinates == (0, 0)
         c.set_coordinates(1, 2)
         assert c.coordinates == (1, 2)
-        assert c.x == 1
-        assert c.y == 2
+        assert c.x == 2
+        assert c.y == 1
 
 
 class HexCellTest(TestCase):
@@ -46,8 +46,8 @@ class HexCellTest(TestCase):
 
     def test_coordinates(self):
         c = HexCell()
-        assert c.coordinates is None
+        assert c.coordinates == (0, 0)
         c.set_coordinates(1, 2)
         assert c.coordinates == (1, 2)
-        assert c.x == 1
-        assert c.y == 2
+        assert c.x == 2
+        assert c.y == 1
diff --git a/tests/grid_test.py b/tests/grid_test.py
index b0f5d0f..3b35fd9 100644
--- a/tests/grid_test.py
+++ b/tests/grid_test.py
@@ -49,7 +49,7 @@ class SquareGridTest(TestCase):
         sg = SquareGrid.from_cells(cells)
         for i in range(sg.n_rows):
             for j in range(sg.n_cols):
-                assert sg.cells[i][j].coordinates is None
+                assert sg.cells[i][j].coordinates == (0, 0)
         sg.reset_cell_coordinates()
         for i in range(sg.n_rows):
             for j in range(sg.n_cols):
diff --git a/tests/room_test.py b/tests/room_test.py
index 8d7e5fa..9a240f6 100644
--- a/tests/room_test.py
+++ b/tests/room_test.py
@@ -1,8 +1,6 @@
 from copy import deepcopy
 from unittest import TestCase
 
-import pytest
-
 from donjuan import Room, SquareCell
 
 
@@ -12,10 +10,21 @@ class RoomTest(TestCase):
         assert r is not None
         assert r.cells == [[]]
 
-    def test_assert_cell_coords(self):
-        c = SquareCell()
-        with pytest.raises(AssertionError):
-            Room(cells=[[c]])
+    def test_shift_vertical(self):
+        cs = [[SquareCell(coordinates=(i, j)) for j in range(5)] for i in range(4)]
+        r = Room(cs)
+        r.shift_vertical(100)
+        for i in range(len(cs)):
+            for j in range(len(cs[0])):
+                assert r.cells[i][j].coordinates == (i + 100, j)
+
+    def test_shift_horizontal(self):
+        cs = [[SquareCell(coordinates=(i, j)) for j in range(5)] for i in range(4)]
+        r = Room(cs)
+        r.shift_horizontal(100)
+        for i in range(len(cs)):
+            for j in range(len(cs[0])):
+                assert r.cells[i][j].coordinates == (i, j + 100)
 
     def test_overlaps(self):
         cs = [[SquareCell(coordinates=(i, j)) for j in range(5)] for i in range(4)]