Browse Source

Base Game of Life implementation

Ivan Arkhipov 6 years ago
commit
d52677a5d1
3 changed files with 258 additions and 0 deletions
  1. 108 0
      .gitignore
  2. 137 0
      GameOfLifeLibrary.py
  3. 13 0
      game.py

+ 108 - 0
.gitignore

@@ -0,0 +1,108 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+.static_storage/
+.media/
+local_settings.py
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+
+# PyCharm Ide
+.idea

+ 137 - 0
GameOfLifeLibrary.py

@@ -0,0 +1,137 @@
+class GameOfLife:
+    def __init__(self, sizex, sizey):
+        self.sizex = sizex
+        self.sizey = sizey
+        self.cells = [[NoUnit(i, j) for j in range(sizey)] for i in range(sizex)]
+        # print(self.cells)
+
+    def parse_field(self, field):
+        assert len(field) == self.sizex
+
+        x = 0
+        for line in field:
+            y = 0
+            assert len(line) == self.sizey
+            for char in line:
+                if char == 'f':
+                    self.cells[x][y] = FishUnit(x, y)
+                if char == 's':
+                    self.cells[x][y] = ShrimpUnit(x, y)
+                if char == 'r':
+                    self.cells[x][y] = RockUnit(x, y)
+                y += 1
+            x += 1
+
+    def print_field(self):
+        dict = {
+            'NoUnit': 'n',
+            'RockUnit': 'r',
+            'ShrimpUnit': 's',
+            'FishUnit': 'f'
+        }
+        for x in range(self.sizex):
+            for y in range(self.sizey):
+                print(dict[self.cells[x][y].type], sep='', end='')
+            print()
+
+    def correct_coors(self, x, y):
+        return 0 <= x < self.sizex and 0 <= y < self.sizey
+
+    def iterate(self):
+        new_cells = [[NoUnit(i, j) for j in range(self.sizey)] for i in range(self.sizex)]
+
+        neighbour_diffs = [
+            [-1, -1],
+            [0, -1],
+            [1, -1],
+            [-1, 0],
+            [1, 0],
+            [-1, 1],
+            [0, 1],
+            [1, 1]
+        ]
+
+        for x in range(self.sizex):
+            for y in range(self.sizey):
+                neighbours = [self.cells[x - d[0]][y - d[1]]
+                              if self.correct_coors(x - d[0], y - d[1]) else
+                              NoUnit(0, 0)
+                              for d in neighbour_diffs]
+                # print(x, y, neighbours)
+                if not self.cells[x][y].should_be_killed(neighbours):
+                    new_cells[x][y] = self.cells[x][y]
+
+                if self.cells[x][y].can_spawn_fish(neighbours):
+                    new_cells[x][y] = FishUnit(x, y)
+                elif self.cells[x][y].can_spawn_shrimp(neighbours):
+                    new_cells[x][y] = ShrimpUnit(x, y)
+
+        self.cells = new_cells
+
+class Unit:
+    def __init__(self, posx, posy):
+        self.posx = posx
+        self.posy = posy
+        self.type = 'Unit'
+
+    def should_be_killed(self, neighbours):
+        return False
+
+    def is_empty(self):
+        return self.type == 'NoUnit' or self.type == 'Unit'
+
+    def can_spawn_shrimp(self, neighbours):
+        return False
+
+    def can_spawn_fish(self, neighbours):
+        return False
+
+    def __str__(self):
+        return self.type + '(' + str(self.posx) + ',' + str(self.posy) + ')'
+
+    def __repr__(self):
+        return self.type + '(' + str(self.posx) + ',' + str(self.posy) + ')'
+
+
+class NoUnit(Unit):
+    def __init__(self, posx, posy):
+        super().__init__(posx, posy)
+        self.type = 'NoUnit'
+
+    def can_spawn_shrimp(self, neighbours):
+        ns_num = sum(1 if neighbour.type == 'ShrimpUnit' else 0 for neighbour in neighbours)
+        return ns_num == 3
+
+    def can_spawn_fish(self, neighbours):
+        ns_num = sum(1 if neighbour.type == 'FishUnit' else 0 for neighbour in neighbours)
+        return ns_num == 3
+
+
+
+class FishUnit(Unit):
+    def __init__(self, posx, posy):
+        super().__init__(posx, posy)
+        self.type = 'FishUnit'
+
+    def should_be_killed(self, neighbours):
+        ns_num = sum(1 if neighbour.type == 'FishUnit' else 0 for neighbour in neighbours)
+        return ns_num < 2 or ns_num >= 4
+
+
+class ShrimpUnit(Unit):
+    def __init__(self, posx, posy):
+        super().__init__(posx, posy)
+        self.type = 'ShrimpUnit'
+
+    def should_be_killed(self, neighbours):
+        ns_num = sum(1 if neighbour.type == 'ShrimpUnit' else 0 for neighbour in neighbours)
+        return ns_num < 2 or ns_num >= 4
+
+
+class RockUnit(Unit):
+    def __init__(self, posx, posy):
+        super().__init__(posx, posy)
+        self.type = 'RockUnit'
+
+    def should_be_killed(self, neighbours):
+        return False

+ 13 - 0
game.py

@@ -0,0 +1,13 @@
+from GameOfLifeLibrary import GameOfLife
+import sys
+
+sys.stdin = open("a.txt")
+
+sizex, sizey, gens = (int(i) for i in input().split())
+
+a = GameOfLife(sizex, sizey)
+a.parse_field([line[:-1] if line[-1] == '\n' else line for line in sys.stdin.readlines()])
+
+for i in range(gens):
+    a.iterate()
+a.print_field()