Issue-20 echnaged some things mentioned in the issues.

This commit is contained in:
2026-04-09 17:31:56 +02:00
parent a32f2d0c6e
commit bc81820d9d
7 changed files with 523 additions and 375 deletions
+98 -88
View File
@@ -42,7 +42,7 @@
<button class="settings-trigger" id="settingsTrigger" onclick="toggleSidebar()" type="button"
aria-controls="settingsSidebar" aria-expanded="false">
<span class="settings-trigger-arrow" id="settingsTriggerArrow">→</span>
<span class="settings-trigger-label" id="settingsTriggerLabel">Brett-Einstellungen</span>
<span class="settings-trigger-label" id="settingsTriggerLabel">Spiel-Einstellungen</span>
</button>
<div class="container">
@@ -65,14 +65,14 @@
</p>
<div class="mode-switch" data-i18n-aria-label="modeSwitchAria" aria-label="Spielmodus">
<button class="btn active" onclick="setMode('queens')" id="btnQueens" type="button">
<span aria-hidden="true">♛</span>
<span data-i18n="btnQueens">Damen</span>
</button>
<button class="btn secondary" onclick="setMode('rooks')" id="btnRooks" type="button">
<span aria-hidden="true">♜</span>
<span data-i18n="btnRooks">Türme</span>
</button>
<button class="btn active" onclick="setMode('queens')" id="btnQueens" type="button">
<span aria-hidden="true">♛</span>
<span data-i18n="btnQueens">Damen</span>
</button>
</div>
</section>
@@ -82,13 +82,14 @@
<p class="section-kicker" id="gameModeEyebrow">Damen-Modus</p>
<h2 id="gameTitle">Damen-Spielbrett</h2>
<p class="board-mode-text" id="boardModeText">
Platziere Damen so, dass keine zwei dieselbe Spalte oder Diagonale teilen.
Platziere Damen frei auf dem Brett. Konflikte entstehen in derselben Reihe, Spalte oder
Diagonale.
</p>
</div>
<button class="info-button" id="infoButton" onclick="toggleInfoModal(true)" type="button"
data-i18n="infoButton" data-i18n-aria-label="infoButton"
aria-label="Spielregeln und Hilfe anzeigen">Regeln & Hilfe</button>
aria-label="Spielregeln und Hilfe anzeigen">Spielanleitung</button>
</div>
<p class="board-size-info" id="boardSizeInfo"><span id="boardSizeInfoPrefix">Aktuelle Brettgrösse im
@@ -118,69 +119,31 @@
</p>
</div>
<div class="board" id="board"></div>
<div class="board-stage">
<div class="board-shell">
<div id="board"></div>
</div>
<div class="board-navigator" id="boardNavigator" hidden>
<button class="btn secondary board-nav-button" onclick="previousSolverStep()" id="btnPrevStep"
type="button" data-i18n="btnPrevStep">
Zurück
</button>
<p class="solver-step-info" id="solverStepInfo">Schritt 0 / 0</p>
<button class="btn secondary board-nav-button" onclick="nextSolverStep()" id="btnNextStep"
type="button" data-i18n="btnNextStep">
Vorwärts
</button>
</div>
<p class="solver-message solver-message-inline" id="solverMessage">Lade eine Animation und steuere sie
am Brett oder spiele sie automatisch ab.</p>
</div>
<div class="controls">
<button class="btn secondary" onclick="resetBoard()" id="btnReset" type="button"
data-i18n="btnReset">Brett
zurücksetzen</button>
<div class="controls-save-row">
<button class="btn" onclick="openSavePanel()" id="btnSave" type="button"
data-i18n="btnSave">Speichern</button>
<button class="btn secondary" onclick="openSavePointsPanel()" id="btnLoad" type="button"
data-i18n="btnLoad">Save-Points</button>
</div>
</div>
<div class="solver-panel">
<div class="solver-panel-header">
<div>
<p class="section-kicker" id="solverKicker" data-i18n="solverKicker">Solver</p>
<h3 id="solverTitle" data-i18n="solverTitle">Lösungswerkzeuge</h3>
<p class="solver-message" id="solverMessage">Bereite einen Ablauf vor und spiele ihn Schritt
für Schritt ab.</p>
</div>
<p class="solver-step-info" id="solverStepInfo">Schritt 0 / 0</p>
</div>
<div class="solver-groups">
<section class="solver-group">
<h4 id="animationSolverTitle" data-i18n="animationSolverTitle">Animations-Solver</h4>
<p class="solver-group-text" id="animationSolverText" data-i18n="animationSolverText">
Bereite den Lösungsweg vor, gehe ihn manüll Schritt für Schritt durch oder spiele die
Animation automatisch ab.
</p>
<div class="solver-controls">
<button class="btn" onclick="prepareSolutionTrace()" id="btnPrepareSolve" type="button"
data-i18n="btnPrepareSolve">Animation vorbereiten</button>
<button class="btn secondary" onclick="nextSolverStep()" id="btnNextStep" type="button"
data-i18n="btnNextStep">Nächster Schritt</button>
<button class="btn secondary" onclick="toggleSolverPlayback()" id="btnPlayPause"
type="button" data-i18n="btnPlayPause">Animation abspielen</button>
</div>
<div class="solver-speed">
<label class="solver-speed-label" id="solverSpeedLabel" for="solverSpeedInput"
data-i18n="solverSpeedLabel">Animationsgeschwindigkeit</label>
<input id="solverSpeedInput" type="range" min="80" max="900" step="20" value="320"
oninput="updateSolverSpeed(this.value)">
<span class="solver-speed-value" id="solverSpeedValue">320 ms</span>
</div>
</section>
<section class="solver-group instant-solver-group">
<h4 id="instantSolverTitle" data-i18n="instantSolverTitle">Sofort-Lösung</h4>
<p class="solver-group-text" id="instantSolverText" data-i18n="instantSolverText">
Lade direkt eine gültige Lösung, ohne Zwischenschritte oder Animation.
</p>
<div class="instant-solver-actions">
<button class="btn accent" onclick="instantSolve()" id="btnInstantSolve" type="button"
data-i18n="btnInstantSolve">Sofort lösen</button>
</div>
</section>
</div>
</div>
</div>
@@ -234,25 +197,68 @@
<aside class="sidebar settings-sidebar" id="settingsSidebar" aria-hidden="true">
<div class="sidebar-header">
<h3 id="settingsSidebarTitle" data-i18n="settingsSidebarTitle">Brett-Einstellungen</h3>
<h3 id="settingsSidebarTitle" data-i18n="settingsSidebarTitle">Spiel-Einstellungen</h3>
<button class="btn secondary sidebar-close" onclick="toggleSidebar(false)" id="settingsSidebarClose"
type="button" data-i18n="settingsSidebarClose">Schliessen</button>
</div>
<p id="settingsSidebarText" data-i18n="settingsSidebarText">Passe die Brettgrösse zwischen 4 und 13 an.</p>
<section class="settings-section">
<p class="section-kicker" id="boardSettingsKicker" data-i18n="boardSettingsKicker">Brett</p>
<h4 id="boardSettingsTitle" data-i18n="boardSettingsTitle">Brettgrösse</h4>
<p id="settingsSidebarText" data-i18n="settingsSidebarText">Passe die Brettgrösse zwischen 4 und 13 an.</p>
<label class="sidebar-label" id="boardSizeInputLabel" for="boardSizeInput"
data-i18n="boardSizeInputLabel">Grösse</label>
<input id="boardSizeInput" type="range" min="4" max="13" value="8" oninput="previewBoardSize(this.value)">
<div class="sidebar-size-row">
<strong><span id="sidebarBoardSizeValue">8</span> x <span id="sidebarBoardSizeValueMirror">8</span></strong>
</div>
<label class="sidebar-label" id="boardSizeInputLabel" for="boardSizeInput"
data-i18n="boardSizeInputLabel">Grösse</label>
<input id="boardSizeInput" type="range" min="4" max="13" value="8" oninput="previewBoardSize(this.value)">
<div class="sidebar-size-row">
<strong><span id="sidebarBoardSizeValue">8</span> x <span
id="sidebarBoardSizeValueMirror">8</span></strong>
</div>
<button class="btn" onclick="applyBoardSize()" id="applyBoardSizeButton" type="button"
data-i18n="applyBoardSizeButton">Grösse anwenden</button>
<p class="sidebar-hint" id="settingsSidebarHint" data-i18n="settingsSidebarHint">Beim Ändern wird das Brett zur
Sicherheit zurückgesetzt. Auf
dem Handy ist 8x8 eingeplant, grössere Bretter können abgeschnitten wirken.</p>
<button class="btn" onclick="applyBoardSize()" id="applyBoardSizeButton" type="button"
data-i18n="applyBoardSizeButton">Grösse anwenden</button>
<p class="sidebar-hint" id="settingsSidebarHint" data-i18n="settingsSidebarHint">Beim Ändern wird das Brett
zur Sicherheit zurückgesetzt. Auf
dem Handy ist 8x8 eingeplant, grössere Bretter können abgeschnitten wirken.</p>
</section>
<section class="settings-section">
<p class="section-kicker" id="saveSettingsKicker" data-i18n="saveSettingsKicker">Speichern</p>
<h4 id="saveSettingsTitle" data-i18n="saveSettingsTitle">Fortschritt speichern</h4>
<p id="saveSettingsText" data-i18n="saveSettingsText">Öffne hier die Optionen zum Speichern oder Laden
deiner Save-Points.</p>
<div class="settings-action-grid">
<button class="btn" onclick="openSavePanel()" id="btnSave" type="button"
data-i18n="btnSave">Speichern</button>
<button class="btn secondary" onclick="openSavePointsPanel()" id="btnLoad" type="button"
data-i18n="btnLoad">Save-Points</button>
</div>
</section>
<section class="settings-section">
<p class="section-kicker" id="solutionSettingsKicker" data-i18n="solutionSettingsKicker">Lösung</p>
<h4 id="solutionSettingsTitle" data-i18n="solutionSettingsTitle">Lösungswerkzeuge</h4>
<p id="solutionSettingsText" data-i18n="solutionSettingsText">Lade eine Animation, steuere sie am Brett mit
Vorwärts und Zurück oder spiele sie automatisch ab.</p>
<div class="settings-action-grid">
<button class="btn" onclick="prepareSolutionTrace()" id="btnPrepareSolve" type="button"
data-i18n="btnPrepareSolve">Animation laden</button>
<button class="btn secondary" onclick="toggleSolverPlayback()" id="btnPlayPause" type="button"
data-i18n="btnPlayPause">Animation abspielen</button>
<button class="btn accent" onclick="instantSolve()" id="btnInstantSolve" type="button"
data-i18n="btnInstantSolve">Sofort lösen</button>
</div>
<div class="solver-speed">
<label class="solver-speed-label" id="solverSpeedLabel" for="solverSpeedInput"
data-i18n="solverSpeedLabel">Animationsgeschwindigkeit</label>
<input id="solverSpeedInput" type="range" min="80" max="900" step="20" value="320"
oninput="updateSolverSpeed(this.value)">
<span class="solver-speed-value" id="solverSpeedValue">320 ms</span>
</div>
</section>
</aside>
<aside class="sidebar save-sidebar" id="saveSidebar" aria-hidden="true">
@@ -338,23 +344,27 @@
<div class="modal-backdrop" id="infoModalBackdrop" onclick="toggleInfoModal(false)"></div>
<section class="modal" id="infoModal" aria-hidden="true" aria-labelledby="infoModalTitle">
<div class="modal-header">
<h3 id="infoModalTitle">Spielregeln und Acht-Damen-Problem</h3>
<h3 id="infoModalTitle">Spielanleitung</h3>
<button class="btn secondary sidebar-close" onclick="toggleInfoModal(false)" type="button"
data-i18n="infoModalClose">Schliessen</button>
</div>
<div class="modal-content">
<p data-i18n="infoModalIntro">Setze pro Reihe genau eine Figur auf das Brett. Eine gültige Lösung hat keine
Konflikte.</p>
<p data-i18n="infoModalIntro">Das Schachbrett besteht aus vielen quadratischen Feldern. Jedes Feld kann
leer sein oder genau eine Figur enthalten. Deine Aufgabe ist es, Figuren auf das Brett zu setzen,
ohne dass sie sich gegenseitig angreifen. Das Puzzle ist erst gelöst, wenn genau so viele Figuren auf
dem Brett stehen wie das Brett Felder pro Seite hat, also zum Beispiel 8 Figuren auf einem
8x8-Brett.</p>
<h4 data-i18n="infoModalModeHeading">So funktioniert der aktuelle Modus</h4>
<p id="infoModeRuleText">Im Damen-Modus dürfen sich Damen weder in derselben Spalte noch diagonal
angreifen. Mit einem Klick setzt oder entfernst du eine Figur.</p>
<h4 data-i18n="infoModalModeHeading">Grundregeln</h4>
<p id="infoModeRuleText">In diesem Modus spielst du mit Damen. Eine Dame ist die Figur mit dem Symbol ♛.
Sie darf keine andere Dame in derselben waagerechten Reihe, senkrechten Spalte oder schrägen
Diagonale treffen. Mit einem Klick setzt du eine Dame auf ein freies Feld oder entfernst sie wieder.</p>
<h4 id="infoModalProblemHeading">Was ist das Acht-Damen-Problem?</h4>
<p id="infoModalProblemText">Das klassische Acht-Damen-Problem fragt nach einer Anordnung von acht Damen
auf einem 8x8-Brett, bei der sich keine zwei Damen schlagen. Es ist ein bekanntes Beispiel für
kombinatorische Suche und Backtracking.</p>
<h4 id="infoModalProblemHeading">Was ist eine Dame?</h4>
<p id="infoModalProblemText">Eine Dame ist eine Schachfigur. In diesem Spiel musst du keine Schachregeln
lernen, sondern nur wissen: Eine Dame kann gerade und schräg über das Brett wirken. Darum müssen
Damen genug Abstand haben, damit sie sich nicht gegenseitig erreichen.</p>
<h4 data-i18n="infoModalTimeHeading">Was zeigen Zeit und Schritte?</h4>
<p data-i18n="infoModalTimeText">Der Schrittzähler erfasst deine Züge auf dem Brett. Die Zeit läuft für das
+34 -45
View File
@@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title data-i18n="meta.title">8-Damen- und 8-Tuerme Solver</title>
<title data-i18n="meta.title">8-Damen- und 8-Türme Solver</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/index.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/footer.css') }}">
</head>
@@ -13,16 +13,16 @@
<header class="landing-nav">
<a class="brand" href="{{ url_for('main.home') }}">
<span class="brand-mark">♛</span>
<span data-i18n="nav.brand">8-Damen- und 8-Tuerme Solver</span>
<span data-i18n="nav.brand">8-Damen- und 8-Türme-Löser</span>
</a>
<nav class="landing-links">
<a href="#problem" data-i18n="nav.problem">Problem</a>
<a href="#features" data-i18n="nav.features">Features</a>
<a href="#features" data-i18n="nav.features">Funktionen</a>
<a href="#journey" data-i18n="nav.journey">Ablauf</a>
<button class="lang-switch" id="langSwitch" type="button" aria-label="Sprache wechseln">DE</button>
<a class="nav-cta secondary" href="{{ url_for('login.login') }}" data-i18n="nav.login">Login</a>
<a class="nav-cta" href="{{ url_for('login.register') }}" data-i18n="nav.signup">Create Account</a>
<a class="nav-cta secondary" href="{{ url_for('login.login') }}" data-i18n="nav.login">Anmelden</a>
<a class="nav-cta" href="{{ url_for('login.register') }}" data-i18n="nav.signup">Account erstellen</a>
</nav>
</header>
@@ -33,42 +33,28 @@
</p>
<h1 data-i18n="hero.title">Entdecke das Acht-Damen- und Acht-Türme-Problem.</h1>
<p class="hero-text" data-i18n="hero.text">
Diese App macht aus einem klassischen Informatik- und Mathematikproblem ein interaktives Erlebnis:
Diese Webanwendung macht aus einem klassischen Informatik- und Mathematikproblem ein interaktives
Erlebnis:
Setze Damen oder Türme, verfolge den Solver Schritt für Schritt, miss deine Zeit und speichere
clevere Zwischenstände.
Zwischenstände.
</p>
<div class="hero-actions">
<a class="hero-button primary" href="{{ url_for('login.register') }}"
data-i18n="hero.primaryCta">Jetzt starten</a>
<a class="hero-button secondary" href="{{ url_for('login.login') }}"
data-i18n="hero.secondaryCta">Bereits Account? Login</a>
</div>
<div class="hero-facts">
<article>
<strong data-i18n="hero.fact1Title">Skalierbar</strong>
<span data-i18n="hero.fact1Text">Brettgrösse flexibel anpassen</span>
</article>
<article>
<strong data-i18n="hero.fact2Title">Schritt für Schritt</strong>
<span data-i18n="hero.fact2Text">Solver mit Animation</span>
</article>
<article>
<strong data-i18n="hero.fact3Title">Save-Points</strong>
<span data-i18n="hero.fact3Text">Zeit und Fortschritt behalten</span>
</article>
data-i18n="hero.secondaryCta">Bereits ein Account? Anmelden</a>
</div>
</div>
<div class="hero-visual">
<div class="board-showcase" id="heroBoard" aria-hidden="true"></div>
<div class="floating-card solver-card">
<p class="floating-label" data-i18n="hero.solverLabel">Solver</p>
<p class="floating-value" data-i18n="hero.solverValue">Backtracking live</p>
<p class="floating-label" data-i18n="hero.solverLabel">Lösungshelfer</p>
<p class="floating-value" data-i18n="hero.solverValue">Backtracking in Echtzeit</p>
</div>
<div class="floating-card timer-card">
<p class="floating-label" data-i18n="hero.challengeLabel">Challenge</p>
<p class="floating-label" data-i18n="hero.challengeLabel">Herausforderung</p>
<p class="floating-value" data-i18n="hero.challengeValue">Zeit und Schritte messen</p>
</div>
</div>
@@ -76,17 +62,20 @@
<section class="info-band" id="problem">
<div class="info-band-inner">
<p class="eyebrow" data-i18n="problem.eyebrow">Warum dieses Problem spannend ist</p>
<h2 data-i18n="problem.title">Die Acht-Damen- und Acht-Tuerme-Probleme sind mehr als Schachrätsel.</h2>
<p class="eyebrow" data-i18n="problem.eyebrow">Was ist das Acht-Damen-Problem?</p>
<h2 data-i18n="problem.title">Eine klassische schachmathematische Aufgabe mit überraschend vielen
Lösungen.</h2>
<p data-i18n="problem.text">
Beim Acht-Damen-Problem suchst du eine Anordnung von acht Damen auf einem Schachbrett, sodass sich
keine zwei Damen schlagen. Beim Acht-Türme-Problem gilt dieselbe Idee für Türme, nur mit
einfacheren Konfliktregeln. Beide Aufgaben zeigen, wie Mustererkennung, systematische Suche und
Backtracking funktionieren.
Das Acht-Damen-Problem ist eine schachmathematische Aufgabe: Acht Damen sollen auf einem
Schachbrett so aufgestellt werden, dass keine zwei Damen dieselbe Reihe, Spalte oder Diagonale
teilen. Das Problem lässt sich auf beliebige Brettgrössen verallgemeinern, indem n Damen auf einem
n x n-Brett platziert werden.
<br><br>
Gerade beim Damenproblem wird schnell sichtbar, warum Strategie wichtig ist: Es gibt unzählige
mögliche Platzierungen, aber nur sehr wenige wirklich gültige Lösungen. Genau das macht diese
App spannend, weil man nicht nur das Ergebnis sieht, sondern auch den Weg dorthin.
Für das klassische 8x8-Brett gibt es 92 Lösungen. Zählt man Stellungen, die nur durch Spiegelung
oder Drehung entstehen, als gleich, bleiben 12 eindeutige Lösungen übrig.
<br><br>
<a href="https://de-academic.com/dic.nsf/dewiki/13248" target="_blank" rel="noopener noreferrer">Quelle:
de-academic.com</a>
</p>
</div>
</section>
@@ -101,7 +90,7 @@
<article class="feature-card">
<span class="feature-icon">♟</span>
<h3 data-i18n="features.card1Title">Interaktives Brett</h3>
<p data-i18n="features.card1Text">Setze Damen oder Tuerme direkt auf dem Brett und prüfe, ob deine
<p data-i18n="features.card1Text">Setze Damen oder Türme direkt auf dem Brett und prüfe, ob deine
Anordnung konfliktfrei ist.</p>
</article>
@@ -109,7 +98,8 @@
<span class="feature-icon">⚙</span>
<h3 data-i18n="features.card2Title">Solver mit Animation</h3>
<p data-i18n="features.card2Text">Beobachte den Lösungsweg Schritt für Schritt und verstehe, wie
Backtracking arbeitet.</p>
Backtracking arbeitet.
</p>
</article>
<article class="feature-card">
@@ -121,8 +111,8 @@
<article class="feature-card">
<span class="feature-icon">💾</span>
<h3 data-i18n="features.card4Title">Save-Points</h3>
<p data-i18n="features.card4Text">Speichere Zwischenstaende mit Notizen, Zeiten und Schrittzahl für
<h3 data-i18n="features.card4Title">Speicherstände</h3>
<p data-i18n="features.card4Text">Speichere Zwischenstände mit Notizen, Zeiten und Schrittzahl für
späteres Weiterarbeiten.</p>
</article>
@@ -145,8 +135,8 @@
<article class="journey-step">
<span class="step-number">01</span>
<h3 data-i18n="journey.step1Title">Account erstellen</h3>
<p data-i18n="journey.step1Text">Registriere dich und erhalte Zugang zu Dashboard, Save-Points und
deinem Fortschritt.</p>
<p data-i18n="journey.step1Text">Registriere dich und erhalte Zugang zum Dashboard, zu
Speicherständen und zu deinem Fortschritt.</p>
</article>
<article class="journey-step">
@@ -160,8 +150,7 @@
<span class="step-number">03</span>
<h3 data-i18n="journey.step3Title">Lösen oder analysieren</h3>
<p data-i18n="journey.step3Text">Teste eigene Ideen oder lass dir die Lösung visuell vom Solver
lösen lassen, dabei wird 1:1
gezeigt wie der Solver vorgeht.</p>
zeigen, damit du den Lösungsweg besser nachvollziehen kannst.</p>
</article>
</div>
</section>
@@ -177,9 +166,9 @@
<div class="hero-actions">
<a class="hero-button primary" href="{{ url_for('login.register') }}"
data-i18n="cta.primaryCta">Create Account</a>
data-i18n="cta.primaryCta">Account erstellen</a>
<a class="hero-button secondary" href="{{ url_for('login.login') }}"
data-i18n="cta.secondaryCta">Login</a>
data-i18n="cta.secondaryCta">Anmelden</a>
</div>
</div>
</section>