add exercises

main
nicole 2025-02-02 23:02:05 +01:00
parent a6a2f6bc6c
commit 2f87817658
4 changed files with 145 additions and 0 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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.

View File

@ -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