uebung2017-4/README.md

89 lines
3.6 KiB
Markdown
Raw Normal View History

2017-05-14 22:35:13 +00: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`.
2. 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