add exercises
parent
a6a2f6bc6c
commit
2f87817658
|
@ -0,0 +1,38 @@
|
|||
# Übungsaufgabe 1: Zauberschule
|
||||
|
||||
## Einführung
|
||||
|
||||
Stell dir vor, du arbeitest an einem System zur Klassifizierung und Verwaltung von magischen Wesen in einer Zauberschule. Dein Ziel ist es, verschiedene Arten von magischen Wesen zu modellieren, ihre magische Stärke zu berechnen und Kämpfe zwischen ihnen zu simulieren.
|
||||
|
||||
## Aufgaben
|
||||
|
||||
##### 1. Definition der magischen Wesen
|
||||
Definiere einen Datentyp ```MagicalCreature```, der verschiedene magische Wesen beschreibt. In der Zauberschule gibt es Drachen (*Dragon*), Einhörner (*Unicorn*), und Zauberer (*Wizard*).
|
||||
Jede Kreatur hat:
|
||||
* einen Namen *name* (String)
|
||||
* ein Magielevel *level* (Int)
|
||||
* Erfahrungspunkte *experience* (Int)
|
||||
|
||||
Kannst du Type- und Value-Konstruktor identifizieren?
|
||||
|
||||
##### 2. Beschreibung der magischen Wesen
|
||||
Erstelle eine Funktion ```describeMagicalCreature```, die eine *MagicalCreature* entgegen nimmt und eine stringbasierte Beschreibung des Wesens zurückgibt.
|
||||
|
||||
Beispielausgabe: *"Dumbledore ist ein Zauberer mit Magielevel 13 und 70 Erfahrungspunkten."*
|
||||
Hinweis: Stelle sicher, dass die Werte des Datentyps in Zeichenketten umgewandelt werden können.
|
||||
|
||||
|
||||
##### 3. Kräfte
|
||||
Zwei Kreaturen können gegeneinander kämpfen. Manchmal sind auch Gäste aus anderen Welten zu Besuch an der Schule, die selbst keine *MagicalCreatures* sind, sich aber trotzdem gerne an den Kämpfen beteiligen möchten (Roboter, Schwertkämpfer, etc.).
|
||||
Deshalb soll eine Typklasse ```Fighter``` erstellt werden. Alle Instanzen der Typklasse müssen eine Methode ```power``` implementieren, die die Kraft der Fighter als *Int* zurückgibt. *MagicalCreatures* sollen eine Instanz dieser Typklasse sein. Die Power wird basierend auf dem Magielevel, Erfahrungswerten und dem Wesenstyp berechnet:
|
||||
* *Dragon*: (Magielevel + Erfahrung) * 3
|
||||
* *Unicorn*: (Magielevel + Erfahrung) * 4
|
||||
* *Wizard*: (Magielevel + Erfahrung) * 5
|
||||
|
||||
##### 4. Magisches Duell
|
||||
Erstelle eine Funktion ```duel```, die zwei *Fighter* gegeneinander antreten lässt. Die Kämpferin oder der Kämpfer mit der höheren Power gewinnt und soll zurückgegeben werden. Falls das Duell unentschieden ausgeht, soll ein String *"Unentschieden"* zurückgegeben werden.
|
||||
|
||||
Hinweis: Die Typklasse *Either* könnte für die Rückgabe hilfreich sein.
|
||||
|
||||
## Ausführen und Testen
|
||||
Kompiliere den Code, führe das Programm aus und überprüfe die Ausgaben.
|
|
@ -0,0 +1,40 @@
|
|||
-- 1. Definition der magischen Wesen
|
||||
|
||||
|
||||
-- 2. Beschreibung der magischen Wesen
|
||||
|
||||
|
||||
-- 3. Kämpfe
|
||||
|
||||
|
||||
-- 4. Magisches Duell
|
||||
|
||||
|
||||
|
||||
-- Hauptfunktion für Tests
|
||||
main :: IO ()
|
||||
main = do
|
||||
-- Erstellen von Beispielwesen
|
||||
let dragon = Dragon "Fafnir" 50 100
|
||||
let unicorn = Unicorn "Sternwind" 40 80
|
||||
let wizard = Wizard "Dumbledore" 30 120
|
||||
|
||||
-- Magische Kräfte anzeigen
|
||||
putStrLn $ "1. und 2. Definition und Beschreibung:"
|
||||
putStrLn $ describeMagicalCreature dragon
|
||||
putStrLn $ describeMagicalCreature unicorn
|
||||
putStrLn $ describeMagicalCreature wizard ++ "\n"
|
||||
|
||||
-- Kräfte berechnen
|
||||
putStrLn $ "3. Kräfte:"
|
||||
putStrLn $ "Power des Drachen: " ++ show (power dragon)
|
||||
putStrLn $ "Power des Einhorns: " ++ show (power unicorn)
|
||||
putStrLn $ "Power des Zauberers: " ++ show (power wizard)
|
||||
putStrLn $ "\n"
|
||||
|
||||
-- Kämpfe zwischen Wesen
|
||||
putStrLn $ "4. Magische Duelle:"
|
||||
putStrLn $ "Dragon vs. Unicorn. Gewonnen hat: " ++ show (duel dragon unicorn)
|
||||
putStrLn $ "Wizard vs. Dragon. Gewonnen hat: " ++ show (duel wizard dragon)
|
||||
putStrLn $ "Unicorn vs. Wizard. Gewonnen hat: " ++ show (duel unicorn wizard)
|
||||
putStrLn $ "Wizard vs. Wizard: " ++ show (duel wizard wizard)
|
|
@ -0,0 +1,16 @@
|
|||
# Übungsaufgabe 2: Maybe (optional)
|
||||
|
||||
## Einführung
|
||||
|
||||
Öffne GHCi und versuche, eine leere Liste an die Funktion *head* zu übergeben. Was passiert?
|
||||
|
||||
## Anweisungen
|
||||
Die Standardfunktionen *head*, *tail*, *last* und *init* sind für leere Listen problematisch, weil sie Fehler werfen. Dein Ziel ist es, eigene Versionen dieser Funktionen zu schreiben, die nie fehlschlagen. Die Funktionen sollen *Just x* zurückgeben, wenn die Liste mindestens ein Element enthält, und *Nothing*, wenn die Liste leer ist.
|
||||
|
||||
So könnte die Typannotation deiner sicheren Funktion beispielsweise aussehen:
|
||||
```safeHead :: [a] -> Maybe a```
|
||||
|
||||
|
||||
## Ausführen und Testen
|
||||
Kompiliere den Code, führe das Programm aus und überprüfe die Ausgaben. Alle Ausgaben sollten *True* sein, wenn *Just* und *Maybe* korrekt implementiert wurden.
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
import Data.Maybe (isNothing)
|
||||
|
||||
safeHead :: [a] -> Maybe a
|
||||
-- implement here
|
||||
|
||||
safeTail :: [a] -> Maybe [a]
|
||||
-- implement here
|
||||
|
||||
safeLast :: [a] -> Maybe a
|
||||
-- implement here
|
||||
|
||||
safeInit :: [a] -> Maybe [a]
|
||||
-- implement here
|
||||
|
||||
|
||||
|
||||
|
||||
-- Tests für safeHead
|
||||
testSafeHead :: IO ()
|
||||
testSafeHead = do
|
||||
print((safeHead [1,2,3]) == (Just 1))
|
||||
print(isNothing (safeHead [] :: Maybe [Int]))
|
||||
|
||||
-- Tests für safeTail
|
||||
testSafeTail :: IO ()
|
||||
testSafeTail = do
|
||||
print((safeTail [1,2,3]) == (Just [2,3]))
|
||||
print (isNothing (safeTail [] :: Maybe [Int]))
|
||||
|
||||
-- Tests für safeLast
|
||||
testSafeLast :: IO ()
|
||||
testSafeLast = do
|
||||
print((safeLast [1,2,3]) == (Just 3))
|
||||
print (isNothing (safeLast [] :: Maybe [Int]))
|
||||
|
||||
-- Tests für safeInit
|
||||
testSafeInit :: IO ()
|
||||
testSafeInit = do
|
||||
print((safeInit [1,2,3]) == (Just [1,2]))
|
||||
print (isNothing (safeInit [] :: Maybe [Int]))
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
putStrLn "Test 1: safeHead"
|
||||
testSafeHead
|
||||
putStrLn "Test 2: safeTail"
|
||||
testSafeTail
|
||||
putStrLn "Test 3: safeLast"
|
||||
testSafeLast
|
||||
putStrLn "Test 4: safeInit"
|
||||
testSafeInit
|
Loading…
Reference in New Issue