app | ||
src | ||
test | ||
.gitignore | ||
.travis.yml | ||
LICENSE | ||
README.md | ||
Setup.hs | ||
stack.yaml | ||
zettel4.cabal |
Ü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.
- Ergänzen Sie den Code, so dass ein toter Boss als rotes
'T'
, ein toter Hero als grünes'T'
dargestellt wird. - 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
- Implementieren Sie eine neue
Action
, die die Blickrichtung des Helden ändert, ohne dass ein World-Update stattfindet. Erweitern Sie hierfür entsprechend denAction
-Typ inGameTypes.hs
, modifizieren SieperformAction
inGameLogic.hs
und schreiben Sie eine FunktionchangeDirection :: Direction -> World -> World
. Erweitern Sie außerdemgetAction
inGameConfig.hs
, so dass gilt:
'h'
führt zu Blick nachWest
'j'
führt zu Blick nachNorth
'k'
führt zu Blick nachSouth
'l'
führt zu Blick nachEast
.
- 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 einenAction
-Wert (SetTrap
) und einenEntity
- Wert (Trap
) inGameTypes.hs
angelegt undgetAction
inGameConfig.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