Initial commit

This commit is contained in:
Richard Feistenauer 2018-12-01 15:14:22 +01:00
commit f060a6e745
19 changed files with 783 additions and 0 deletions

11
.idea/WorldGeneration.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.7" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/WorldGeneration.iml" filepath="$PROJECT_DIR$/.idea/WorldGeneration.iml" />
</modules>
</component>
</project>

405
.idea/workspace.xml Normal file
View File

@ -0,0 +1,405 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="5a936069-819f-4c75-93de-a950897acf14" name="Default Changelist" comment="" />
<ignored path="$PROJECT_DIR$/venv/" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FUSProjectUsageTrigger">
<session id="1685401553">
<usages-collector id="statistics.lifecycle.project">
<counts>
<entry key="project.closed" value="1" />
<entry key="project.open.time.1" value="1" />
<entry key="project.open.time.4" value="1" />
<entry key="project.open.time.5" value="2" />
<entry key="project.opened" value="4" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.open">
<counts>
<entry key="py" value="11" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.open">
<counts>
<entry key="Python" value="11" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.edit">
<counts>
<entry key="dummy" value="25" />
<entry key="py" value="2139" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.edit">
<counts>
<entry key="PLAIN_TEXT" value="25" />
<entry key="Python" value="2139" />
</counts>
</usages-collector>
</session>
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/world_generator.py">
<provider selected="true" editor-type-id="text-editor">
<state>
<caret selection-end-column="22" />
<folding>
<element signature="e#24#38#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/scripts/main_ui.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="272">
<caret line="16" column="59" selection-start-line="16" selection-start-column="59" selection-end-line="16" selection-end-column="59" />
<folding>
<element signature="e#24#37#0" expanded="true" />
<marker date="1543672995350" expanded="true" signature="132:425" ph="..." />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/__init__.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/cellular_automaton.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="680">
<caret line="44" column="87" selection-start-line="44" selection-start-column="87" selection-end-line="44" selection-end-column="87" />
<folding>
<element signature="e#0#16#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/ca_rule.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="39" selection-start-line="10" selection-start-column="39" selection-end-line="10" selection-end-column="39" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/ca_neighberhood.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="51">
<caret line="3" column="63" selection-start-line="3" selection-start-column="55" selection-end-line="3" selection-end-column="63" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/ca_grid.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="629">
<caret line="38" column="10" selection-start-line="38" selection-start-column="9" selection-end-line="38" selection-end-column="10" />
<folding>
<element signature="e#0#45#0" expanded="true" />
<marker date="1540986500017" expanded="true" signature="3484:3522" ph="..." />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/ca_cell.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="1" column="43" selection-start-line="1" selection-start-column="43" selection-end-line="1" selection-end-column="43" />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>get_coordinate_from_index</find>
<find>print</find>
</findStrings>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/src/cellular_automaton/ca_neighberhood.py" />
<option value="$PROJECT_DIR$/src/cellular_automaton/ca_cell.py" />
<option value="$PROJECT_DIR$/src/cellular_automaton/ca_rule.py" />
<option value="$PROJECT_DIR$/src/cellular_automaton/ca_grid.py" />
<option value="$PROJECT_DIR$/src/cellular_automaton/cellular_automaton.py" />
<option value="$PROJECT_DIR$/src/world_generator.py" />
<option value="$PROJECT_DIR$/src/cellular_automaton/__init__.py" />
<option value="$PROJECT_DIR$/src/cellular_automaton/pygame_main.py" />
<option value="$PROJECT_DIR$/scripts/main_ui.py" />
</list>
</option>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="442" />
<option name="y" value="-11" />
<option name="width" value="1400" />
<option name="height" value="1000" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Scope" />
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="WorldGeneration" type="b2602c69:ProjectViewProjectNode" />
<item name="WorldGeneration" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="WorldGeneration" type="b2602c69:ProjectViewProjectNode" />
<item name="WorldGeneration" type="462c0819:PsiDirectoryNode" />
<item name="images" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="WorldGeneration" type="b2602c69:ProjectViewProjectNode" />
<item name="WorldGeneration" type="462c0819:PsiDirectoryNode" />
<item name="scripts" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="WorldGeneration" type="b2602c69:ProjectViewProjectNode" />
<item name="WorldGeneration" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="WorldGeneration" type="b2602c69:ProjectViewProjectNode" />
<item name="WorldGeneration" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="cellular_automaton" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
</panes>
</component>
<component name="PropertiesComponent">
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\DamKoVosh\Eigene Dokumente\Programming\WorldGeneration\scripts" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager" selected="Python.main_ui">
<configuration name="main_ui" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="WorldGeneration" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/scripts" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/scripts/main_ui.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="world_generator" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="WorldGeneration" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/src" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/world_generator.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<list>
<item itemvalue="Python.world_generator" />
<item itemvalue="Python.main_ui" />
</list>
<recent_temporary>
<list>
<item itemvalue="Python.main_ui" />
<item itemvalue="Python.world_generator" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="5a936069-819f-4c75-93de-a950897acf14" name="Default Changelist" comment="" />
<created>1540970314178</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1540970314178</updated>
</task>
<servers />
</component>
<component name="TodoView">
<todo-panel id="selected-file">
<is-autoscroll-to-source value="true" />
</todo-panel>
<todo-panel id="all">
<are-packages-shown value="true" />
<is-autoscroll-to-source value="true" />
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="1912" y="-6" width="1936" height="1056" extended-state="6" />
<editor active="true" />
<layout>
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.24973656" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" />
<window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.49894625" visible="true" weight="0.329718" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" weight="0.329718" />
<window_info anchor="bottom" id="Version Control" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="Terminal" order="8" sideWeight="0.49894625" weight="0.329718" />
<window_info anchor="bottom" id="Event Log" order="9" sideWeight="0.50105375" side_tool="true" visible="true" weight="0.329718" />
<window_info anchor="bottom" id="Python Console" order="10" sideWeight="0.49947312" weight="0.329718" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
</layout>
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="editorHistoryManager">
<entry file="file://$USER_HOME$/AppData/Roaming/Python/Python37/site-packages/pygame/__init__.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="221">
<caret line="143" selection-start-line="143" selection-end-line="143" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/world_generator.py">
<provider selected="true" editor-type-id="text-editor">
<state>
<caret selection-end-column="22" />
<folding>
<element signature="e#24#38#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/__init__.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/cellular_automaton.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="680">
<caret line="44" column="87" selection-start-line="44" selection-start-column="87" selection-end-line="44" selection-end-column="87" />
<folding>
<element signature="e#0#16#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/ca_rule.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="39" selection-start-line="10" selection-start-column="39" selection-end-line="10" selection-end-column="39" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/ca_neighberhood.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="51">
<caret line="3" column="63" selection-start-line="3" selection-start-column="55" selection-end-line="3" selection-end-column="63" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/ca_grid.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="629">
<caret line="38" column="10" selection-start-line="38" selection-start-column="9" selection-end-line="38" selection-end-column="10" />
<folding>
<element signature="e#0#45#0" expanded="true" />
<marker date="1540986500017" expanded="true" signature="3484:3522" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/cellular_automaton/ca_cell.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="1" column="43" selection-start-line="1" selection-start-column="43" selection-end-line="1" selection-end-column="43" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/scripts/main_ui.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="272">
<caret line="16" column="59" selection-start-line="16" selection-start-column="59" selection-end-line="16" selection-end-column="59" />
<folding>
<element signature="e#24#37#0" expanded="true" />
<marker date="1543672995350" expanded="true" signature="132:425" ph="..." />
</folding>
</state>
</provider>
</entry>
</component>
</project>

BIN
images/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

48
scripts/main_ui.py Normal file
View File

@ -0,0 +1,48 @@
#!/usr/bin/env python3
import pygame
import random
from cellular_automaton import cellular_automaton
class WorldGeneratorWindow:
def __init__(self, windows_size):
self.window_size = windows_size
pygame.init()
pygame.display.set_caption("World Generator")
pygame.display.set_mode(self.window_size)
def display_cellular_automaton(self, cellular_automaton_instance):
pass
def main():
running = True
pygame.init()
pygame.display.set_caption("minimal program")
screen = pygame.display.set_mode((1000, 730))
image = pygame.image.load("../images/map.png")
screen.blit(image, (0, 0))
screen.set_at((50, 60), [50, 0, 0])
screen.set_at((50, 61), [50, 0, 0])
screen.set_at((51, 60), [50, 0, 0])
screen.set_at((51, 61), [50, 0, 0])
pygame.display.flip()
while running:
for x in range(0, 1000):
for y in range(0, 700):
screen.set_at((x, y), [random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255)])
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if __name__ == "__main__":
main()

View File

View File

@ -0,0 +1,19 @@
class CACell:
def __init__(self, initial_state=None):
if initial_state:
assert isinstance(initial_state, (tuple, list))
self._state = initial_state
else:
self._state = [0]
def __getitem__(self, index):
return self._state[index]
def __setitem__(self, index, value):
self._state[index] = value
def __len__(self):
return len(self._state)
def __str__(self):
return str(self._state)

View File

@ -0,0 +1,124 @@
from cellular_automaton.ca_cell import CACell
from functools import reduce
class CAGrid:
def __init__(self, dimensions, initial_grid_state=None):
assert isinstance(dimensions, list)
assert len(dimensions) > 0
self._dimensions = dimensions
self._cell_count = reduce(lambda x, y: x*y, dimensions)
if initial_grid_state:
assert isinstance(initial_grid_state, list)
assert len(initial_grid_state) == self._cell_count
assert isinstance(initial_grid_state[0], CACell)
self._grid = initial_grid_state
else:
self._grid = []
for i in range(self._cell_count):
self._grid.append(CACell())
def get_index_from_coordinate(self, coordinate):
""" Convert a coordinate to the index in the grid list.
:param coordinate: A tuple or list with the position of the cell.
Has to have the same dimension as the grid.
:return: The index of the cell at the coordinates
"""
assert len(self._dimensions) == len(coordinate)
index = 0
for i, c in enumerate(coordinate[1:]):
index += c * reduce(lambda x, y: x * y, self._dimensions[:i+1])
index += coordinate[0]
return index
def get_coordinate_from_index(self, index):
""" Convert an index to the coordinate in the grid list.
:param index: The Index of the cell in the grid.
:return: The coordinate pointing at the indexed cell in the grid.
"""
coordinate = len(self._dimensions)*[0]
for i, d in enumerate(self._dimensions):
coordinate[-(i + 1)] = index // reduce(lambda x, y: x * y, self._dimensions[-(i + 1):])
index = index % reduce(lambda x, y: x * y, self._dimensions[-(i + 1):])
coordinate[0] = index
return coordinate
def get_cell_by_coordinate(self, coordinate):
""" Read a cell using a list or tuple as reference
:param coordinate A tuple or list with the position of the cell.
Has to have the same dimension as the grid.
:return: The CACell at the coordinate in the grid.
"""
try:
return self[self.get_index_from_coordinate(coordinate)]
except IndexError:
return None
def get_all_neighbour_cells(self, position, neighborhood):
""" Get a list with all cells defined by the neighborhood.
:param position: The position as index or coordinate.
:param neighborhood: The neighborhood definition as tuple.
:return: All Cells defined by the neighborhood in a list.
"""
if isinstance(position, (tuple, list)):
coordinate = position[:]
else:
coordinate = self.get_coordinate_from_index(position)
neighbors = []
for neighbor in neighborhood:
neighbor_coordinate = []
for i, (c, nc) in enumerate(zip(coordinate, neighbor)):
coord = c + nc
if coord < 0:
coord = self._dimensions[i] - 1
elif coord == self._dimensions[i]:
coord = 0
neighbor_coordinate.append(coord)
index_ = self.get_cell_by_coordinate(neighbor_coordinate)
if index_:
neighbors.append(index_)
return neighbors
def get_dimensions(self):
return self._dimensions
def set_cell_by_coordinate(self, coordinate, value):
""" Write to a cell using a list or tuple as reference
:param coordinate A tuple or list with the position of the cell.
Has to have the same dimension as the grid.
"""
try:
self._grid[self.get_index_from_coordinate(coordinate)] = value
except IndexError:
return None
def __eq__(self, other):
if len(self._grid) != len(other):
return False
for i in self._cell_count:
if self._grid[i] != other[i]:
return False
return True
def __len__(self):
return len(self._grid)
def __getitem__(self, index):
return self._grid[int(index)]
def __setitem__(self, index, value):
self._grid[index] = value
def __str__(self):
return str(self._grid)

View File

@ -0,0 +1,7 @@
class Neighborhood:
MOOR_2_X_2 = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 0], [0, 1], [1, -1], [1, 0], [1, 1]]
def __init__(self):
pass

View File

@ -0,0 +1,13 @@
import abc
class CARule(abc.ABC):
@abc.abstractmethod
def evolve_cell(self, cell, neighbors):
"""
Evolves a cell and returns its new state as list of states.
:param cell: The cell to evolve.
:param neighbors: A list of its neighbors.
:return: The new state list.
"""
pass

View File

@ -0,0 +1,54 @@
import threading
import time
from cellular_automaton.ca_cell import CACell
from cellular_automaton.ca_grid import CAGrid
class CellularAutomaton:
def __init__(self, threads=1):
assert threads > 0
self._thread_count = threads
def evolve(self, grid, neighborhood, rule):
range_ = int(len(grid) / self._thread_count)
threads = []
for t in range(self._thread_count):
new_thread = EvolutionThread(grid, neighborhood, rule, [t * range_, t * range_ + range_])
threads.append(new_thread)
new_thread.start()
new_grid_state = []
for thread in threads:
while not thread.is_finished():
time.sleep(0.01)
new_grid_state.extend(thread.get_new_cell_states())
thread.join()
return CAGrid(grid.get_dimensions(), new_grid_state)
class EvolutionThread(threading.Thread):
def __init__(self, grid, neighborhood, rule, range_):
super(EvolutionThread, self).__init__()
self._grid = grid
self._neighborhood = neighborhood
self._rule = rule
self._range = range_
self._next_state = []
self._finished = False
def run(self):
for cell_id in range(*self._range):
neighbors = self._grid.get_all_neighbour_cells(cell_id, self._neighborhood)
cell = self._grid[cell_id]
self._next_state.append(CACell(self._rule.evolve_cell(cell, neighbors)))
self._finished = True
def get_new_cell_states(self):
return self._next_state
def is_finished(self):
return self._finished

90
src/world_generator.py Normal file
View File

@ -0,0 +1,90 @@
#!/usr/bin/env python3
import tkinter
from cellular_automaton.cellular_automaton import CellularAutomaton
from cellular_automaton.ca_neighberhood import Neighborhood
from cellular_automaton.ca_rule import CARule
from cellular_automaton.ca_grid import CAGrid
from cellular_automaton.ca_cell import CACell
import datetime
import pygame
UPDATE_RATE = 10
class TkGUI:
def __init__(self):
self.root = tkinter.Tk()
self.canvas = tkinter.Canvas(self.root)
self.canvas.pack(padx=5, pady=5)
self.ca = None
self.current_state = None
self.dimensions = None
self.rule_ = None
self.grid_image = None
def run(self):
self.root.after(10, self.update_state())
self.root.mainloop()
def update_state(self):
a = datetime.datetime.now()
self.current_state = self.ca.evolve(self.current_state, Neighborhood.MOOR_2_X_2, self.rule_)
b = datetime.datetime.now()
self.draw_current_state()
c = datetime.datetime.now()
print(b-a)
print(c-b)
self.root.after(UPDATE_RATE, self.update_state)
def draw_current_state(self):
for idx in range(self.dimensions[0]):
for idy in range(self.dimensions[1]):
cell = self.current_state[idy * self.dimensions[0] + idx]
if cell[0] == 0:
cell_color = "#ffffff"
else:
cell_color = "#444444"
self.grid_image.put(cell_color, (idx, idy))
def start(self, ca_, grid, dimensions, rule_):
self.grid_image = tkinter.PhotoImage(width=dimensions[0], height=dimensions[1])
self.ca = ca_
self.current_state = grid
self.dimensions = dimensions
self.rule_ = rule_
# Clear the canvas (remove all shapes)
self.canvas.delete(tkinter.ALL)
self.draw_current_state()
self.canvas.create_image(self.dimensions, image=self.grid_image, state="normal")
# Draw the canvas
self.draw_current_state()
class TestRule(CARule):
def evolve_cell(self, cell, neighbors):
if neighbors[1][0] != 0:
return [1]
else:
return [0]
#if __name__ == '__main__':
# gui = TkGUI()
# dim = [200, 500]
# ca = CellularAutomaton(2)
#
# new_grid = CAGrid(dim)
# new_grid.set_cell_by_coordinate([1, 1], CACell([1]))
# rule = TestRule()
# gui.start(ca, new_grid, dim, rule)##
#
# gui.run()