{ "games": [ { "slug": "query-builder", "title": "Query Builder", "language": "SQL", "path": "syntax", "description": "Baue SQL-Abfragen Stück für Stück zusammen und lerne die Reihenfolge der Klauseln.", "tasks": [ { "type": "cloze", "prompt": "Spalten auswählen", "points": 100, "narrative": "Jede Abfrage beginnt mit dem richtigen Keyword.", "codeTemplate": "{{1}} name, stadt\nFROM kunden;", "gaps": [ { "position": 1, "placeholder": "Keyword", "hint": "Womit wählst du Spalten aus?", "caseSensitive": false, "solutions": [ "SELECT" ] } ], "hint": "Das allererste Wort jeder Lese-Abfrage.", "successText": "Perfekt, die Spalten sind ausgewählt!" }, { "type": "match", "prompt": "Klausel und Zweck", "points": 100, "instruction": "Ordne jede Klausel ihrer Aufgabe zu.", "pairs": [ [ "WHERE", "filtert einzelne Zeilen" ], [ "GROUP BY", "fasst Zeilen zu Gruppen zusammen" ], [ "HAVING", "filtert ganze Gruppen" ], [ "ORDER BY", "sortiert das Ergebnis" ] ], "hint": "WHERE wirkt VOR der Gruppierung, HAVING danach.", "successText": "Alle Klauseln richtig zugeordnet!" }, { "type": "choice", "prompt": "Der Durchschnitt", "points": 100, "question": "Welche Aggregatfunktion liefert den Durchschnittswert?", "options": [ "SUM()", "AVG()", "COUNT()", "MAX()" ], "correctIndex": 1, "hint": "Average heißt Durchschnitt.", "successText": "Richtig, AVG() berechnet den Mittelwert." }, { "type": "cloze", "prompt": "Zeilen filtern", "points": 100, "narrative": "Du suchst nur Kunden aus Leipzig.", "codeTemplate": "SELECT name\nFROM kunden\nWHERE stadt {{1}} 'Leipzig';", "gaps": [ { "position": 1, "placeholder": "Operator", "hint": "Test auf Gleichheit.", "caseSensitive": false, "solutions": [ "=" ] } ], "hint": "In SQL prüft man Gleichheit mit einem einzelnen Zeichen.", "successText": "Gut gefiltert!" }, { "type": "cloze", "prompt": "Nur Eindeutiges", "points": 100, "narrative": "Du willst jede Stadt nur einmal sehen.", "codeTemplate": "SELECT {{1}} stadt\nFROM kunden;", "gaps": [ { "position": 1, "placeholder": "Keyword", "hint": "Entfernt doppelte Werte.", "caseSensitive": false, "solutions": [ "DISTINCT" ] } ], "hint": "Das Wort steht direkt hinter SELECT.", "successText": "Duplikate verschwunden!" }, { "type": "choice", "prompt": "Alle Zeilen zählen", "points": 100, "question": "Wie zählst du die Anzahl aller Zeilen einer Tabelle?", "options": [ "COUNT(*)", "SUM(*)", "TOTAL()", "ROWS()" ], "correctIndex": 0, "hint": "Der Stern steht für alle Spalten.", "successText": "Genau, COUNT(*) zählt jede Zeile." }, { "type": "cloze", "prompt": "Gruppieren", "points": 100, "narrative": "Wie viele Mitarbeiter hat jede Abteilung?", "codeTemplate": "SELECT abteilung, COUNT(*)\nFROM mitarbeiter\n{{1}} abteilung;", "gaps": [ { "position": 1, "placeholder": "Klausel", "hint": "Fasst Zeilen je Abteilung zusammen.", "caseSensitive": false, "solutions": [ "GROUP BY" ] } ], "hint": "Zwei Wörter mit Leerzeichen.", "successText": "Sauber gruppiert!" }, { "type": "order", "prompt": "Einfache Abfrage bauen", "points": 100, "instruction": "Bring die Zeilen in die korrekte SQL-Reihenfolge.", "items": [ "SELECT name", "FROM kunden", "WHERE stadt = 'Berlin'", "ORDER BY name" ], "hint": "Erst auswählen, dann woher, dann filtern, dann sortieren.", "successText": "Die Abfrage steht richtig!" }, { "type": "cloze", "prompt": "Absteigend sortieren", "points": 100, "narrative": "Die ältesten Kunden sollen oben stehen.", "codeTemplate": "SELECT name, alter\nFROM kunden\nORDER BY alter {{1}};", "gaps": [ { "position": 1, "placeholder": "Keyword", "hint": "Descending = absteigend.", "caseSensitive": false, "solutions": [ "DESC" ] } ], "hint": "Drei Buchstaben für absteigend.", "successText": "Größter Wert zuerst!" }, { "type": "choice", "prompt": "Vor der Gruppierung filtern", "points": 100, "question": "Welche Klausel filtert Zeilen, BEVOR gruppiert wird?", "options": [ "HAVING", "WHERE", "GROUP BY", "ORDER BY" ], "correctIndex": 1, "hint": "Diese Klausel arbeitet auf einzelnen Zeilen.", "successText": "Richtig, WHERE filtert vor der Gruppierung." }, { "type": "cloze", "prompt": "Gruppen filtern", "points": 100, "narrative": "Nur Abteilungen mit mehr als 5 Leuten interessieren dich.", "codeTemplate": "SELECT abteilung, COUNT(*)\nFROM mitarbeiter\nGROUP BY abteilung\n{{1}} COUNT(*) > 5;", "gaps": [ { "position": 1, "placeholder": "Klausel", "hint": "Filtert nach dem Gruppieren.", "caseSensitive": false, "solutions": [ "HAVING" ] } ], "hint": "WHERE geht hier nicht, weil aggregiert wird.", "successText": "Nur große Abteilungen bleiben übrig!" }, { "type": "choice", "prompt": "Nach der Gruppierung", "points": 100, "question": "Welche Klausel filtert ganze Gruppen NACH GROUP BY?", "options": [ "WHERE", "HAVING", "LIMIT", "ON" ], "correctIndex": 1, "hint": "Sie kann Aggregatfunktionen wie COUNT(*) nutzen.", "successText": "Korrekt, HAVING filtert Gruppen." }, { "type": "match", "prompt": "Aggregatfunktionen", "points": 100, "instruction": "Ordne jede Funktion ihrer Bedeutung zu.", "pairs": [ [ "COUNT()", "Anzahl" ], [ "SUM()", "Summe" ], [ "AVG()", "Durchschnitt" ], [ "MAX()", "Maximum" ], [ "MIN()", "Minimum" ] ], "hint": "Englische Wörter helfen: count, sum, average ...", "successText": "Alle Funktionen sitzen!" }, { "type": "cloze", "prompt": "Ergebnis begrenzen", "points": 100, "narrative": "Du brauchst nur die ersten 10 Treffer.", "codeTemplate": "SELECT name\nFROM kunden\n{{1}} 10;", "gaps": [ { "position": 1, "placeholder": "Klausel", "hint": "Begrenzt die Zeilenzahl.", "caseSensitive": false, "solutions": [ "LIMIT" ] } ], "hint": "Englisch für Grenze.", "successText": "Nur 10 Zeilen, perfekt!" }, { "type": "cloze", "prompt": "Datensatz einfügen", "points": 100, "narrative": "Ein neuer Kunde kommt in die Tabelle.", "codeTemplate": "{{1}} INTO kunden (name, stadt)\n{{2}} ('Anna', 'Berlin');", "gaps": [ { "position": 1, "placeholder": "Keyword", "hint": "Womit fügst du ein?", "caseSensitive": false, "solutions": [ "INSERT" ] }, { "position": 2, "placeholder": "Keyword", "hint": "Leitet die Werteliste ein.", "caseSensitive": false, "solutions": [ "VALUES" ] } ], "hint": "INSERT INTO ... VALUES (...).", "successText": "Anna ist eingetragen!" }, { "type": "order", "prompt": "Vollständige Abfrage", "points": 100, "instruction": "Setze die komplette Abfrage in die richtige Reihenfolge.", "items": [ "SELECT abteilung, COUNT(*)", "FROM mitarbeiter", "WHERE gehalt > 3000", "GROUP BY abteilung", "HAVING COUNT(*) > 2", "ORDER BY abteilung" ], "hint": "SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY.", "successText": "Die ganze Query steht korrekt!" } ] }, { "slug": "sql-detective", "title": "SQL Detective", "language": "SQL", "path": "debugging", "description": "Löse IT-Ermittlungsfälle, indem du fehlerhafte und fehlende Teile von SQL-Abfragen aufspürst.", "tasks": [ { "type": "spot", "prompt": "Fall: Falsche Anführungszeichen", "points": 100, "narrative": "Die Abfrage liefert einen Fehler statt der Berliner Kunden.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "SELECT", "*", "FROM", "kunden", "WHERE", "stadt", "=", "\"Berlin\"", ";" ], "bugIndex": 7, "fix": "'Berlin'", "hint": "String-Literale brauchen in SQL einfache Anführungszeichen.", "successText": "Gelöst! Strings stehen in einfachen Quotes." }, { "type": "choice", "prompt": "Fall: NULL-Werte finden", "points": 100, "question": "Welche Bedingung findet Zeilen ohne Stadt (NULL)?", "options": [ "stadt = NULL", "stadt IS NULL", "stadt == NULL", "stadt NULL()" ], "correctIndex": 1, "hint": "Mit = lässt sich NULL nicht vergleichen.", "successText": "Richtig, NULL prüft man mit IS NULL." }, { "type": "cloze", "prompt": "Fall: Fehlendes JOIN-Schlüsselwort", "points": 100, "narrative": "Der Verknüpfungs-Befehl fehlt zwischen den Tabellen.", "codeTemplate": "SELECT *\nFROM bestellungen b\nJOIN kunden k {{1}} b.kunde_id = k.id;", "gaps": [ { "position": 1, "placeholder": "Keyword", "hint": "Gibt die Verknüpfungsbedingung an.", "caseSensitive": false, "solutions": [ "ON" ] } ], "hint": "Zwei Buchstaben.", "successText": "Die Tabellen sind sauber verbunden!" }, { "type": "spot", "prompt": "Fall: Kaputter Operator", "points": 100, "narrative": "Der Vergleichsoperator existiert so nicht.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "SELECT", "name", "FROM", "kunden", "WHERE", "alter", "=>", "18", ";" ], "bugIndex": 6, "fix": ">=", "hint": "Größer-oder-gleich schreibt man andersherum.", "successText": "Korrekt, der Operator heißt >=." }, { "type": "cloze", "prompt": "Fall: NULL-Prüfung ergänzen", "points": 100, "narrative": "Du suchst Kunden, bei denen keine Stadt hinterlegt ist.", "codeTemplate": "SELECT name\nFROM kunden\nWHERE stadt {{1}} NULL;", "gaps": [ { "position": 1, "placeholder": "Operator", "hint": "Nicht = verwenden!", "caseSensitive": false, "solutions": [ "IS" ] } ], "hint": "Das Schlüsselwort für NULL-Vergleiche.", "successText": "Sauber, IS NULL funktioniert." }, { "type": "choice", "prompt": "Fall: Der richtige JOIN", "points": 100, "question": "Welcher JOIN liefert ALLE Zeilen der linken Tabelle, auch ohne Treffer rechts?", "options": [ "INNER JOIN", "LEFT JOIN", "RIGHT JOIN", "CROSS JOIN" ], "correctIndex": 1, "hint": "Links steht zuerst.", "successText": "Richtig, LEFT JOIN behält alle linken Zeilen." }, { "type": "spot", "prompt": "Fall: Verlorenes Komma", "points": 100, "narrative": "Zwischen zwei Spalten hat sich ein falsches Wort eingeschlichen.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "SELECT", "name", "AND", "stadt", "FROM", "kunden", ";" ], "bugIndex": 2, "fix": ",", "hint": "Spalten werden nicht mit AND getrennt.", "successText": "Genau, Spalten trennt ein Komma." }, { "type": "cloze", "prompt": "Fall: Muster-Suche", "points": 100, "narrative": "Du suchst alle Namen, die mit A beginnen.", "codeTemplate": "SELECT name\nFROM kunden\nWHERE name {{1}} 'A%';", "gaps": [ { "position": 1, "placeholder": "Operator", "hint": "Für Mustervergleiche mit %.", "caseSensitive": false, "solutions": [ "LIKE" ] } ], "hint": "Vier Buchstaben für Textmuster.", "successText": "Alle A-Namen gefunden!" }, { "type": "choice", "prompt": "Fall: Nur gemeinsame Treffer", "points": 100, "question": "Welcher JOIN liefert nur Zeilen, die in BEIDEN Tabellen einen Treffer haben?", "options": [ "LEFT JOIN", "FULL JOIN", "INNER JOIN", "RIGHT JOIN" ], "correctIndex": 2, "hint": "Die Schnittmenge beider Tabellen.", "successText": "Korrekt, INNER JOIN zeigt nur Übereinstimmungen." }, { "type": "spot", "prompt": "Fall: NULL falsch verglichen", "points": 100, "narrative": "Diese Abfrage liefert nie ein Ergebnis, obwohl es NULL-Werte gibt.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "SELECT", "*", "FROM", "kunden", "WHERE", "stadt", "=", "NULL", ";" ], "bugIndex": 6, "fix": "IS", "hint": "NULL lässt sich nicht mit = vergleichen.", "successText": "Gelöst! IS NULL statt = NULL." }, { "type": "cloze", "prompt": "Fall: Bereich abfragen", "points": 100, "narrative": "Gesucht sind Produkte zwischen 10 und 20 Euro.", "codeTemplate": "SELECT *\nFROM produkte\nWHERE preis {{1}} 10 AND 20;", "gaps": [ { "position": 1, "placeholder": "Keyword", "hint": "Für einen Wertebereich inklusive Grenzen.", "caseSensitive": false, "solutions": [ "BETWEEN" ] } ], "hint": "Englisch für 'zwischen'.", "successText": "Bereich korrekt eingegrenzt!" }, { "type": "match", "prompt": "Fall: JOIN-Typen einordnen", "points": 100, "instruction": "Ordne jedem JOIN-Typ seine Bedeutung zu.", "pairs": [ [ "INNER JOIN", "nur Treffer in beiden Tabellen" ], [ "LEFT JOIN", "alle links + passende rechts" ], [ "RIGHT JOIN", "alle rechts + passende links" ], [ "FULL JOIN", "alle Zeilen beider Tabellen" ] ], "hint": "Denk an links, rechts und beide Seiten.", "successText": "Alle JOIN-Typen aufgeklärt!" }, { "type": "spot", "prompt": "Fall: Tippfehler im Schlüsselwort", "points": 100, "narrative": "Ein Schlüsselwort wurde vertippt und blockiert die Abfrage.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "SELECT", "COUNT(*)", "FROM", "mitarbeiter", "GROPU BY", "abteilung", ";" ], "bugIndex": 4, "fix": "GROUP BY", "hint": "Lies das Gruppierungs-Keyword genau.", "successText": "Tippfehler entlarvt: GROUP BY!" }, { "type": "cloze", "prompt": "Fall: Liste von Werten", "points": 100, "narrative": "Gesucht sind Kunden aus Berlin oder Leipzig.", "codeTemplate": "SELECT *\nFROM kunden\nWHERE stadt {{1}} ('Berlin', 'Leipzig');", "gaps": [ { "position": 1, "placeholder": "Operator", "hint": "Prüft, ob ein Wert in einer Liste steht.", "caseSensitive": false, "solutions": [ "IN" ] } ], "hint": "Zwei Buchstaben.", "successText": "Beide Städte erfasst!" }, { "type": "choice", "prompt": "Fall: Kreuzprodukt", "points": 100, "question": "Wie viele Zeilen liefert ein CROSS JOIN von 3 und 4 Zeilen?", "options": [ "7", "12", "3", "4" ], "correctIndex": 1, "hint": "Beim Kreuzprodukt wird multipliziert.", "successText": "Richtig, 3 mal 4 = 12 Zeilen." }, { "type": "cloze", "prompt": "Fall: Eindeutige zählen", "points": 100, "narrative": "Wie viele verschiedene Städte kommen vor?", "codeTemplate": "SELECT COUNT({{1}} stadt)\nFROM kunden;", "gaps": [ { "position": 1, "placeholder": "Keyword", "hint": "Zählt nur unterschiedliche Werte.", "caseSensitive": false, "solutions": [ "DISTINCT" ] } ], "hint": "Das gleiche Wort, das Duplikate entfernt.", "successText": "Nur eindeutige Städte gezählt!" } ] }, { "slug": "debug-hunt", "title": "Debug Hunt", "language": "Java", "path": "debugging", "description": "Jage echte Bugs in Java-Code: falsche Typen, Vergleiche, Indizes und mehr.", "tasks": [ { "type": "spot", "prompt": "Falscher Datentyp", "points": 100, "narrative": "Hier wird einer int-Variablen ein Text zugewiesen.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "int", "x", "=", "\"10\"", ";" ], "bugIndex": 3, "fix": "10", "hint": "Ein int speichert Zahlen, keinen String.", "successText": "Erwischt! 10 ohne Anführungszeichen." }, { "type": "choice", "prompt": "Was wird ausgegeben?", "points": 100, "question": "Was gibt System.out.println(5 + 3 + \"!\"); aus?", "options": [ "53!", "8!", "5 + 3!", "!8" ], "correctIndex": 1, "hint": "Erst werden die Zahlen addiert, dann kommt der Text.", "successText": "Richtig, 5+3=8, also 8!" }, { "type": "cloze", "prompt": "Vergleich statt Zuweisung", "points": 100, "narrative": "In der Bedingung soll verglichen werden, nicht zugewiesen.", "codeTemplate": "if (x {{1}} 5) {\n System.out.println(\"fünf\");\n}", "gaps": [ { "position": 1, "placeholder": "Operator", "hint": "Doppeltes Zeichen für Gleichheit.", "caseSensitive": true, "solutions": [ "==" ] } ], "hint": "Ein einzelnes = würde nur zuweisen.", "successText": "Korrekt, == vergleicht Werte." }, { "type": "spot", "prompt": "Fehlendes Semikolon", "points": 100, "narrative": "Diese Zeile endet mit dem falschen Zeichen.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "int", "y", "=", "5", "," ], "bugIndex": 4, "fix": ";", "hint": "Anweisungen enden in Java nicht mit Komma.", "successText": "Gut, eine Anweisung endet mit ;" }, { "type": "cloze", "prompt": "Null-Prüfung", "points": 100, "narrative": "Vor dem Zugriff soll geprüft werden, ob name nicht null ist.", "codeTemplate": "if (name {{1}} null) {\n name.length();\n}", "gaps": [ { "position": 1, "placeholder": "Operator", "hint": "Ungleich.", "caseSensitive": true, "solutions": [ "!=" ] } ], "hint": "Ausrufezeichen und Gleichheitszeichen.", "successText": "Sicher, != null verhindert den Crash." }, { "type": "choice", "prompt": "String-Vergleich", "points": 100, "question": "Welcher Fehler steckt in if (s == \"hallo\") für einen Inhaltsvergleich?", "options": [ "Vergleicht Referenzen statt Inhalt", "Syntaxfehler", "Nichts, ist korrekt", "s muss großgeschrieben sein" ], "correctIndex": 0, "hint": "Für String-Inhalte nutzt man equals().", "successText": "Richtig, == vergleicht nur Referenzen." }, { "type": "spot", "prompt": "Index außerhalb der Grenzen", "points": 100, "narrative": "Diese Schleife greift einen Schritt zu weit zu.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "for", "(", "int", "i", "=", "0", ";", "i", "<=", "arr.length", ";", "i++", ")" ], "bugIndex": 8, "fix": "<", "hint": "Gültige Indizes gehen von 0 bis length-1.", "successText": "Gelöst! i < arr.length verhindert den Überlauf." }, { "type": "cloze", "prompt": "Rückgabewert", "points": 100, "narrative": "Die Methode soll das Quadrat zurückgeben, tut es aber nicht.", "codeTemplate": "int quadrat(int n) {\n {{1}} n * n;\n}", "gaps": [ { "position": 1, "placeholder": "Keyword", "hint": "Liefert einen Wert zurück.", "caseSensitive": true, "solutions": [ "return" ] } ], "hint": "Sechs Buchstaben, kleingeschrieben.", "successText": "Korrekt, return gibt das Ergebnis zurück." }, { "type": "choice", "prompt": "Ganzzahl-Division", "points": 100, "question": "Was ergibt 10 / 3 in Java, wenn beide Werte int sind?", "options": [ "3.33", "3", "4", "3.0" ], "correctIndex": 1, "hint": "Bei int-Division wird der Rest verworfen.", "successText": "Richtig, das Ergebnis ist 3." }, { "type": "spot", "prompt": "Falscher Variablentyp", "points": 100, "narrative": "Ein Wahrheitswert wird im falschen Typ gespeichert.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "int", "flag", "=", "true", ";" ], "bugIndex": 0, "fix": "boolean", "hint": "true und false brauchen einen eigenen Typ.", "successText": "Erwischt! boolean statt int." }, { "type": "cloze", "prompt": "Typ für Wahrheitswerte", "points": 100, "narrative": "Welcher Datentyp speichert true oder false?", "codeTemplate": "{{1}} aktiv = true;", "gaps": [ { "position": 1, "placeholder": "Datentyp", "hint": "Für ja/nein-Werte.", "caseSensitive": true, "solutions": [ "boolean" ] } ], "hint": "Sieben Buchstaben, kleingeschrieben.", "successText": "Korrekt, boolean speichert Wahrheitswerte." }, { "type": "choice", "prompt": "String-Verkettung", "points": 100, "question": "Was gibt System.out.println(\"\" + 5 + 3); aus?", "options": [ "8", "53", "5 3", "Fehler" ], "correctIndex": 1, "hint": "Sobald ein String dabei ist, wird verkettet statt addiert.", "successText": "Richtig, das Ergebnis ist 53." }, { "type": "spot", "prompt": "Verdrehter Operator", "points": 100, "narrative": "Der Ungleich-Operator wurde falsch herum geschrieben.", "instruction": "Klick den fehlerhaften Token an.", "tokens": [ "if", "(", "a", "=!", "b", ")" ], "bugIndex": 3, "fix": "!=", "hint": "Erst das Ausrufezeichen, dann das Gleichheitszeichen.", "successText": "Gelöst! Der Operator heißt !=." }, { "type": "cloze", "prompt": "Kurzschreibweise zum Addieren", "points": 100, "narrative": "Der Wert von summe soll um 5 erhöht werden.", "codeTemplate": "int summe = 0;\nsumme {{1}} 5;", "gaps": [ { "position": 1, "placeholder": "Operator", "hint": "Kurzform für summe = summe + 5.", "caseSensitive": true, "solutions": [ "+=" ] } ], "hint": "Plus und Gleichheitszeichen.", "successText": "Korrekt, += addiert und weist zu." }, { "type": "choice", "prompt": "Array-Zugriff", "points": 100, "question": "Was passiert bei int[] a = new int[3]; a[3] = 1;?", "options": [ "Läuft normal durch", "ArrayIndexOutOfBoundsException", "NullPointerException", "Kompilierfehler" ], "correctIndex": 1, "hint": "Gültige Indizes sind 0, 1 und 2.", "successText": "Richtig, Index 3 existiert nicht." }, { "type": "cloze", "prompt": "Schleifenbedingung", "points": 100, "narrative": "Die Schleife soll genau zehnmal laufen (0 bis 9).", "codeTemplate": "for (int i = 0; i {{1}} 10; i++) {\n System.out.println(i);\n}", "gaps": [ { "position": 1, "placeholder": "Operator", "hint": "Kleiner als, nicht kleiner-gleich.", "caseSensitive": true, "solutions": [ "<" ] } ], "hint": "Mit <= würde sie elfmal laufen.", "successText": "Korrekt, i < 10 ergibt 10 Durchläufe." }, { "type": "choice", "prompt": "Was steht in b?", "points": 100, "question": "Welchen Wert hat b nach boolean b = 5 > 3;?", "options": [ "true", "false", "1", "Fehler" ], "correctIndex": 0, "hint": "Ist 5 wirklich größer als 3?", "successText": "Richtig, 5 > 3 ist true." } ] }, { "slug": "git-mission", "title": "Git Mission", "language": "Git", "path": "debugging", "description": "Meistere typische Repo-Situationen mit den richtigen Git-Befehlen und Reihenfolgen.", "tasks": [ { "type": "order", "prompt": "Mission: Änderung veröffentlichen", "points": 100, "instruction": "Bring die Befehle in die richtige Reihenfolge.", "items": [ "git add .", "git commit -m \"feat: Login hinzugefügt\"", "git push" ], "hint": "Erst vormerken, dann festschreiben, dann hochladen.", "successText": "Deine Änderung ist veröffentlicht!" }, { "type": "cloze", "prompt": "Befehl: Festschreiben", "points": 100, "narrative": "Deine vorgemerkten Änderungen sollen gespeichert werden.", "codeTemplate": "git {{1}} -m \"fix: Bug behoben\"", "gaps": [ { "position": 1, "placeholder": "Befehl", "hint": "Schreibt Änderungen in die Historie.", "caseSensitive": true, "solutions": [ "commit" ] } ], "hint": "Sechs Buchstaben.", "successText": "Commit erstellt!" }, { "type": "choice", "prompt": "Mission: Historie ansehen", "points": 100, "question": "Welcher Befehl zeigt den Commit-Verlauf?", "options": [ "git status", "git log", "git diff", "git show" ], "correctIndex": 1, "hint": "Englisch für Protokoll.", "successText": "Richtig, git log zeigt die Historie." }, { "type": "cloze", "prompt": "Befehl: Branch wechseln", "points": 100, "narrative": "Du willst zurück auf den main-Branch.", "codeTemplate": "git {{1}} main", "gaps": [ { "position": 1, "placeholder": "Befehl", "hint": "Moderner Befehl zum Branch-Wechsel.", "caseSensitive": true, "solutions": [ "switch", "checkout" ] } ], "hint": "switch oder das ältere checkout.", "successText": "Du bist jetzt auf main!" }, { "type": "order", "prompt": "Mission: Arbeit zwischenparken", "points": 100, "instruction": "Du musst schnell den Branch wechseln, ohne zu committen. Ordne die Schritte.", "items": [ "git stash", "git switch main", "git pull", "git switch feature", "git stash pop" ], "hint": "Erst sichern, Branch-Arbeit erledigen, dann zurückholen.", "successText": "Deine Arbeit ist wieder da!" }, { "type": "choice", "prompt": "Mission: Lokale Änderung verwerfen", "points": 100, "question": "Du willst eine noch NICHT committete Änderung an datei.txt verwerfen. Welcher Befehl?", "options": [ "git restore datei.txt", "git revert HEAD", "git reset --hard origin", "git rm datei.txt" ], "correctIndex": 0, "hint": "restore stellt den letzten committeten Stand wieder her.", "successText": "Richtig, git restore verwirft die Änderung." }, { "type": "cloze", "prompt": "Befehl: Branch zusammenführen", "points": 100, "narrative": "Der Feature-Branch soll in den aktuellen Branch übernommen werden.", "codeTemplate": "git {{1}} feature/login", "gaps": [ { "position": 1, "placeholder": "Befehl", "hint": "Führt zwei Branches zusammen.", "caseSensitive": true, "solutions": [ "merge" ] } ], "hint": "Englisch für verschmelzen.", "successText": "Branches zusammengeführt!" }, { "type": "order", "prompt": "Mission: Neuer Feature-Branch", "points": 100, "instruction": "Starte ein neues Feature und veröffentliche es. Ordne die Schritte.", "items": [ "git switch -c feature/login", "git add .", "git commit -m \"Login umgesetzt\"", "git push -u origin feature/login" ], "hint": "Branch anlegen, vormerken, committen, hochladen.", "successText": "Feature-Branch steht online!" }, { "type": "cloze", "prompt": "Befehl: Einzelnen Commit holen", "points": 100, "narrative": "Du brauchst genau einen Commit aus einem anderen Branch.", "codeTemplate": "git {{1}} a1b2c3d", "gaps": [ { "position": 1, "placeholder": "Befehl", "hint": "Pflückt einen einzelnen Commit.", "caseSensitive": true, "solutions": [ "cherry-pick" ] } ], "hint": "Zwei Wörter mit Bindestrich.", "successText": "Commit übernommen!" }, { "type": "choice", "prompt": "Mission: Gepushten Commit zurücknehmen", "points": 100, "question": "Welcher Befehl macht einen bereits gepushten Commit mit einem neuen Commit rückgängig?", "options": [ "git reset --hard", "git revert ", "git checkout", "git clean" ], "correctIndex": 1, "hint": "Er ändert die Historie nicht, sondern kehrt sie um.", "successText": "Richtig, git revert ist sicher für geteilte Branches." }, { "type": "cloze", "prompt": "Befehl: Commit umkehren", "points": 100, "narrative": "Der letzte Commit soll durch einen Gegen-Commit rückgängig gemacht werden.", "codeTemplate": "git {{1}} HEAD", "gaps": [ { "position": 1, "placeholder": "Befehl", "hint": "Erzeugt einen umkehrenden Commit.", "caseSensitive": true, "solutions": [ "revert" ] } ], "hint": "Englisch für rückgängig machen.", "successText": "Der Commit ist umgekehrt!" }, { "type": "order", "prompt": "Mission: Merge-Konflikt lösen", "points": 100, "instruction": "Beim Zusammenführen entsteht ein Konflikt. Ordne die Schritte zur Lösung.", "items": [ "git merge feature", "git status", "git add konflikt.txt", "git commit" ], "hint": "Mergen, Konflikt prüfen, gelöste Datei vormerken, abschließen.", "successText": "Konflikt gelöst und gemergt!" }, { "type": "cloze", "prompt": "Befehl: Arbeit zwischenspeichern", "points": 100, "narrative": "Du willst deine Änderungen kurz beiseitelegen, ohne zu committen.", "codeTemplate": "git {{1}}", "gaps": [ { "position": 1, "placeholder": "Befehl", "hint": "Legt Änderungen auf einen Stapel.", "caseSensitive": true, "solutions": [ "stash" ] } ], "hint": "Englisch für Versteck.", "successText": "Änderungen sicher zwischengespeichert!" }, { "type": "choice", "prompt": "Mission: Remote-Stand holen", "points": 100, "question": "Welcher Befehl lädt Änderungen vom Remote UND führt sie zusammen?", "options": [ "git fetch", "git pull", "git push", "git clone" ], "correctIndex": 1, "hint": "fetch holt nur, dieser Befehl mergt zusätzlich.", "successText": "Richtig, git pull holt und mergt." }, { "type": "cloze", "prompt": "Befehl: Stash zurückholen", "points": 100, "narrative": "Deine zwischengespeicherten Änderungen sollen zurück in den Arbeitsbereich.", "codeTemplate": "git stash {{1}}", "gaps": [ { "position": 1, "placeholder": "Befehl", "hint": "Holt den letzten Stash und entfernt ihn vom Stapel.", "caseSensitive": true, "solutions": [ "pop" ] } ], "hint": "Drei Buchstaben.", "successText": "Deine Änderungen sind zurück!" }, { "type": "order", "prompt": "Mission: Gepushten Commit rückgängig", "points": 100, "instruction": "Ein fehlerhafter Commit ist schon auf dem Remote. Ordne die sichere Lösung.", "items": [ "git log --oneline", "git revert a1b2c3d", "git push" ], "hint": "Hash finden, umkehren, hochladen.", "successText": "Der fehlerhafte Commit ist neutralisiert!" } ] }, { "slug": "html-architect", "title": "HTML Architect", "language": "HTML", "path": "syntax", "description": "Baue Seiten mit semantischem HTML: Struktur-Elemente, Attribute und sauberes Markup.", "tasks": [ { "type": "cloze", "prompt": "Kopfbereich auszeichnen", "points": 100, "narrative": "Oben auf der Seite stehen Logo und Titel. Welches Element umschliesst diesen Kopfbereich?", "codeTemplate": "<{{1}}>\n

Mindflux

\n", "gaps": [ { "position": 1, "placeholder": "Tag", "hint": "Semantischer Kopfbereich.", "caseSensitive": false, "solutions": [ "header" ] }, { "position": 2, "placeholder": "Tag", "hint": "Gleiches Tag wie das oeffnende.", "caseSensitive": false, "solutions": [ "header" ] } ], "successText": "Stark!
markiert den einleitenden Bereich." }, { "type": "choice", "prompt": "Hauptinhalt", "points": 100, "question": "Welches Element kennzeichnet den zentralen Hauptinhalt eines Dokuments?", "options": [ "
", "", "", "
" ], "correctIndex": 0, "hint": "Es darf pro Seite nur einmal sichtbar vorkommen.", "successText": "Genau,
umschliesst den Hauptinhalt." }, { "type": "cloze", "prompt": "Navigation", "points": 100, "narrative": "Die Linkliste fuehrt durch die Seite.", "codeTemplate": "<{{1}} aria-label=\"Hauptmenue\">\n Start\n", "gaps": [ { "position": 1, "placeholder": "Tag", "hint": "Steht fuer Navigation.", "caseSensitive": false, "solutions": [ "nav" ] }, { "position": 2, "placeholder": "Tag", "hint": "Gleiches Tag schliessen.", "caseSensitive": false, "solutions": [ "nav" ] } ], "successText": "
", "hint": "Welches Tag wurde geoeffnet?", "successText": "Korrekt, oeffnendes und schliessendes Tag muessen uebereinstimmen." }, { "type": "cloze", "prompt": "Thematischer Abschnitt", "points": 100, "narrative": "Ein klar abgegrenztes Kapitel mit eigener Ueberschrift.", "codeTemplate": "<{{1}}>\n

Kapitel 1

\n", "gaps": [ { "position": 1, "placeholder": "Tag", "hint": "Thematischer Block mit Ueberschrift.", "caseSensitive": false, "solutions": [ "section" ] }, { "position": 2, "placeholder": "Tag", "hint": "Gleiches Tag schliessen.", "caseSensitive": false, "solutions": [ "section" ] } ], "successText": "
gruppiert thematisch zusammengehoerigen Inhalt." }, { "type": "choice", "prompt": "Randinhalt", "points": 100, "question": "Welches Element eignet sich fuer ergaenzende Randinhalte wie eine Sidebar?", "options": [ "