diff --git a/MainPage/stas/eigenerCode.js b/MainPage/stas/eigenerCode.js index 5c1618f..2bd6707 100644 --- a/MainPage/stas/eigenerCode.js +++ b/MainPage/stas/eigenerCode.js @@ -146,355 +146,6 @@ modusBtns.forEach(btn => { }); }); -let trainingsZustand = { - modus: "leicht", - // für alle Level - quelleKarten: [], - basisKarten: [], - aktiveKarten: [], - gelernt: [], - nichtGelernt: [], - // für Mittel - ziehKarten: [], - rundeNummer: 0, - richtung: "EN_DE", -}; - -// Startet das Training im Modus "Leicht". -function startLeichtTraining() { - trainingsZustand.modus = "leicht"; - trainingsZustand.quelleKarten = [...parsedArray]; - trainingsZustand.aktiveKarten = []; - trainingsZustand.gelernt = []; - trainingsZustand.nichtGelernt = []; - - for (let i = 0; i < 3; i++) { - if (trainingsZustand.quelleKarten.length > 0) { - const karte = trainingsZustand.quelleKarten.shift(); - karte.versuche = 0; - trainingsZustand.aktiveKarten.push(karte); - } - } - zeigeNaechsteKarte(); -} - -// Verarbeitet die Antwort des Nutzers im leichten Modus. -function antworteAufKarte(weißIch) { - const karte = trainingsZustand.aktuelleKarte; - - if (weißIch) { - trainingsZustand.gelernt.push(karte); - trainingsZustand.aktiveKarten = trainingsZustand.aktiveKarten.filter(k => k !== karte); - } else { - karte.versuche++; - if (karte.versuche >= 5) { - trainingsZustand.nichtGelernt.push(karte); - trainingsZustand.aktiveKarten = trainingsZustand.aktiveKarten.filter(k => k !== karte); - } else { - trainingsZustand.aktiveKarten.push(trainingsZustand.aktiveKarten.splice(trainingsZustand.aktiveKarten.indexOf(karte), 1)[0]); - } - } - - if (trainingsZustand.aktiveKarten.length < 3 && trainingsZustand.quelleKarten.length > 0) { - let neueKarte = trainingsZustand.quelleKarten.shift(); - neueKarte.versuche = 0; - trainingsZustand.aktiveKarten.push(neueKarte); - } - - zeigeNaechsteKarte(); -} - -// Wählt zufällig eine aktive Karte aus -function zeigeNaechsteKarte() { - if (trainingsZustand.aktiveKarten.length === 0) { - - if (trainingsZustand.quelleKarten.length === 0) { - alert(`Training beendet! - Gelernt: ${trainingsZustand.gelernt.length} - Nicht gelernt: ${trainingsZustand.nichtGelernt.length}`); - return; - } - - const neueKarte = trainingsZustand.quelleKarten.shift(); - neueKarte.versuche = 0; - trainingsZustand.aktiveKarten.push(neueKarte); - } - const index = Math.floor( - Math.random() * trainingsZustand.aktiveKarten.length - ); - - trainingsZustand.aktuelleKarte = - trainingsZustand.aktiveKarten[index]; - - renderLeichtKarte(trainingsZustand.aktuelleKarte); -} - -// Rendert eine einzelne Karte im leichten Modus. -function renderLeichtKarte(karte) { - const container = document.getElementById("trainingFlip"); - container.innerHTML = ""; - - const cardEl = document.createElement("div"); - cardEl.className = "training-card"; - cardEl.innerHTML = ` -
-
-

${karte.englisch}

-
${karte.ipa}
-
${karte.beispielEN}
-
-
-

${karte.deutsch}

-
${karte.beispielDE}
-
-
- `; - - cardEl.onclick = () => cardEl.classList.toggle("flip"); - - const actions = document.createElement("div"); - actions.className = "training-actions"; - actions.innerHTML = ` - - - `; - - actions.querySelector("#knowBtn").onclick = () => antworteAufKarte(true); - actions.querySelector("#dontKnowBtn").onclick = () => antworteAufKarte(false); - - container.appendChild(cardEl); - container.appendChild(actions); -} - -// Startet das Training im Modus "Mittel". -function startMittelTraining() { - trainingsZustand.modus = "mittel"; - trainingsZustand.basisKarten = parsedArray.map(karte => ({ - ...karte, - erfolge: 0, - fehler: 0 - })); - - trainingsZustand.gelernt = []; - trainingsZustand.nichtGelernt = []; - trainingsZustand.rundeNummer = 0; - - ladeMittelRunde(); -} - -// Lädt eine neue Runde im mittleren Trainingsmodus. -function ladeMittelRunde() { - trainingsZustand.aktiveKarten = []; - trainingsZustand.ziehKarten = []; - - trainingsZustand.richtung = trainingsZustand.rundeNummer % 2 === 0 ? "EN_DE" : "DE_EN"; - trainingsZustand.rundeNummer++; - - mischeArray(trainingsZustand.basisKarten); - trainingsZustand.aktiveKarten = trainingsZustand.basisKarten.slice(0, 4); - - if(trainingsZustand.aktiveKarten.length === 0) { - alert(`Training beendet! - Gelernt: ${trainingsZustand.gelernt.length} - Nicht gelernt: ${trainingsZustand.nichtGelernt.length}`); - return; - } - - trainingsZustand.ziehKarten = mischeArray([...trainingsZustand.aktiveKarten]); - - renderMittelMatching(); -} - -// Rendert das Matching-Layout für den mittleren Modus. -function renderMittelMatching() { - const container = document.getElementById("trainingMatching"); - container.innerHTML = ""; - - const links = document.createElement("div"); - links.className = "spalte-links"; - - const rechts = document.createElement("div"); - rechts.className = "spalte-rechts"; - - // Linke Zone - trainingsZustand.aktiveKarten.forEach(karte => { - const dropZone = document.createElement("div"); - dropZone.className = "training-card drop-zone"; - dropZone.dataset.id = karte.id; - - if(trainingsZustand.richtung === "EN_DE") { - dropZone.innerHTML = ` -
-

${karte.englisch}

-
${karte.ipa}
-
${karte.beispielEN}
-
- `;} else { - dropZone.innerHTML = ` -
-

${karte.deutsch}

-
${karte.beispielDE}
-
- `;} - - links.appendChild(dropZone); - }); - - // draggable + droppable (swap) - trainingsZustand.ziehKarten.forEach((karte, index) => { - const ziehKarte = document.createElement("div"); - ziehKarte.className = "training-card zieh-karte"; - ziehKarte.draggable = true; - ziehKarte.dataset.index = index; - - if(trainingsZustand.richtung === "EN_DE") { - ziehKarte.innerHTML = ` -
-

${karte.deutsch}

-
${karte.beispielDE}
-
- `;} else { - ziehKarte.innerHTML = ` -
-

${karte.englisch}

-
${karte.ipa}
-
${karte.beispielEN}
-
- `;} - - // dragstart - ziehKarte.addEventListener("dragstart", e => { - console.log("dragstart работает"); - e.dataTransfer.setData("draggedIndex", index); - }); - - // dragover - ziehKarte.addEventListener("dragover", e => { - e.preventDefault(); - }); - - // drop - ziehKarte.addEventListener("drop", e => { - console.log("drop работает"); - - e.preventDefault(); - - const draggedIndex = Number(e.dataTransfer.getData("draggedIndex")); - - swapZiehKarten(draggedIndex, index); - }); - - rechts.appendChild(ziehKarte); - }); - - container.appendChild(links); - container.appendChild(rechts); -} - -// Überprüft, ob die Zuordnungen korrekt sind. -function pruefeRunde() { - - const ziehElemente = document.querySelectorAll(".zieh-karte"); - - trainingsZustand.aktiveKarten.forEach((karte, index) => { - - const gezogene = trainingsZustand.ziehKarten[index]; - const element = ziehElemente[index]; - - element.style.backgroundColor = ""; - - if (karte.id === gezogene.id) { - element.style.backgroundColor = "#a8f0a8"; - karte.erfolge++; - } else { - element.style.backgroundColor = "#f5a8a8"; - karte.fehler++; - } - - }); - - setTimeout(() => { - beendeMittelRunde(); - }, 1000); -} - -// Bewertet nach jeder Runde den Lernstatus jeder Karte. -function beendeMittelRunde() { - - const verbleibende = []; - - trainingsZustand.basisKarten.forEach(karte => { - - if (karte.erfolge >= 2) { - trainingsZustand.gelernt.push(karte); - } - else if (karte.fehler >= 4) { - trainingsZustand.nichtGelernt.push(karte); - } - else { - verbleibende.push(karte); - } - }); - - trainingsZustand.basisKarten = verbleibende; - - if (trainingsZustand.basisKarten.length === 0) { - alert(`Training beendet! - Gelernt: ${trainingsZustand.gelernt.length} - Nicht gelernt: ${trainingsZustand.nichtGelernt.length}`); - return; - } - - ladeMittelRunde(); -} - -// Tauscht zwei Ziehkarten anhand ihrer Indizes -function swapZiehKarten(index1, index2) { - [trainingsZustand.ziehKarten[index1], trainingsZustand.ziehKarten[index2]] = - [trainingsZustand.ziehKarten[index2], trainingsZustand.ziehKarten[index1]]; - - const container = document.querySelector(".spalte-rechts"); - container.innerHTML = ""; - - trainingsZustand.ziehKarten.forEach((karte, idx) => { - const ziehKarte = document.createElement("div"); - ziehKarte.className = "training-card zieh-karte"; - ziehKarte.draggable = true; - ziehKarte.dataset.index = idx; - - if (trainingsZustand.richtung === "EN_DE") { - ziehKarte.innerHTML = ` -
-

${karte.deutsch}

-
${karte.beispielDE}
-
- `; - } else { - ziehKarte.innerHTML = ` -
-

${karte.englisch}

-
${karte.ipa}
-
${karte.beispielEN}
-
- `; - } - - ziehKarte.addEventListener("dragstart", e => { - e.dataTransfer.setData("draggedIndex", idx); - }); - - ziehKarte.addEventListener("dragover", e => e.preventDefault()); - - ziehKarte.addEventListener("drop", e => { - e.preventDefault(); - const draggedIndex = Number(e.dataTransfer.getData("draggedIndex")); - swapZiehKarten(draggedIndex, idx); - }); - - container.appendChild(ziehKarte); - }); -} - // Blendet alle Trainingslevel-Ansichten aus function showMode(id) { @@ -521,7 +172,7 @@ document.querySelectorAll(".level-btn").forEach(btn => { if (type === "flip") { showLevel("trainingFlip"); - startLeichtTraining(); + startFlipTraining(); document.getElementById("checkBtn").style.display = "none"; } @@ -551,65 +202,249 @@ document.querySelectorAll(".level-btn").forEach(btn => { }); }); -function startMultipleTraining() { - trainingsZustand.modus = "multiple"; - trainingsZustand.quelleKarten = mischeArray([...parsedArray]); - trainingsZustand.aktuelleKarte = null; - trainingsZustand.gelernt = []; - trainingsZustand.nichtGelernt = []; +class TrainingsEngine { - zeigeNaechsteMultipleKarte(); -} + constructor(kartenListe) { + this.kartenQueue = []; + this.letzteKarteId = null; + this.gelernt = []; + this.nichtGelernt = []; -function generiereMultipleOptionen(karte) { - const optionen = [karte.deutsch]; + // Initialisierung aller Richtungen + kartenListe.forEach(karte => { + ["EN_DE", "DE_EN"].forEach(richtung => { + this.kartenQueue.push({ + karte: karte, + richtung: richtung, + korrektInFolge: 0, + versuche: 0, + maxVersuche: 3, + status: "learning" + }); + }); + }); - const falscheOptionen = parsedArray - .filter(k => k.id !== karte.id) - .map(k => k.deutsch); - - mischeArray(falscheOptionen); - - optionen.push(...falscheOptionen.slice(0, 4)); - - return mischeArray(optionen); -} - -function generiereHint(deutsch) { - const chars = deutsch.split(''); - const anzahlZuVerstecken = Math.floor(chars.length / 2); - - const indices = Array.from(chars.keys()); - mischeArray(indices); - - for (let i = 0; i < anzahlZuVerstecken; i++) { - chars[indices[i]] = '*'; + this.#mischeQueue(); } - return chars.join(''); + //ÖFFENTLICHE API + + naechstesElement() { + if (this.kartenQueue.length === 0) return null; + + // Verhindert direkte Wiederholung derselben Karte + if ( + this.kartenQueue.length > 1 && + this.kartenQueue[0].karte.id === this.letzteKarteId + ) { + const alternativeIndex = this.kartenQueue.findIndex( + el => el.karte.id !== this.letzteKarteId + ); + + if (alternativeIndex !== -1) { + const [element] = this.kartenQueue.splice(alternativeIndex, 1); + this.kartenQueue.unshift(element); + } + } + + const aktuellesElement = this.kartenQueue.shift(); + this.letzteKarteId = aktuellesElement.karte.id; + + return aktuellesElement; + } + + antwortVerarbeiten(element, istKorrekt) { + if (!element || element.status !== "learning") return; + + element.versuche++; + + if (istKorrekt) { + element.korrektInFolge++; + + if (element.korrektInFolge >= 3) { + element.status = "gelernt"; + this.gelernt.push(element); + this.kartenQueue = this.kartenQueue.filter(e => e !== element); + return; + } + + this.#wiederEinreihen(element, 8, 10); + + } else { + element.korrektInFolge = 0; + element.maxVersuche = 5; + + if (element.versuche >= element.maxVersuche) { + element.status = "nichtGelernt"; + this.nichtGelernt.push(element); + this.kartenQueue = this.kartenQueue.filter(e => e !== element); + return; + } + + this.#wiederEinreihen(element, 2, 3); + } + } + + istBeendet() { + return this.kartenQueue.length === 0; + } + + statistik() { + const alle = [...this.kartenQueue]; + + return { + verbleibend: this.kartenQueue.length, + gelernt: alle.filter(e => e.status === "gelernt").length, + nichtGelernt: alle.filter(e => e.status === "nichtGelernt").length + }; + } + + exportiereZustand() { + return JSON.stringify({ + kartenQueue: this.kartenQueue, + letzteKarteId: this.letzteKarteId + }); + } + + ladeZustand(json) { + const daten = JSON.parse(json); + this.kartenQueue = daten.kartenQueue; + this.letzteKarteId = daten.letzteKarteId; + } + + //PRIVATE METHODEN + #wiederEinreihen(element, minAbstand, maxAbstand) { + const zufall = + Math.floor(Math.random() * (maxAbstand - minAbstand + 1)) + minAbstand; + + const position = Math.min(zufall, this.kartenQueue.length); + this.kartenQueue.splice(position, 0, element); + } + + #mischeQueue() { + for (let i = this.kartenQueue.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [this.kartenQueue[i], this.kartenQueue[j]] = + [this.kartenQueue[j], this.kartenQueue[i]]; + } + } } +let flipEngine; -function zeigeNaechsteMultipleKarte() { - if (trainingsZustand.quelleKarten.length === 0) { - alert(`Training beendet! -Gelernt: ${trainingsZustand.gelernt.length} -Nicht gelernt: ${trainingsZustand.nichtGelernt.length}`); +function startFlipTraining() { + flipEngine = new TrainingsEngine(parsedArray); + zeigeNaechsteFlipKarte(); +} + +function zeigeNaechsteFlipKarte() { + const element = flipEngine.naechstesElement(); + + const container = document.getElementById("trainingFlip"); + container.innerHTML = ""; + + if (!element) { + container.classList.remove("hidden"); + container.innerHTML = `
🎉 Training beendet!
Gelernt: ${flipEngine.gelernt.length}
Nicht gelernt: ${flipEngine.nichtGelernt.length}
`; return; } - const karte = trainingsZustand.quelleKarten.shift(); - trainingsZustand.aktuelleKarte = karte; + const cardEl = document.createElement("div"); + cardEl.className = "training-card"; + cardEl.innerHTML = ` +
+ +
+
+

${element.richtung === "EN_DE" ? element.karte.englisch : element.karte.deutsch}

+ ${element.richtung === "EN_DE" && element.karte.ipa + ? `
${element.karte.ipa}
` + : `` + } +
+
+ ${element.richtung === "EN_DE" + ? element.karte.beispielEN || "" + : element.karte.beispielDE || "" + } +
+
+ +
+
+

${element.richtung === "EN_DE" ? element.karte.deutsch : element.karte.englisch}

+ ${element.richtung !== "EN_DE" && element.karte.ipa + ? `
${element.karte.ipa}
` + : `` + } +
+
+ ${element.richtung === "EN_DE" + ? element.karte.beispielDE || "" + : element.karte.beispielEN || "" + } +
+
+ +
+`; + + cardEl.onclick = () => cardEl.classList.toggle("flip"); + + const actions = document.createElement("div"); + actions.className = "training-actions"; + const knowBtn = document.createElement("button"); + knowBtn.innerText = "Weiß ich"; + const dontKnowBtn = document.createElement("button"); + dontKnowBtn.innerText = "Weiß ich nicht"; + + knowBtn.onclick = () => { + flipEngine.antwortVerarbeiten(element, true); + zeigeNaechsteFlipKarte(); + }; + dontKnowBtn.onclick = () => { + flipEngine.antwortVerarbeiten(element, false); + zeigeNaechsteFlipKarte(); + }; + + actions.appendChild(knowBtn); + actions.appendChild(dontKnowBtn); + + container.appendChild(cardEl); + container.appendChild(actions); +} + +let multipleEngine; + +function startMultipleTraining() { + multipleEngine = new TrainingsEngine(parsedArray); + zeigeNaechsteMultipleKarte(); +} + +let aktuelleKarte = null; +let ersteAntwort = true; + +function zeigeNaechsteMultipleKarte() { const container = document.getElementById("trainingMultiple"); container.innerHTML = ""; + const element = multipleEngine.naechstesElement(); + + if (!element) { + container.innerHTML = `
🎉 Training beendet!
Gelernt: ${multipleEngine.gelernt.length}
Nicht gelernt: ${multipleEngine.nichtGelernt.length}
`; + return; + } + + aktuelleKarte = element; + ersteAntwort = true; + const frage = document.createElement("div"); frage.className = "multiple-frage"; - frage.innerHTML = `

${karte.englisch}

`; + frage.innerHTML = `

${element.richtung === "EN_DE" ? element.karte.englisch : element.karte.deutsch}

`; container.appendChild(frage); - const optionen = generiereMultipleOptionen(karte); + const optionen = generiereMultipleOptionen(element); const optionContainer = document.createElement("div"); optionContainer.className = "multiple-optionen"; @@ -619,12 +454,22 @@ Nicht gelernt: ${trainingsZustand.nichtGelernt.length}`); btn.innerText = text; btn.onclick = () => { - if (text === karte.deutsch) { - trainingsZustand.gelernt.push(karte); - zeigeNaechsteMultipleKarte(); - } else { + const korrektText = element.richtung === "EN_DE" ? element.karte.deutsch : element.karte.englisch; + const istKorrekt = (text === korrektText); + + if (istKorrekt) { + btn.style.backgroundColor = "#a8f0a8"; + if (ersteAntwort) multipleEngine.antwortVerarbeiten(element, true); + setTimeout(() => zeigeNaechsteMultipleKarte(), 500); + + } else if (ersteAntwort) { + btn.style.backgroundColor = "#f5a8a8"; + btn.style.textDecoration = "line-through"; + multipleEngine.antwortVerarbeiten(element, false); + ersteAntwort = false; + } else { + btn.style.backgroundColor = "#f5a8a8"; btn.style.textDecoration = "line-through"; - btn.disabled = true; } }; @@ -633,132 +478,407 @@ Nicht gelernt: ${trainingsZustand.nichtGelernt.length}`); container.appendChild(optionContainer); } +function generiereMultipleOptionen(element) { + const korrekt = element.richtung === "EN_DE" ? element.karte.deutsch : element.karte.englisch; -trainingsZustand.hintCards = []; + const falscheOptionen = parsedArray + .filter(k => k.id !== element.karte.id) + .map(k => element.richtung === "EN_DE" ? k.deutsch : k.englisch); + + mischeArray(falscheOptionen); + + const optionen = [korrekt, ...falscheOptionen.slice(0, 4)]; + return mischeArray(optionen); +} + +function mischeArray(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +} + +let hintEngine; function startHintTraining() { - trainingsZustand.modus = "hint"; - trainingsZustand.hintCards = mischeArray([...parsedArray]); + hintEngine = new TrainingsEngine(parsedArray); zeigeNaechsteHintKarte(); } function zeigeNaechsteHintKarte() { - if (trainingsZustand.hintCards.length === 0) { - alert(`Training beendet! - Gelernt: ${trainingsZustand.gelernt.length} - Nicht gelernt: ${trainingsZustand.nichtGelernt.length}`); - return; - } - - const karte = trainingsZustand.hintCards.shift(); - trainingsZustand.aktuelleKarte = karte; - const container = document.getElementById("trainingHint"); container.innerHTML = ""; + const element = hintEngine.naechstesElement(); + + if (!element) { + container.innerHTML = ` +
+ 🎉 Training beendet!
+ Gelernt: ${hintEngine.gelernt.length}
+ Nicht gelernt: ${hintEngine.nichtGelernt.length} +
+ `; + return; + } + + const korrekt = element.richtung === "EN_DE" ? element.karte.deutsch : element.karte.englisch; + const frage = document.createElement("div"); frage.className = "hint-frage"; - frage.innerHTML = `

${karte.englisch}

`; + frage.innerText = element.richtung === "EN_DE" ? element.karte.englisch : element.karte.deutsch; container.appendChild(frage); const clue = document.createElement("div"); clue.className = "hint-clue"; - clue.innerText = generiereHint(karte.deutsch); + clue.innerText = erstelleClue(korrekt); container.appendChild(clue); const input = document.createElement("input"); input.className = "hint-input"; - input.placeholder = "Schreibe die Übersetzung hier..."; + input.placeholder = "Schreibe die Übersetzung..."; + input.autofocus = true; + input.style.fontSize = "18px"; + input.style.padding = "5px 10px"; + input.style.border = "2px solid #005b5b"; + input.style.borderRadius = "6px"; + input.style.width = "300px"; + input.style.caretColor = "#005b5b"; container.appendChild(input); + const feedback = document.createElement("div"); + feedback.className = "hint-feedback"; + feedback.style.marginTop = "10px"; + container.appendChild(feedback); + const button = document.createElement("button"); button.className = "hint-button"; button.innerText = "Überprüfen"; container.appendChild(button); - const feedback = document.createElement("div"); - feedback.className = "hint-feedback"; - container.appendChild(feedback); + let phase = "check"; - button.onclick = () => { - const answer = input.value.trim(); - if (answer.toLowerCase() === karte.deutsch.toLowerCase()) { - feedback.innerText = "✅ Richtig!"; - trainingsZustand.gelernt.push(karte); - setTimeout(() => zeigeNaechsteHintKarte(), 800); - } else { - feedback.innerText = `❌ Falsch! Richtige Antwort: ${karte.deutsch}`; - trainingsZustand.nichtGelernt.push(karte); - setTimeout(() => zeigeNaechsteHintKarte(), 1200); + const pruefeAntwort = () => { + if (phase === "check") { + const userAnswer = input.value.trim(); + if (!userAnswer) return; + + const istKorrekt = userAnswer.toLowerCase() === korrekt.toLowerCase(); + hintEngine.antwortVerarbeiten(element, istKorrekt); + + if (istKorrekt) { + input.style.backgroundColor = "#a8f0a8"; + setTimeout(() => zeigeNaechsteHintKarte(), 500); + } else { + input.style.backgroundColor = "#f5a8a8"; + feedback.innerText = `Korrekte Antwort: ${korrekt}`; + button.innerText = "Weiter"; + phase = "next"; + } + } else if (phase === "next") { + zeigeNaechsteHintKarte(); } }; + + button.onclick = pruefeAntwort; + + input.addEventListener("keydown", (e) => { + if (e.key === "Enter") { + e.preventDefault(); + pruefeAntwort(); + } + }); + + input.focus(); } -function startWriteTraining() { - trainingsZustand.modus = "write"; - trainingsZustand.quelleKarten = mischeArray([...parsedArray]); - trainingsZustand.aktuelleKarte = null; - trainingsZustand.gelernt = []; - trainingsZustand.nichtGelernt = []; +function erstelleClue(text) { + if (text.length === 1) return "*"; + const chars = text.split(""); + let clue = chars.map(char => (char === " " ? " " : "*")); + + const visibleIndices = []; + while (visibleIndices.length < Math.max(1, Math.floor(chars.length / 2))) { + const idx = Math.floor(Math.random() * chars.length); + if (chars[idx] !== " " && !visibleIndices.includes(idx)) { + visibleIndices.push(idx); + } + } + + visibleIndices.forEach(idx => { + clue[idx] = chars[idx]; + }); + + return clue.join(""); +} + +let writeEngine; + +function startWriteTraining() { + writeEngine = new TrainingsEngine(parsedArray); zeigeNaechsteWriteKarte(); } function zeigeNaechsteWriteKarte() { - if (trainingsZustand.quelleKarten.length === 0) { - const container = document.getElementById("trainingWrite"); + const container = document.getElementById("trainingWrite"); + container.innerHTML = ""; + + const element = writeEngine.naechstesElement(); + + if (!element) { container.innerHTML = ` -
- Training beendet!
- Gelernt: ${trainingsZustand.gelernt.length}
- Nicht gelernt: ${trainingsZustand.nichtGelernt.length} +
+ 🎉 Training beendet!
+ Gelernt: ${writeEngine.gelernt.length}
+ Nicht gelernt: ${writeEngine.nichtGelernt.length}
`; return; } - const karte = trainingsZustand.quelleKarten.shift(); - trainingsZustand.aktuelleKarte = karte; - - const container = document.getElementById("trainingWrite"); - container.innerHTML = ""; + const korrekt = element.richtung === "EN_DE" ? element.karte.deutsch : element.karte.englisch; const frage = document.createElement("div"); - frage.className = "schwer-frage"; - frage.innerHTML = `

${karte.englisch}

`; + frage.className = "hint-frage"; + frage.innerHTML = element.richtung === "EN_DE" ? element.karte.englisch : element.karte.deutsch; container.appendChild(frage); const input = document.createElement("input"); - input.type = "text"; - input.placeholder = "Schreibe die Übersetzung hier..."; + input.className = "hint-input"; + input.placeholder = "Schreibe die Übersetzung..."; + input.autofocus = true; input.style.fontSize = "18px"; + input.style.padding = "5px 10px"; + input.style.border = "2px solid #005b5b"; + input.style.borderRadius = "6px"; input.style.width = "300px"; - input.style.padding = "8px"; + input.style.caretColor = "#005b5b"; container.appendChild(input); - const submitBtn = document.createElement("button"); - submitBtn.innerText = "Überprüfen"; - submitBtn.style.marginTop = "10px"; - submitBtn.onclick = () => { - const answer = input.value.trim(); - const resultDiv = document.createElement("div"); - resultDiv.style.marginTop = "12px"; - resultDiv.style.fontWeight = "600"; + const feedback = document.createElement("div"); + feedback.className = "hint-feedback"; + feedback.style.marginTop = "10px"; + container.appendChild(feedback); - if (answer.toLowerCase() === karte.deutsch.toLowerCase()) { - trainingsZustand.gelernt.push(karte); - resultDiv.style.color = "#28a745"; - resultDiv.innerText = "Richtig!"; - } else { - trainingsZustand.nichtGelernt.push(karte); - resultDiv.style.color = "#dc3545"; - resultDiv.innerText = `Falsch! Richtige Antwort: ${karte.deutsch}`; + const button = document.createElement("button"); + button.className = "hint-button"; + button.innerText = "Überprüfen"; + container.appendChild(button); + + let phase = "check"; + + const pruefeAntwort = () => { + if (phase === "check") { + const userAnswer = input.value.trim(); + if (!userAnswer) return; + + const istKorrekt = userAnswer.toLowerCase() === korrekt.toLowerCase(); + writeEngine.antwortVerarbeiten(element, istKorrekt); + + if (istKorrekt) { + input.style.backgroundColor = "#a8f0a8"; + setTimeout(() => zeigeNaechsteWriteKarte(), 500); + } else { + input.style.backgroundColor = "#f5a8a8"; + feedback.innerText = `Korrekte Antwort: ${korrekt}`; + button.innerText = "Weiter"; + phase = "next"; + } + } else if (phase === "next") { + zeigeNaechsteWriteKarte(); } - - container.appendChild(resultDiv); - - setTimeout(() => zeigeNaechsteWriteKarte(), 2000); }; - container.appendChild(submitBtn); + button.onclick = pruefeAntwort; + input.addEventListener("keydown", (e) => { + if (e.key === "Enter") { + e.preventDefault(); + pruefeAntwort(); + } + }); + + input.focus(); } + +let matchingEngine; +let matchingRunde = 0; +let linkeKarten = []; +let rechteKarten = []; +let aktuelleRichtung = "EN_DE"; + +function startMittelTraining() { + matchingEngine = new TrainingsEngine(parsedArray); + matchingRunde = 0; + ladeMatchingRunde(); +} + +function ladeMatchingRunde() { + const container = document.getElementById("trainingMatching"); + container.innerHTML = ""; + + aktuelleRichtung = matchingRunde % 2 === 0 ? "EN_DE" : "DE_EN"; + matchingRunde++; + + const learningCards = matchingEngine.kartenQueue.filter(e => e.status === "learning"); + + linkeKarten = learningCards + .reduce((acc, el) => { + if (!acc.find(a => a.karte.id === el.karte.id)) acc.push(el); + return acc; + }, []) + .slice(0, 4); + + rechteKarten = mischeArray([...linkeKarten]); + + const linksDiv = document.createElement("div"); + linksDiv.className = "spalte-links"; + + const rechtsDiv = document.createElement("div"); + rechtsDiv.className = "spalte-rechts"; + + linkeKarten.forEach(k => { + const dropZone = document.createElement("div"); + dropZone.className = "training-card drop-zone"; + dropZone.dataset.id = k.karte.id; + + dropZone.innerHTML = ` +
+

${aktuelleRichtung === "EN_DE" ? k.karte.englisch : k.karte.deutsch}

+ ${aktuelleRichtung === "EN_DE" && k.karte.ipa ? `
${k.karte.ipa}
` : ""} +
+
+ ${aktuelleRichtung === "EN_DE" ? k.karte.beispielEN || "" : k.karte.beispielDE || ""} +
+ `; + linksDiv.appendChild(dropZone); + }); + + rechteKarten.forEach((k, index) => { + const ziehKarte = document.createElement("div"); + ziehKarte.className = "training-card zieh-karte"; + ziehKarte.draggable = true; + ziehKarte.dataset.index = index; + + const zeigeEnglisch = aktuelleRichtung === "DE_EN"; + ziehKarte.innerHTML = ` +
+

${zeigeEnglisch ? k.karte.englisch : k.karte.deutsch}

+ ${zeigeEnglisch && k.karte.ipa ? `
${k.karte.ipa}
` : ""} +
+
+ ${zeigeEnglisch ? k.karte.beispielEN || "" : k.karte.beispielDE || ""} +
+ `; + + ziehKarte.addEventListener("dragstart", e => e.dataTransfer.setData("draggedIndex", index)); + ziehKarte.addEventListener("dragover", e => e.preventDefault()); + ziehKarte.addEventListener("drop", e => { + e.preventDefault(); + const draggedIndex = Number(e.dataTransfer.getData("draggedIndex")); + swapZiehKarten(draggedIndex, index, linksDiv, rechtsDiv); + }); + + rechtsDiv.appendChild(ziehKarte); + }); + + container.appendChild(linksDiv); + container.appendChild(rechtsDiv); +} + +function renderMatchingRechts(linksDiv, rechtsDiv) { + rechtsDiv.innerHTML = ""; + + rechteKarten.forEach((k, index) => { + const ziehKarte = document.createElement("div"); + ziehKarte.className = "training-card zieh-karte"; + ziehKarte.draggable = true; + ziehKarte.dataset.index = index; + + const zeigeEnglisch = (aktuelleRichtung === "DE_EN"); + ziehKarte.innerHTML = ` +
+

${zeigeEnglisch ? k.karte.englisch : k.karte.deutsch}

+ ${zeigeEnglisch && k.karte.ipa + ? `
${k.karte.ipa}
` + : "" + } +
+
+ ${zeigeEnglisch + ? k.karte.beispielEN || "" + : k.karte.beispielDE || "" + } +
+ `; + + ziehKarte.addEventListener("dragstart", e => e.dataTransfer.setData("draggedIndex", index)); + ziehKarte.addEventListener("dragover", e => e.preventDefault()); + ziehKarte.addEventListener("drop", e => { + e.preventDefault(); + const draggedIndex = Number(e.dataTransfer.getData("draggedIndex")); + swapZiehKarten(draggedIndex, index, linksDiv, rechtsDiv); + }); + + rechtsDiv.appendChild(ziehKarte); + }); + + const container = document.getElementById("trainingMatching"); + container.appendChild(linksDiv); + container.appendChild(rechtsDiv); +} + +function swapZiehKarten(fromIndex, toIndex, linksDiv, rechtsDiv) { + const temp = rechteKarten[fromIndex]; + rechteKarten[fromIndex] = rechteKarten[toIndex]; + rechteKarten[toIndex] = temp; + renderMatchingRechts(linksDiv, rechtsDiv); +} + +function pruefeRunde() { + const ziehElemente = document.querySelectorAll(".zieh-karte"); + + linkeKarten.forEach((k, index) => { + const gezogene = rechteKarten[index]; + const elementDiv = ziehElemente[index]; + + if (k.karte.id === gezogene.karte.id) { + elementDiv.style.backgroundColor = "#a8f0a8"; + matchingEngine.antwortVerarbeiten(gezogene, true); + } else { + elementDiv.style.backgroundColor = "#f5a8a8"; + matchingEngine.antwortVerarbeiten(gezogene, false); + } + }); + + const learningLeft = matchingEngine.kartenQueue.length; + const gelerntCount = matchingEngine.gelernt.length; + const nichtGelerntCount = matchingEngine.nichtGelernt.length; + + if (learningLeft === 0) { + const container = document.getElementById("trainingMatching"); + container.innerHTML = ` +
+ 🎉 Training beendet!
+ Gelernt: ${gelerntCount}
+ Nicht gelernt: ${nichtGelerntCount} +
+ `; + const checkBtn = document.getElementById("checkBtn"); + if (checkBtn) checkBtn.style.display = "none"; + return; + } + + setTimeout(() => { + ladeMatchingRunde(); + }, 1000); +} + +function mischeArray(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +} \ No newline at end of file diff --git a/MainPage/stas/style.css b/MainPage/stas/style.css index 1c2c5ab..d8824e6 100644 --- a/MainPage/stas/style.css +++ b/MainPage/stas/style.css @@ -281,13 +281,6 @@ h1 { } } -.training-card { - width: 300px; - margin: 10px auto; - perspective: 1000px; - cursor: pointer; -} - #trainingFlip .training-card { height: 180px; } @@ -299,6 +292,42 @@ h1 { margin-top: 10px; } +.training-card { + width: 300px; + margin: 10px auto; + perspective: 1000px; + cursor: pointer; + box-sizing: border-box; +} + +#trainingMatching .drop-zone, +#trainingMatching .zieh-karte { + min-height: 120px; + max-height: 120px; + width: 300px; + background: #fff; + border: 2px solid #666; + border-radius: 8px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + font-size: 0.9rem; + padding: 5px; + box-sizing: border-box; + text-align: center; +} + + #trainingMatching .drop-zone h2, + #trainingMatching .zieh-karte h2, + #trainingMatching .drop-zone .ipa, + #trainingMatching .zieh-karte .ipa, + #trainingMatching .drop-zone .example, + #trainingMatching .zieh-karte .example { + margin: 2px 0; + overflow: hidden; + } + .training-card-inner { width: 100%; height: 100%; @@ -323,8 +352,42 @@ h1 { box-sizing: border-box; display: flex; flex-direction: column; - justify-content: center; - gap: 10px; + justify-content: flex-start; + align-items: stretch; +} + +.card-top { + display: inline-flex; + flex-direction: column; + align-items: center; + gap: 2px; +} + +.card-top h2 { + margin: 0; + line-height: 1.1; +} + +.card-top h3 { + margin: 0; + line-height: 1.1; +} + +.card-top .ipa { + margin: 0; + line-height: 1.1; +} + +.card-example { + margin-top: auto; + text-align: center; + font-size: 15px; + line-height: 1.4; +} + +.ipa { + font-size: 16px; + color: #555; } .training-back { @@ -344,28 +407,6 @@ h1 { cursor: pointer; } -.training-front h2 { - margin-bottom: 4px; - margin-top: -25px; -} - -.training-front .ipa { - font-size: 16px; - color: #555; - margin-bottom: 34px; - margin-top: -12px; -} - -.training-front .example { - font-size: 15px; - line-height: 1.4; -} - -.training-back h2 { - margin-bottom: 54px; - margin-top: -28px; -} - #pdfPages, #onlineTraining { display: none;