Compare commits
No commits in common. "c958cc6634073fbe2ca04899e469f8aa07998406" and "3cd8ca1d0d3f812101aa278048c269c756e738b0" have entirely different histories.
c958cc6634
...
3cd8ca1d0d
20
Code/Main.py
20
Code/Main.py
|
@ -11,7 +11,6 @@ if __name__ == "__main__":
|
|||
|
||||
"""
|
||||
Getting the args
|
||||
- own ip
|
||||
- own port
|
||||
|
||||
Optional: A neighbour:
|
||||
|
@ -23,25 +22,22 @@ if __name__ == "__main__":
|
|||
args = sys.argv
|
||||
|
||||
print(args)
|
||||
if len(args) >= 3:
|
||||
own_ip = args[1]
|
||||
own_port = int(args[2])
|
||||
if len(args) >= 2:
|
||||
own_port = int(args[1])
|
||||
else:
|
||||
print("using default ip 0.0.0.0")
|
||||
print("using default port 8080")
|
||||
own_ip = "0.0.0.0"
|
||||
own_port = 8080
|
||||
|
||||
neighbours = Neighbours(own_process=Member(own_ip, own_port))
|
||||
neighbours = Neighbours(own_process=Member("0.0.0.0", own_port))
|
||||
game_state = GameState(neighbours)
|
||||
server = Server(neighbours, game_state)
|
||||
|
||||
n_direction = Direction.LEFT
|
||||
if len(args) > 5:
|
||||
n_direction = args[5]
|
||||
if len(args) >= 5:
|
||||
n_ip = args[3]
|
||||
n_port = int(args[4])
|
||||
if len(args) > 4:
|
||||
n_direction = args[4]
|
||||
if len(args) >= 4:
|
||||
n_ip = args[2]
|
||||
n_port = int(args[3])
|
||||
neighbours.connect(Direction[n_direction], n_ip, n_port)
|
||||
|
||||
serverThread = threading.Thread(target=server.start)
|
||||
|
|
57
README.md
57
README.md
|
@ -4,48 +4,8 @@ Implementierung des berühmten [Conway's Game of Life](https://en.wikipedia.org/
|
|||
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.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3+
|
||||
|
||||
```shell
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Ausführen
|
||||
|
||||
```shell
|
||||
python -m Code.Main own_ip own_port [ neighbour_ip neighbour_port (LEFT|RIGHT) ]
|
||||
```
|
||||
|
||||
### Beispiel (auf lokalem Rechner)
|
||||
|
||||
Als erster Teilnehmer
|
||||
|
||||
```shell
|
||||
python -m Code.Main 0.0.0.0 8080
|
||||
```
|
||||
|
||||
Als zweiter Teilnehmer
|
||||
|
||||
```shell
|
||||
python -m Code.Main 0.0.0.0 8081 0.0.0.0 8080 RIGHT
|
||||
```
|
||||
|
||||
Als dritter Teilnehmer
|
||||
|
||||
```shell
|
||||
python -m Code.Main 0.0.0.0 8082 0.0.0.0 8080 LEFT
|
||||
```
|
||||
|
||||
### Mit zwei Teilnehmern auf dem lokalen Rechner
|
||||
|
||||
```shell
|
||||
python -m Code.Main 0.0.0.0 8080 & sleep 2 && python -m Code.Main 0.0.0.0 8081 0.0.0.0 8080 RIGHT
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
@ -59,13 +19,11 @@ verbunden wird, sondern nur, dass man räumlich **rechts** von Teilnehmer 1 lieg
|
|||
![Schema Verbindungsaufbau](./images/Verbindungsaufbau.drawio.svg)
|
||||
|
||||
## 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.
|
||||
|
@ -75,19 +33,16 @@ werden vermieden, indem ein Teilnehmer die Information nicht mehr weiterleitet,
|
|||
schon im richtigen Zustand befindet.
|
||||
|
||||
## Zeitliche Synchronisation
|
||||
|
||||
Um sicherzustellen, dass alle Teilnehmer gleichzeitig den Entwicklungsschritt durchführen und somit der Randaustausch auch
|
||||
korrekt funktioniert, wird eine vereinfachte Version von Lamport Clocks verwendet.
|
||||
Jeder Prozess hat einen Counter, den er bei jedem Entwicklungsschritt um eins erhöht.
|
||||
Da für jeden Entwicklungsschritt zuerst die Ränder der benachbarten Teilenehmer abgefragt werden müssen und dies blockieriend
|
||||
geschieht, sind alle Teilnehmer zu jedem Zeitpunkt um maximal 1 bezüglich ihres Counters versetzt.
|
||||
Damit man jedoch mit seinem Entwicklungsschritt nicht warten muss, bis alle Nachbar den Rand angefragt haben, hält jeder
|
||||
Prozess eine Kopie seine Randes vom vorherigen Zeitpunkt.
|
||||
Bei der Anfrage nach dem Rand wird der nachgefragte Counter mitgeschickt, dieser muss dem aktuellen oder dem vorherigen
|
||||
Counter entsprechen oder um eins größer sein, als der aktuelle Counter.
|
||||
Ist der angefragte Counter um eins größer als der aktuelle, liegt also quasi in der Zukunft, wird der Request blockiert,
|
||||
bis der Angefragte den nächsten Entwicklungsschritt durchgeführt hat.
|
||||
Da für jeden Entwicklungsschritt zuerst die Ränder der benachbarten Teilenehmer abgefragt werden müssen und dies blockieriend geschieht, sind alle Teilnehmer zu jedem Zeitpunkt um maximal 1 bezüglich ihres Counters versetzt.
|
||||
Damit man jedoch mit seinem Entwicklungsschritt nicht warten muss, bis alle Nachbar den Rand angefragt haben, hält jeder Prozess eine Kopie seine Randes vom vorherigen Zeitpunkt.
|
||||
Bei der Anfrage nach dem Rand wird der nachgefragte Counter mitgeschickt, dieser muss dem aktuellen oder dem vorherigen Counter entsprechen oder um eins größer sein, als der aktuelle Counter.
|
||||
Ist der angefragte Counter um eins größer als der aktuelle, liegt also quasi in der Zukunft, wird der Request blockiert, bis der Angefragte den nächsten Entwicklungsschritt durchgeführt hat.
|
||||
Somit wird das gesamte Game of Life nur so schnell ausgeführt, wie der langsamste Teilenehmer ist.
|
||||
|
||||
|
||||
|
||||
<!-- LocalWords: Counter
|
||||
-->
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
pygame~=2.1.2
|
||||
requests~=2.27.1
|
Loading…
Reference in New Issue