Autor: Michał Powała
Quell-Repository: Two-heroes-fight-simulation
Zwei-Helden-Kampfsimulation
Dieses Repository enthält Lösungen für bestimmte Aufgaben (unten in dieser Datei), die auf unterschiedliche Weise angegangen werden. Jeder Ansatz (der abgeschlossen ist) hat seinen eigenen Zweig und sein eigenes Tag. Die Anwendung ist über die CLI ausführbar.
Der Zweck dieses Repositorys besteht (für mich) darin, sauberen Code und ein wenig gutes Code-Design zu üben, was folgt:
- Vier Säulen von OOP (für mich, wenn man sich auf SOLID konzentriert, sind sie von selbst entstanden)
- Abstraktion
- Nachlass
- Verkapselung
- Polymorphismus
- SOLIDE Prinzipien
- Einzelverantwortung (jeder meiner Klasse hat seine eigene einzigartige Aufgabe)
- Offen/geschlossen (als ich anfing, mit verschiedenen Ansätzen zu experimentieren, blieben die meisten meiner internen Komponenten unberührt, es mussten nur neue Funktionen hinzugefügt werden)
- Liskov-Substitutionsprinzip (mein Code verwendet bei Bedarf Abstraktion und kennt die zugrunde liegende Implementierung nicht; schauen Sie sich zum Beispiel die Unit- und Colleague-Klassen an)
- Prinzip der Schnittstellentrennung (viele kleine Schnittstellen statt einer großen)
- Abhängigkeitsinversionsprinzip (der einzige Ort, an dem Klassen instanziiert werden, ist das run.php-Skript und die Fabriken, und schauen Sie sich Randomizer an – es kann verspottet werden! Ich verwende rand() nicht direkt in irgendeiner Klasse)
- Designmuster
- Dekorateur (src/Modifier)
- Fabrikmethode
- Beobachtermuster (richtiger Zweig)
- Mediatormuster (richtiger Zweig)
- Taktische DDD-Muster
- Wertobjekt (src/Property)
- Aggregate (src/Unit – jedes bisschen Logik, das hier gekapselt werden könnte, ist hier)
- Domänendienst (TurnService)
- Anwendungsdienst (GamePlayService)
- Fabriken (Fabriken)
- Ereignisse (src/Event) (ja, ich könnte stattdessen den Ereignisbus verwenden)
- Lose Kopplung (entsteht aus SOLID)
Aktions-/Ereignisprotokollierer, Fehlerprotokollierer, Drucker (Leser) und Kernlogik sind alle lose miteinander gekoppelt - TDD
Um ehrlich zu sein, ist es kein reines TDD, bei dem man zuerst Tests implementiert, die fehlschlagen, und dann den Quellcode, nach dem die Tests bestanden werden (ich denke, das ist nicht praktikabel), aber nachdem ich eine Abstraktionsebene oder eine Klasse erstellt habe, habe ich sie sofort getestet und alle kleineren Fehler behoben, wenn benötigte oder logische Fehler, über die ich nicht nachgedacht hatte. Deshalb funktionierte der Code, als ich das run.php-Skript (das den Einstiegspunkt zur Anwendung bildet) implementierte und es als letzten Schritt ausführte! Ich denke, das ist gut genug und reines TDD ist nicht erforderlich.
Wie man läuft
- Führen Sie docer aus:
docker-compose up -d
- Anwendung ausführen:
docker-compose exec cli php run.php
- Unit-Tests ausführen
docker-compose exec cli vendor/bin/phpunit tests/
AUFGABE
Erstelle eine Kampfsimulation zwischen Orderus und dem Biest. Jedes Mal, wenn der Kampf beginnt, werden Biest und Orderus mit unterschiedlichen Statistiken generiert, die den folgenden Regeln folgen:
- Bestellus:
- Gesundheit: 70 - 100
- Stärke: 70 - 80
- Verteidigung: 45 – 55
- Geschwindigkeit: 40 – 50
- Glück: 10 % – 30 % (0 % bedeutet kein Glück, 100 % immer Glück)
- zusätzliche Fähigkeiten:
- Schneller Schlag: Schlage zweimal zu, während er an der Reihe ist anzugreifen; Es besteht eine Chance von 10 %, dass er diese Fertigkeit bei jedem Angriff einsetzt
- Magischer Schild: Erleidet nur die Hälfte des üblichen Schadens, wenn ein Feind angreift; Es gibt eine 20-prozentige Änderung, wenn er diese Fertigkeit jedes Mal einsetzt, wenn er verteidigt
- Tier:
- Gesundheit: 60 - 90
- Stärke: 60 - 90
- Verteidigung: 40 – 60
- Geschwindigkeit: 40 – 60
- Glück: 25 % – 40 %
Spielregeln:
- Der erste Angriff erfolgt durch den Spieler mit der höheren Geschwindigkeit. Wenn beide Spieler die gleiche Geschwindigkeit haben, wird der Angriff von dem Spieler mit dem meisten Glück ausgeführt.
- Nach einem Angriff wechseln die Spieler die Rollen: Der Angreifer verteidigt nun, der Verteidiger greift nun an.
- Der vom Angreifer verursachte Schaden wird mit der folgenden Formel berechnet:
Damage = Attacker strength – Defender defence
- Der Schaden wird von der Gesundheit des Verteidigers abgezogen. Ein Angreifer kann seinen Treffer verfehlen und keinen Schaden anrichten, wenn der Verteidiger in diesem Zug Glück hat.
- Die Fähigkeiten von Orderus treten je nach Wahrscheinlichkeit zufällig auf, also berücksichtige sie in jeder Runde.
- Das Spiel endet, wenn einer der Spieler keine Gesundheit mehr hat oder die Anzahl der Runden 20 erreicht.
- Die Anwendung muss in jeder Runde die Ergebnisse ausgeben: Was ist passiert, welche Fähigkeiten wurden verwendet (falls vorhanden), der verursachte Schaden, die verbleibende Gesundheit des Verteidigers.
- Wenn wir einen Gewinner haben, bevor die maximale Anzahl an Runden erreicht ist, muss er bekannt gegeben werden.
ZWEIGE und TAGS
- Zweig: Basis; tag: base-running-app:
Enthält eine Basislösung (Kernfunktionalität, Unit-getestet), die das Drucken noch nicht unterstützt - Zweig: Beobachtermuster; Tag: Running-App-Observer-Muster:
Enthält den gesamten Code aus base
und erweitert ihn um Drucken und Protokollieren unter Verwendung von Observer Pattern - Zweig: Mediator-Muster; Tag: Running-App-Mediator-Muster:
Enthält den gesamten Code aus base
und erweitert ihn um Drucken und Protokollieren unter Verwendung von Mediator Pattern
Weitere Zweige und Ansätze werden hinzugefügt...
Aktueller Zweig: Basis
WORT DER ERKLÄRUNG
Die einfachste und „Web-App“-Lösung wäre die Verwendung eines externen oder selbst erstellten Event-Busses, aber ich möchte einfach nur mit Design Patterns herumspielen (vielleicht füge ich diese Lösung eines Tages hinzu).
TODO
- Ich habe vergessen, die Fehlschlagfähigkeit zu implementieren ...
- Korrigieren Sie eine nicht vorhandene Delegation im MagicShield-Dekorator