Record syntax, Lenses, Quickcheck, Dungeon crawler...
Go to file
2017-05-15 12:15:34 +02:00
app first commit 2017-05-15 00:35:13 +02:00
src first commit 2017-05-15 00:35:13 +02:00
test first commit 2017-05-15 00:35:13 +02:00
.gitignore first commit 2017-05-15 00:35:13 +02:00
.travis.yml first commit 2017-05-15 00:35:13 +02:00
LICENSE first commit 2017-05-15 00:35:13 +02:00
README.md Update README.md 2017-05-15 12:15:34 +02:00
Setup.hs first commit 2017-05-15 00:35:13 +02:00
stack.yaml first commit 2017-05-15 00:35:13 +02:00
zettel4.cabal first commit 2017-05-15 00:35:13 +02:00

Übungszettel 4

In dieser und den nächsten Übungen werden wir uns mit der (Weiter-)Entwicklung eines Spiels beschäftigen.

Bisher umfasst das Spiel die folgenden Module:

  • GameTypes.hs
  • GameLogic.hs
  • GameDraw.hs
  • GameConfig.hs
  • GameMain.hs

Sie können es mit stack exec Game ausprobieren.

Wie Sie sehen werden, sind uns bei der Implementation dieses Spiels leider einige Fehler unterlaufen. Außerdem fehlen noch einige wichtige Features, aber zum Glück kennen sich unsere Tutanden gut genug aus, um uns zu helfen!

Issue 1

Sie haben in der Vorlesung bereits Record syntax kennengelernt. Im Modul GameLogic.hs unter "Initialization" findet sich die unschöne Funktion newWorld. Geben Sie dieser Funktion eine anschauliche Form, indem Sie Teilausdrücke refaktorisieren (in sinnvollen Funktionen oder where-/let-Klauseln) und verwenden Sie Record syntax um eine default World anzulegen! Bedenken Sie, dass sie zur Zuweisung einzelner Record fields genau deren Namen verwenden müssen (nicht die daraus erstellten Lenses).

Issue 2

In der Datei GameDraw.hs wird bestimmt, wie eine World angezeigt wird.

  1. Ergänzen Sie den Code, so dass ein toter Boss als rotes 'T', ein toter Hero als grünes 'T' dargestellt wird.
  2. Ergänzen Sie das Spiel um einen visuellen Hinweis, der anzeigt, ob das Spiel pausiert ist.

Issue 3

Obwohl die Spielerbewegung einwandfrei funktioniert, schlägt der entsprechende QuickCheck-Test fehl! Korrigieren Sie den QuickCheck-Test.

Issue 4

  1. Implementieren Sie eine neue Action, die die Blickrichtung des Helden ändert, ohne dass ein World-Update stattfindet. Erweitern Sie hierfür entsprechend den Action-Typ in GameTypes.hs, modifizieren Sie performAction in GameLogic.hs und schreiben Sie eine Funktion changeDirection :: Direction -> World -> World. Erweitern Sie außerdem getAction in GameConfig.hs, so dass gilt:
  • 'h' führt zu Blick nach West
  • 'j' führt zu Blick nach North
  • 'k' führt zu Blick nach South
  • 'l' führt zu Blick nach East.
  1. Eine Kollegin hat begonnen ein neues Feature zu implementieren: Eine neue Action soll dem Spieler/der Spielerin das Stellen von Fallen vor dem Helden ermöglichen. Bewegt sich ein Monster auf eine solche Falle, soll diese zuschnappen und Schaden zufügen. Die Kollegin hat bereits einen Action-Wert (SetTrap) und einen Entity- Wert (Trap) in GameTypes.hs angelegt und getAction in GameConfig.hs angepasst. Im GameLogic-Modul hat sie die zu modifizierenden Stellen mit einem -- TODO-Kommentar markiert. Bringen Sie ihre Arbeit zuende.

Bonus: Issue 5

An einigen Stellen im Code fügen Entities Schaden zu. Hard coded finden sich folgende Schadenswerte:

  • Angreifender Hero fügt Boss 45 Schaden zu
  • Explodierende Bomb fügt Held 30 bzw. entfernter 15 Schaden zu
  • Läuft der Held in ein Fire fügt es ihm 15 Schaden zu
  • Läuft der Boss in eine Trap fügt diese ihm x Schaden zu

Implementieren Sie ein sinnvolles Schadensystem, in dem Sie den Typ Stats um ein Feld _damage :: Integer erweitern. Ein großes Feuer soll mehr Schaden zufügen als ein kleines. Passen Sie die GameLogic entsprechend an. Hinweis: Trap hat bisher keine Stats. Wie Sie hier verfahren, ist Ihnen überlassen.

Appendix:

Die wichtigsten Lens operators (unbedingt anschauen): https://github.com/ekmett/lens/wiki/Operators

Auch das hier ist definitv einen Blick Wert: http://intolerable.me/lens-operators-intro/

Und hier noch ein Link zu Setter: https://hackage.haskell.org/package/lens-4.15.2/docs/Control-Lens-Setter.html