diff --git a/Code/UI/Field.py b/Code/UI/Field.py
index 0c778aa..8396e72 100644
--- a/Code/UI/Field.py
+++ b/Code/UI/Field.py
@@ -11,11 +11,22 @@ class Field:
self.width = GeneralConfig.fields_amount_x + 2
self.height = GeneralConfig.fields_amount_y + 2
self.field_shift = -10
+ self.shapes = Shapes()
self.squares = self._creat_squares()
- self.shapes = {Shape.VERTICAL_GLIDER: Shapes().creat_vertical_glieder}
+
+ def get_square_on_click_pos(self, mousclick_pos):
+ index_x = 0
+ index_y = 0
+ for line in self.squares:
+ index_y += 1
+ index_x = 0
+ for square in line:
+ index_x += 1
+ if square.rect.collidepoint(mousclick_pos):
+ return (index_y, index_x)
def create_shape(self, shape: Shape, start_square_pos):
- self.squares = self.shapes[shape](start_square_pos, self.squares)
+ self.squares = self.shapes.create_shape(start_square_pos,self.squares, shape)
def _creat_squares(self):
squares = [
diff --git a/Code/UI/PlayingField.py b/Code/UI/PlayingField.py
index 604b82d..6d6e83f 100644
--- a/Code/UI/PlayingField.py
+++ b/Code/UI/PlayingField.py
@@ -33,18 +33,23 @@ class GameState:
self.is_evolving = not self.is_evolving
self.neighbours.toggle_pause(self.is_evolving)
if event.key == pygame.K_v:
- index_x = 0
- index_y = 0
-
- for line in self.field.squares:
- index_y += 1
- index_x = 0
- for square in line:
- index_x += 1
- if square.rect.collidepoint(pygame.mouse.get_pos()):
- self.field.create_shape(Shape.VERTICAL_GLIDER,
- (int(index_y ),
- int(index_x )))
+ self.field.create_shape(Shape.VERTICAL_GLIDER_LEFT,
+ self.field.get_square_on_click_pos(pygame.mouse.get_pos()))
+ if event.key == pygame.K_b:
+ self.field.create_shape(Shape.VERTICAL_GLIDER_RIGHT,
+ self.field.get_square_on_click_pos(pygame.mouse.get_pos()))
+ if event.key == pygame.K_n:
+ self.field.create_shape(Shape.GLIDER_LEFT_DOWN,
+ self.field.get_square_on_click_pos(pygame.mouse.get_pos()))
+ if event.key == pygame.K_m:
+ self.field.create_shape(Shape.GLIDER_RIGHT,
+ self.field.get_square_on_click_pos(pygame.mouse.get_pos()))
+ if event.key == pygame.K_y:
+ self.field.create_shape(Shape.VERTICAL_GLIDER_RIGHT,
+ self.field.get_square_on_click_pos(pygame.mouse.get_pos()))
+ if event.key == pygame.K_x:
+ self.field.create_shape(Shape.VERTICAL_GLIDER_LEFT,
+ self.field.get_square_on_click_pos(pygame.mouse.get_pos()))
def update_field_with_input(self, event):
for line in self.field.squares:
@@ -91,7 +96,7 @@ def run_game(game_state: GameState):
time_elapsed_since_last_action += clock.get_time()
if game_state.is_evolving:
- if time_elapsed_since_last_action > 100:
+ if time_elapsed_since_last_action > 10:
# start = ti.time()
game_state.update_borders()
game_state.evolve()
diff --git a/Code/UI/Shape.py b/Code/UI/Shape.py
index f9076fc..412aa5e 100644
--- a/Code/UI/Shape.py
+++ b/Code/UI/Shape.py
@@ -2,4 +2,11 @@ from enum import Enum
class Shape(Enum):
- VERTICAL_GLIDER = 1
+ HORIZONTAL_GLIDER_LEFT = 1
+ HORIZONTAL_GLIDER_RIGHT=2
+ GLIDER_LEFT_DOWN = 3
+ GLIDER_RIGHT=4
+ VERTICAL_GLIDER_RIGHT=5
+ VERTICAL_GLIDER_LEFT=6
+
+
diff --git a/Code/UI/Shapes.py b/Code/UI/Shapes.py
index a7813e4..c6f54a2 100644
--- a/Code/UI/Shapes.py
+++ b/Code/UI/Shapes.py
@@ -1,23 +1,40 @@
+from operator import itemgetter
+
from Code import Config
+from Code.UI.Shape import Shape
class Shapes:
- def creat_vertical_glieder(self, start_square_pos: tuple, squares):
- points =[(0,0),(1,0),(2,0),(2,1),(1,2)]
- if self._check_bounderies((6, 6), start_square_pos, squares):
+ def create_shape(self, start_square_pos: tuple, squares, type):
+ return self._create_shape(start_square_pos, squares, Structures.shapes[type])
+
+ def _get_size(self, points):
+ x = max(max(points, key=itemgetter(0)))
+ y = max(max(points, key=itemgetter(1)))
+ return (x, y)
+
+ def _create_shape(self, start_square_pos: tuple, squares, points):
+ if self._check_bounderies(self._get_size(points), start_square_pos, squares):
for point in points:
- squares[start_square_pos[0]+point[1]][start_square_pos[1]+point[0]].active = True
+ squares[start_square_pos[0] + point[1]][start_square_pos[1] + point[0]].active = True
return squares
-
- def _creat_shape(self,start_square_pos: tuple, squares):
-
-
def _check_bounderies(self, bounderies, start_square_pos: tuple, field):
- x_valid = (Config.GeneralConfig.fields_amount_x-2 - start_square_pos[1]) > bounderies[0]
- y_valid = (Config.GeneralConfig.fields_amount_y-2 - start_square_pos[1]) > bounderies[1]
-
+ print(bounderies)
+ delta_start_pos_x = start_square_pos[0]
+ delta_start_pos_y = start_square_pos[1]
+ x_valid = (Config.GeneralConfig.fields_amount_x - 2 - int(delta_start_pos_x)) > bounderies[0]
+ y_valid = (Config.GeneralConfig.fields_amount_y - 2 - int(delta_start_pos_y)) > bounderies[1]
return x_valid and y_valid
+class Structures:
+ shapes = {Shape.GLIDER_LEFT_DOWN: [(0, 0), (1, 0), (2, 0), (2, 1), (1, 2)],
+ Shape.HORIZONTAL_GLIDER_LEFT: [(0, 0), (1, 0), (2, 0), (3, 0), (4, 1), (4, 3), (0, 1), (0, 2), (1, 3)],
+ Shape.HORIZONTAL_GLIDER_RIGHT: [(0, 1), (0, 3), (1, 0), (3, 0), (2, 0), (4, 0), (4, 1), (4, 2), (3, 3)],
+ Shape.GLIDER_RIGHT: [(0, 2), (1, 0), (1, 2), (2, 1), (2, 2)],
+ Shape.VERTICAL_GLIDER_RIGHT: [(1, 0), (3, 0), (0, 1), (0, 3), (0, 2), (0, 4), (1, 4), (2, 4), (3, 3)],
+ Shape.VERTICAL_GLIDER_LEFT: [(0, 0), (0, 1), (0, 2), (0, 3), (1, 4), (3, 4), (1, 0), (2, 0), (3, 1)]
+
+ }
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0f9b730
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+# Game of Life über mehrere Monitore
+
+Implementierung des berühmten [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life) als verteiltes System.
+Jeder Teilnehmer hat einen Bereich in dem er Game of Life berechnet und seine Kanten mit den andren Teilnehmer austauscht.
+Die gesamte Koordination erfolgt dezentral, Kommunikation ist immer p2p-basiert.
+
+
+## Einstieg
+Um an dem Spiel teilzunehmen, muss jeder Teilnehmer (außer der erste) beim Starten der Anwendung die IP-Adresse und den
+Port eines anderen Teilnehmers angeben, mit dem er sich verbinden will.
+Zusätzlich muss die Richtung der Kante, mit welcher er sich mit diesem verbinden will, angegeben werden.
+Da jeder Teilnehmer an jeder seiner Kanten maximal mit einem anderen Teilnehmer verbunden sein kann, ist es möglich,
+dass die Kante, die beim Einstieg gewählt wird, bereits besetzt ist.
+Ist dies der Fall, wird der Anfragende automatisch an denjenigen weitergeleitet, der diese Kante besetzt.
+Dies passiert so lange bis eine freie Kante gefunden wird und sich somit zwei Teilnehmer verbinden.
+Wenn man sich also **rechts** von Teilnehmer 1 verbinden will, ist es nicht garantiert, dass man direkt mit Teilnehmer 1
+verbunden wird, sondern nur, dass man räumlich **rechts** von Teilnehmer 1 liegt.
+
+
+
+## Suche
+Die Suche ist recht simpel.
+Jeder Teilnehmer kennt nur die Knoten, welche die für ihn relevanten Informationen haben und diese verändern sich im Laufe
+der Zeit auch nicht.
+
+## Verbreitung
+Eine relevante Information, die an das gesamte Netz verbreitet werden muss, ist eine Zustandsänderung bezüglich der
+Pausierung der Simulation.
+Hierfür wird einfaches Flooding verwendet.
+D.h. jeder Teilnehmer schickt den neuen Zustand an alle seine Nachbarn und diese senden ihn wiederum an ihre Nachbarn.
+Da es nur zwei mögliche Zustände für den Pause-Zustand geben kann, ist Flooding ausreichend effizient, zyklische Nachrichten
+ werden vermieden, indem ein Teilnehmer die Information nicht mehr weiterleitet, wenn er sie bereits bekommen hat, sich also
+schon im richtigen Zustand befindet.
+
+## Zeitliche Synchronisation
+Um sicherzustellen, dass alle Teilnehmer gleichzeitig den Entwicklungsschritt durchführen und somit der Randaustausch auch
+korrekt funktioniert.
diff --git a/images/Verbindungsaufbau b/images/Verbindungsaufbau
new file mode 100644
index 0000000..2292fb6
--- /dev/null
+++ b/images/Verbindungsaufbau
@@ -0,0 +1 @@
+1VjbcpswEP0aP9bDHecxdtJ20stkJmmTPnUUWECtQFTINs7XV4AEyCS+pGlIXhLt0e4i7e5Z1kzsRVp+YChPvtAQyMQywnJin00syzT9mfhXIZsG8U2jAWKGQ6nUAVf4HiSo1JY4hEJT5JQSjnMdDGiWQcA1DDFG17paRIn+1BzFMACuAkSG6A0OedKgM9fo8I+A40Q92TTkToqUsgSKBIV03YPs84m9YJTyZpWWCyBV8FRcGrv3j+y2B2OQ8UMM6EXp399/Kv6cej/n32buBY/Sd7Y8G9+oC0Mo7i9FynhCY5ohct6hc0aXWQiVV0NInc5nSnMBmgL8BZxvZDLRklMBJTwlchdKzG976x+Vq6nlSvGslK5rYaOEjLPNbV/om1VyZ1dLyrC5YXWtRwMnoYIuWQA7oqUKELEY+A49q02v4AXQFMR5hB0Dgjhe6edAskDjVq/LoVjINB6RUul3hchSPulaQB5KRXLm2V2RtzHpZX2dYA5XOaqvvxZU1jOGirwhV4TLKvPSwQoYh3J3WIdhUAa+JIbsDJYn5XWPZxJKehRT2LMHzhmTC4bGBf9ALpg6F/wX5IJ1IBceKYIX4sKQDF9BrCyPiDPP75hYxdXqO7A7nIXLLH57DdGcGqajF4I3O9lTCbV0CQyLQAOTYIQJWVBCWX1z2zPQiekLvOCM/obejnXme8ZIBeX9Y0HVpqeMoU1PIac440XP82UFdM3Ksbaa1WzrZbtH3xXJ1Iu5OUFX2u1Vnl7t1rDzW6+h09vGK+v0/iBQHf8LlEWsGgoHPYJBkFQ1so2P+tqYuv2eceAENXX77cLc0yqekePem3hpGGNm9InvgCMHgVE7/aFVMOoY7T04ObAh/a8BkwyStNobv9duT9WOP3KvnQ3ieAMiKoxUf7NByIIlW9U0aio6PK1+wwsxIKgocKAHUCfd/+9vT61YmRtj6jjGiZYe2x1kx30gOwo7bsgZTCXtVxX1dGcr6w11pdWu8WafoyZSA0fHjl1tWapqNrSxSx+jOmvlnkZRAXyyXcI7Ry0hdt9kGvXuy5Z9/hc=
\ No newline at end of file
diff --git a/images/Verbindungsaufbau.drawio.svg b/images/Verbindungsaufbau.drawio.svg
new file mode 100644
index 0000000..0151560
--- /dev/null
+++ b/images/Verbindungsaufbau.drawio.svg
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/images/Verbindungsaufbau.png b/images/Verbindungsaufbau.png
new file mode 100644
index 0000000..b2ba945
Binary files /dev/null and b/images/Verbindungsaufbau.png differ