<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zauberwürfel lösen</title>
    <description>The latest articles on DEV Community by Zauberwürfel lösen (@zauberwuerfelloesen).</description>
    <link>https://dev.to/zauberwuerfelloesen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4195777%2F550bea5a-7223-405c-be64-89b40c432d93.png</url>
      <title>DEV Community: Zauberwürfel lösen</title>
      <link>https://dev.to/zauberwuerfelloesen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zauberwuerfelloesen"/>
    <language>en</language>
    <item>
      <title>Der weiße Kreuz-Test: Eine Spezifikation für ein Würfel-Lernwerkzeug</title>
      <dc:creator>Zauberwürfel lösen</dc:creator>
      <pubDate>Tue, 20 Oct 2026 09:28:57 +0000</pubDate>
      <link>https://dev.to/zauberwuerfelloesen/der-weisse-kreuz-test-eine-spezifikation-fur-ein-wurfel-lernwerkzeug-20gj</link>
      <guid>https://dev.to/zauberwuerfelloesen/der-weisse-kreuz-test-eine-spezifikation-fur-ein-wurfel-lernwerkzeug-20gj</guid>
      <description>&lt;p&gt;„Das Kreuz ist fertig“ klingt nach einer einfachen Aussage. Für ein Lernwerkzeug ist sie aber erst dann brauchbar, wenn klar ist, welche Bedingungen tatsächlich erfüllt sein müssen. Eine weiße Form auf einer Seite ist dafür zu wenig.&lt;/p&gt;

&lt;p&gt;Wir betrachten einen gewöhnlichen 3×3 und ein weißes Kreuz. Die vier weißen Kanten müssen um den weißen Mittelstein liegen. Zusätzlich muss die zweite Farbe jeder dieser Kanten zum Mittelstein der angrenzenden Seite passen. Genau diese zweite Bedingung wird beim Lernen leicht übersehen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vom Eindruck zur überprüfbaren Regel
&lt;/h2&gt;

&lt;p&gt;Stell dir vor, ein Programm erhält für jede der vier Kreuzpositionen drei Angaben: Liegt Weiß auf der weißen Seite? Welche Farbe zeigt die Kante seitlich? Welche Farbe hat der Mittelstein dieser Seite? Dann lässt sich eine bewusst lokale Prüfung formulieren.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hasAlignedWhiteCross&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;edge&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;whiteOnWhiteFace&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sideColor&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;centerColor&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Diese Funktion setzt voraus, dass die vier Einträge bereits die vier verschiedenen Kreuzpositionen beschreiben. Sie prüft nicht, ob die Eingabe aus einem echten Würfel stammt. Wer denselben Eintrag viermal übergibt, hat den Datenvertrag verletzt. Ein produktives Werkzeug müsste Positionen identifizieren und doppelte oder fehlende Angaben gesondert behandeln.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die entscheidenden Gegenbeispiele
&lt;/h2&gt;

&lt;p&gt;Beginne mit vier korrekt ausgerichteten Kanten. Ändere nun die seitliche Farbe genau einer Kante. Der Test muss fehlschlagen, obwohl von oben weiterhin ein weißes Kreuz zu sehen sein kann. Das ist ein nützlicher Regressionstest für eine Oberfläche, die sonst nur die obere Fläche betrachtet.&lt;/p&gt;

&lt;p&gt;Ein zweites Gegenbeispiel ist eine Kante mit korrekter Farbkombination, aber falscher Orientierung. Auch sie darf die Prüfung nicht bestehen. Ein dritter Fall sind nur drei erfasste Kanten: „Alle vorhandenen stimmen“ ist logisch etwas anderes als „Alle erforderlichen sind vorhanden und stimmen“.&lt;/p&gt;

&lt;p&gt;Gerade der letzte Fall zeigt, warum ein bloßes every auf einer Liste nicht genügt. Auf einer leeren Liste liefert every in JavaScript true. Die Längenprüfung im Beispiel gehört deshalb zur fachlichen Aussage, nicht nur zur defensiven Programmierung.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eine hilfreiche Fehlermeldung
&lt;/h2&gt;

&lt;p&gt;Ein rotes Kreuzsymbol allein erklärt wenig. Besser ist eine Rückmeldung wie: „Die weiß-grüne Kante liegt auf der weißen Seite; ihre grüne Seite passt aber noch nicht zum grünen Mittelstein.“ So sieht die lernende Person, welcher Teil bereits stimmt und welcher noch geprüft werden muss.&lt;/p&gt;

&lt;p&gt;Das Werkzeug sollte aus einer solchen Diagnose keine universelle Reparaturfolge ableiten. Die passenden Züge hängen von der gesamten Stellung ab. Eine kurze Folge kann in einem bestimmten Fall helfen und in einem anderen bereits gelöste Kanten wieder verändern. Diagnose und Lösungsvorschlag benötigen unterschiedliche Informationen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Übung am echten Würfel
&lt;/h2&gt;

&lt;p&gt;Halte den Würfel zunächst mit Weiß oben. Prüfe jede der vier Kanten einzeln und lies ihre zweite Farbe ab. Drehe anschließend den gesamten Würfel in der Hand, um die Seiten zu sehen, ohne die Ebenen zu verändern. Vergleiche jede Kantenfarbe mit dem zugehörigen Mittelstein.&lt;/p&gt;

&lt;p&gt;Notiere für jede Position „oben richtig“ und „seitlich richtig“ getrennt. Erst wenn alle acht Teilprüfungen stimmen, ist dieses Kreuz korrekt ausgerichtet. Die Ecken sind damit noch nicht gelöst; ein korrektes Kreuz ist ein Zwischenziel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Warum diese Spezifikation nützt
&lt;/h2&gt;

&lt;p&gt;Ein klar benanntes Zwischenziel macht einen Lernweg nachvollziehbar. Die Oberfläche muss kein vollständiger Solver sein, um hilfreiches Feedback zu geben. Sie muss aber die Grenzen ihrer Prüfung offenlegen und darf einen Teilzustand nicht als vollständig gelösten Würfel ausgeben.&lt;/p&gt;

&lt;p&gt;Die Originalgrafik zeigt den Unterschied zwischen einer weißen Form und einem korrekt ausgerichteten Kreuz. Unser Projekt &lt;a href="https://zauberwuerfelloesen.de/" rel="noopener noreferrer"&gt;Zauberwürfel lösen&lt;/a&gt; bietet dazu eine &lt;a href="https://zauberwuerfelloesen.de/anleitung/" rel="noopener noreferrer"&gt;praktische Schritt-für-Schritt-Anleitung&lt;/a&gt;. Dieser technische Beitrag beschreibt die Prüfung hinter dem Lernziel, keinen universellen Lösungsalgorithmus.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7nrqjj1zm3oifizay425.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7nrqjj1zm3oifizay425.png" alt="Originalgrafik: korrektes Kreuz und Seitenfarben" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>learning</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Undo für Würfelzüge: Warum die inverse Folge rückwärts gelesen wird</title>
      <dc:creator>Zauberwürfel lösen</dc:creator>
      <pubDate>Tue, 20 Oct 2026 09:25:38 +0000</pubDate>
      <link>https://dev.to/zauberwuerfelloesen/undo-fur-wurfelzuge-warum-die-inverse-folge-ruckwarts-gelesen-wird-2m48</link>
      <guid>https://dev.to/zauberwuerfelloesen/undo-fur-wurfelzuge-warum-die-inverse-folge-ruckwarts-gelesen-wird-2m48</guid>
      <description>&lt;p&gt;Ein Undo-Knopf wirkt selbstverständlich, bis mehrere Zustandsänderungen zusammenkommen. Der Zauberwürfel macht das Problem greifbar: Wer eine Zugfolge rückgängig machen möchte, muss nicht nur jeden Zug umkehren, sondern auch die Reihenfolge umdrehen.&lt;/p&gt;

&lt;p&gt;Das ist ein schönes Beispiel für inverse Operationen und für Tests, die ein kleines Lernwerkzeug zuverlässig machen können. Wir bleiben bei sechs Außenseitenzügen und ihren Zusätzen Apostroph oder 2. Der Code berechnet eine inverse Zeichenfolge; er ist kein Würfelsimulator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der letzte Schritt wird zuerst aufgehoben
&lt;/h2&gt;

&lt;p&gt;Angenommen, die Folge lautet R U F2. Zuerst wurde rechts gedreht, dann oben und zuletzt vorne um 180 Grad. Um zum Anfang zurückzukehren, hebt man zuerst F2 auf. Danach folgt U' und zuletzt R'. Die inverse Folge lautet also F2 U' R'.&lt;/p&gt;

&lt;p&gt;Die bloße Folge R' U' F2 ist im Allgemeinen nicht das Undo der ursprünglichen Folge. Drehungen verschiedener Seiten sind nicht beliebig vertauschbar. Das kennt man auch von anderen Arbeitsabläufen: Wer erst eine Schachtel öffnet und dann etwas hineinlegt, kann diese Handlung nicht rückgängig machen, indem er zuerst die Schachtel schließt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eine kleine reine Funktion
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;invertMoves&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;invertMoves&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;R&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;U&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;F2 U' R'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Die Funktion erwartet bereits validierte Tokens. Ein halber Zug bleibt ein halber Zug, weil zweimal 180 Grad zusammen 360 Grad ergeben. Bei Vierteldrehungen wechselt ein Zug zwischen normaler Schreibweise und Apostroph.&lt;/p&gt;

&lt;p&gt;Die Kopie mit [...tokens] ist wichtig: reverse verändert ein Array direkt. Würden wir das Eingabearray umdrehen, könnte eine andere Anzeige im Trainer plötzlich ihre Reihenfolge wechseln. Das wäre ein Seiteneffekt des Undo-Berechnens, obwohl noch gar kein Zug ausgeführt wurde.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drei Tests mit unterschiedlicher Aussage
&lt;/h2&gt;

&lt;p&gt;Erstens sollte die Inversion eines einzelnen R zu R' führen. Zweitens muss die beispielhafte Folge R U F2 die erwartete Folge F2 U' R' ergeben. Drittens sollte eine doppelte Inversion wieder dieselbe Tokenliste liefern.&lt;/p&gt;

&lt;p&gt;Der dritte Test ist nützlich, aber allein nicht ausreichend. Eine fehlerhafte Funktion, die ihre Eingabe unverändert zurückgibt, besteht ihn ebenfalls. Ein Test braucht deshalb nicht nur eine elegante Eigenschaft, sondern auch konkrete Gegenbeispiele und bekannte erwartete Ergebnisse.&lt;/p&gt;

&lt;p&gt;Für einen echten Simulator kommt ein weiterer Test hinzu: Wendet man eine Folge und anschließend ihre Inverse an, muss der vollständige Zustand wieder identisch sein. Vergleiche dabei alle relevanten Bauteile und Orientierungen. Ein Foto einer einzelnen Farbseite kann Fehler auf der Rückseite verbergen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Undo ist kein Reparaturversprechen
&lt;/h2&gt;

&lt;p&gt;Am echten Würfel funktioniert das Rückgängigmachen nur zuverlässig, wenn die tatsächlich ausgeführten Züge bekannt sind und dieselbe Orientierungskonvention beibehalten wurde. Wer zwischendurch den Würfel anders hält oder einen Zug überspringt, hat eine andere Historie als das Programm.&lt;/p&gt;

&lt;p&gt;Ein Lernwerkzeug sollte deshalb nach jedem bestätigten Zug einen klaren Fortschritt anzeigen. Bei einer Unterbrechung kann es den letzten sicheren Schritt markieren. Nach einem nicht protokollierten Handgriff ist eine ehrliche Rückfrage besser als ein automatisches „Jetzt ist alles repariert“.&lt;/p&gt;

&lt;h2&gt;
  
  
  Übung und Erklärung
&lt;/h2&gt;

&lt;p&gt;Schreibe drei Züge auf, etwa R U F2. Lege die inverse Folge schriftlich daneben, bevor du etwas drehst. Führe beide Folgen langsam aus und prüfe anschließend den ganzen Würfel. Wiederhole die Übung mit nur einem Zug mit Apostroph. Ziel ist zuerst das Verständnis der Umkehrung, nicht die Geschwindigkeit.&lt;/p&gt;

&lt;p&gt;Wir nutzen solche kleinen Übungen im deutschsprachigen Projekt &lt;a href="https://zauberwuerfelloesen.de/" rel="noopener noreferrer"&gt;Zauberwürfel lösen&lt;/a&gt;. Die &lt;a href="https://zauberwuerfelloesen.de/anleitung/" rel="noopener noreferrer"&gt;Anleitung&lt;/a&gt; ergänzt die technische Erklärung um den Lernweg am echten 3×3. Die Grafik gehört zu unserer Original-Lernreihe über systematische Fehlerkontrolle.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg7f5hz3b423yeglso6oc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg7f5hz3b423yeglso6oc.png" alt="Originalgrafik: sichere Zwischenstände und systematische Fehlerkontrolle" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>code</category>
      <category>computerscience</category>
      <category>programming</category>
    </item>
    <item>
      <title>Einen kleinen Parser für Würfelnotation bauen – mit klaren Grenzen</title>
      <dc:creator>Zauberwürfel lösen</dc:creator>
      <pubDate>Tue, 20 Oct 2026 09:22:24 +0000</pubDate>
      <link>https://dev.to/zauberwuerfelloesen/einen-kleinen-parser-fur-wurfelnotation-bauen-mit-klaren-grenzen-4b70</link>
      <guid>https://dev.to/zauberwuerfelloesen/einen-kleinen-parser-fur-wurfelnotation-bauen-mit-klaren-grenzen-4b70</guid>
      <description>&lt;p&gt;Wer einen Algorithmus-Trainer entwickelt, braucht zuerst eine verlässliche Eingabe. Ein Feld, das beliebigen Text annimmt und stillschweigend unbekannte Zeichen entfernt, ist bei Würfelzügen keine gute Grundlage: Aus einer fehlerhaften Zugfolge kann so unbemerkt eine andere werden.&lt;/p&gt;

&lt;p&gt;Hier bauen wir einen kleinen Parser für genau sechs Außenseitenzüge. Er akzeptiert R, L, U, D, F und B, jeweils optional mit einem Apostroph oder einer 2. Andere Notationen werden bewusst abgelehnt. Das Beispiel ist eine Lernhilfe und kein vollständiger Standardparser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die Perspektive gehört zur Grammatik
&lt;/h2&gt;

&lt;p&gt;R bezeichnet die rechte Seite, U die obere und F die vordere. Ein Buchstabe ohne Zusatz bedeutet eine Vierteldrehung im Uhrzeigersinn, betrachtet direkt auf die betreffende Seite. Ein Apostroph bezeichnet die Gegenrichtung; eine 2 eine halbe Drehung.&lt;/p&gt;

&lt;p&gt;„Im Uhrzeigersinn“ bezieht sich also nicht immer auf dieselbe Sicht von vorne. Gerade B oder D werden häufig falsch interpretiert. Ein Parser kann die Schreibweise prüfen, aber nicht feststellen, ob ein Mensch den Würfel richtig hält. Ein Trainer muss diese Perspektive zusätzlich erklären.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eine kleine, explizite Grammatik
&lt;/h2&gt;

&lt;p&gt;Das folgende Beispiel erwartet durch Leerzeichen getrennte Tokens. Führende und nachfolgende Leerzeichen sind erlaubt. Ein leerer Text entspricht einer leeren Zugfolge.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parseMoves&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;([&lt;/span&gt;&lt;span class="sr"&gt;RLUDFB&lt;/span&gt;&lt;span class="se"&gt;])(&lt;/span&gt;&lt;span class="sr"&gt;2|'&lt;/span&gt;&lt;span class="se"&gt;)?&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unbekannter Zug: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;face&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;turns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Die Funktion verändert keinen Würfel. Sie produziert eine strukturierte Liste mit Seite und Vierteldrehungen. Der Wert 3 ist dabei eine bequeme Darstellung für eine Vierteldrehung gegen den Uhrzeigersinn: Drei Drehungen im Uhrzeigersinn haben denselben Effekt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was wird absichtlich nicht akzeptiert?
&lt;/h2&gt;

&lt;p&gt;Klammern, Wiederholungsgruppen, Slice-Moves, breite Züge, Rotationen des ganzen Würfels und Schreibweisen ohne Trennzeichen gehören nicht zu dieser Minimalversion. Auch R2' wird abgelehnt, obwohl manche Notationen eine solche Schreibweise tolerieren. Für ein kleines Werkzeug ist eine eng erklärte Eingabesprache oft hilfreicher als halb unterstützte Sonderfälle.&lt;/p&gt;

&lt;p&gt;Eine Fehlermeldung sollte das problematische Token nennen. „Ungültige Eingabe“ sagt wenig aus; „Unbekannter Zug: Q“ lässt sich sofort beheben. Für eine spätere Erweiterung wären außerdem die Position im Text und ein Beispiel für eine zulässige Eingabe nützlich.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests beginnen mit Gegenbeispielen
&lt;/h2&gt;

&lt;p&gt;Probiere zunächst eine einzelne Drehung, dann eine halbe Drehung und danach einen Zug mit Apostroph. Prüfe anschließend mehrere Leerzeichen, einen Zeilenumbruch und eine leere Eingabe. Zum Schluss müssen Q, R3 und die nicht unterstützte Schreibweise RUR' eine verständliche Fehlermeldung auslösen.&lt;/p&gt;

&lt;p&gt;Ein besonders wichtiger Test ist die unveränderte Reihenfolge. Der Parser darf R U niemals in U R umsortieren. Auf einem Würfel ist die Reihenfolge im Allgemeinen entscheidend. Eine Sortierung, die bei Farbnamen als Identitätsvergleich sinnvoll sein kann, wäre hier ein gravierender Fehler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Von der Eingabe zum Lernwerkzeug
&lt;/h2&gt;

&lt;p&gt;Zeige nach dem Parsen die Tokens einzeln an. Lass die lernende Person den nächsten Zug zuerst benennen, bevor die Animation startet. Eine Pause sollte die aktuelle Ansicht und den bisherigen Fortschritt erhalten. Nach einem Fehler ist eine verständliche Rückkehr zum letzten sicheren Zustand wertvoller als eine schnelle weitere Animation.&lt;/p&gt;

&lt;p&gt;Ein vollständiger Simulator benötigt zusätzlich getestete Zugoperatoren. Erst sie legen fest, welche Bauteile ein Zug bewegt und wie sich ihre Orientierung ändert. Parser und Simulator getrennt zu prüfen macht Fehler leichter auffindbar.&lt;/p&gt;

&lt;p&gt;Weitere Erklärungen zu Bauteilen und Notation bietet unser Lernprojekt &lt;a href="https://zauberwuerfelloesen.de/" rel="noopener noreferrer"&gt;Zauberwürfel lösen&lt;/a&gt;. Die &lt;a href="https://zauberwuerfelloesen.de/anleitung/" rel="noopener noreferrer"&gt;praktische Anleitung&lt;/a&gt; verbindet die Zeichen mit dem Würfel in der Hand. Text, Beispiel und Grafik sind für diese Lernreihe erstellt; der Code ist bewusst ein begrenztes Lehrbeispiel.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3xi64702efq1cob89q9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3xi64702efq1cob89q9h.png" alt="Originalgrafik zu Würfelbauteilen und Notation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>coding</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Zauberwürfel als Zustandsmodell: Warum Farben allein nicht reichen</title>
      <dc:creator>Zauberwürfel lösen</dc:creator>
      <pubDate>Tue, 20 Oct 2026 09:20:20 +0000</pubDate>
      <link>https://dev.to/zauberwuerfelloesen/zauberwurfel-als-zustandsmodell-warum-farben-allein-nicht-reichen-2neh</link>
      <guid>https://dev.to/zauberwuerfelloesen/zauberwurfel-als-zustandsmodell-warum-farben-allein-nicht-reichen-2neh</guid>
      <description>&lt;p&gt;Ein 3×3-Zauberwürfel ist ein überraschend gutes Beispiel für Datenmodellierung. Auf den ersten Blick sieht man 54 farbige Felder. Für viele Aufgaben ist es jedoch sinnvoller, die beweglichen Bauteile zu betrachten: zwölf Kanten und acht Ecken. Die Mittelsteine legen fest, welche Farben zu den Seiten gehören.&lt;/p&gt;

&lt;p&gt;Dieser Beitrag entwickelt ein kleines Modell für Lernwerkzeuge. Er ist kein vollständiger Solver. Es geht darum, Begriffe sauber zu trennen, damit ein Übungsprogramm nicht versehentlich eine falsche Stellung als gelöst bestätigt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identität, Position und Orientierung
&lt;/h2&gt;

&lt;p&gt;Eine Kante hat zwei Farben. Diese Farbkombination bestimmt ihre Identität: Eine weiß-grüne Kante bleibt dieselbe Kante, auch wenn sie gerade hinten oben liegt. Ihre Position beschreibt dagegen den Platz im Würfel. Ihre Orientierung beschreibt, wie sie an diesem Platz gedreht ist.&lt;/p&gt;

&lt;p&gt;Bei einer Ecke gilt dasselbe mit drei Farben. Der Zielplatz einer weiß-grün-roten Ecke liegt dort, wo die entsprechenden drei Seiten zusammentreffen. Eine weiße Fläche genügt deshalb nicht als Lösungsprüfung: Die weißen Steine können oben liegen, während die seitlichen Farben noch nicht zu den Mittelsteinen passen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ein bewusst kleines JavaScript-Modell
&lt;/h2&gt;

&lt;p&gt;Für eine Erklärung kann man die Identität als sortierte Farbliste ausdrücken. Das ist praktisch für Vergleiche, bildet aber noch keine physikalischen Züge ab.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pieceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;colors&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;samePiece&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;pieceId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nf"&gt;pieceId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;samePiece&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;samePiece&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Die Sortierung macht nur die Reihenfolge der Farbnamen unwichtig. Sie macht aus einer falschen Farbkombination keine richtige und verrät auch nichts über die Orientierung.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests, die eine falsche Sicherheit verhindern
&lt;/h2&gt;

&lt;p&gt;Ein sinnvoller Testfall beginnt mit einem korrekten Zielplatz. Danach verändert man genau eine Eigenschaft: dieselbe Kante am falschen Platz, eine andere Kante am richtigen Platz oder dieselbe Kante mit vertauschter Orientierung. Wer nur die Identität vergleicht, muss im dritten Fall noch keine vollständige Lösung melden.&lt;/p&gt;

&lt;p&gt;Für einen echten Simulator braucht das Modell feste Konventionen. Was bedeutet vorne? Welche Seite ist oben? Wie werden Eckorientierungen gezählt? Solche Regeln gehören in die Dokumentation und in die Tests. Eine nicht erklärte Konvention ist eine häufige Ursache für scheinbar zufällige Fehler.&lt;/p&gt;

&lt;p&gt;Auch die Mittelsteine brauchen eine klare Behandlung. Beim üblichen 3×3 bleiben ihre relativen Beziehungen erhalten. Dreht man den ganzen Würfel in der Hand, ändert sich die Sicht des Betrachters, nicht die Identität seiner Bauteile. Ein Lernwerkzeug sollte zwischen einer Änderung der Ansicht und einem Zug einer Ebene unterscheiden.&lt;/p&gt;

&lt;h2&gt;
  
  
  Übung ohne Code
&lt;/h2&gt;

&lt;p&gt;Suche am echten Würfel eine beliebige Kante. Nenne beide Farben und zeige ihren Zielplatz anhand der Mittelsteine, ohne etwas zu drehen. Wiederhole die Aufgabe mit einer Ecke und ihren drei Farben. Erst wenn der Zielplatz klar ist, lohnt sich die Frage nach einer Zugfolge.&lt;/p&gt;

&lt;p&gt;Die Übung ist klein, aber sie prüft genau die Trennung zwischen Beobachtung und Planung. „Ich sehe Weiß“ ist eine Beobachtung. „Dieser Stein gehört hierher“ benötigt bereits eine Regel. „Ich drehe jetzt R“ ist ein Eingriff in den Zustand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grenzen des Beispiels
&lt;/h2&gt;

&lt;p&gt;Das Modell prüft keine vollständige Würfelstellung auf Lösbarkeit. Es erkennt keine verdrehte Einzelecke und keine unzulässige Vertauschung. Es ersetzt auch keinen getesteten Zugoperator. Diese Grenzen ausdrücklich zu benennen ist hilfreicher, als einem kurzen Codebeispiel Eigenschaften zuzuschreiben, die es nicht besitzt.&lt;/p&gt;

&lt;p&gt;Wir entwickeln unter &lt;a href="https://zauberwuerfelloesen.de/" rel="noopener noreferrer"&gt;Zauberwürfel lösen&lt;/a&gt; deutschsprachiges Lernmaterial. Die &lt;a href="https://zauberwuerfelloesen.de/anleitung/" rel="noopener noreferrer"&gt;Schritt-für-Schritt-Anleitung&lt;/a&gt; ergänzt das abstrakte Modell um den praktischen Lernweg am Würfel. Dieser Beitrag und die Grafik stammen aus unserem Projekt.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6moio79lmw9y87z3a69d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6moio79lmw9y87z3a69d.png" alt="Originalgrafik: Ecke, Kante und Mittelstein mit ihren Zielplätzen" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>computerscience</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
