Wie kann ich sicherstellen, dass ein Gitter mit Tetris-ähnlichen Teilen gefüllt werden kann?

8

Ich denke an ein Puzzlespiel, bei dem das Ziel darin besteht, ein Gitter mit geformten Puzzleteilen zu füllen (zum Beispiel die klassischen Tetris-Formen).

Wie kann ich eine Reihe von Teilen erstellen, die garantiert zum Füllen des Rasters verwendet werden können, ohne Lücken zu hinterlassen? Wie könnte ich diesen Algorithmus anpassen, um die Schwierigkeit des resultierenden Puzzles zu skalieren?

Baher Ramzy
quelle
1
Erlauben Sie einzelne oder kleine zwei Squarenparts?
Steven
@steven "Monominos" und "Dominos". Alle klassischen Tetris-Stücke sind Tetrominos. Es gibt 12 Pentominos und 35 Hexominos ...
David van Brink

Antworten:

8

Dies ist ein bekanntes schwieriges Problem, bei dem bestimmt wird, welche Rechtecke mit bestimmten Teilen gekachelt werden können.

Wenn Sie jedoch Rätsel bauen und die Teile kontrollieren können, ist das Gegenteil der Fall, ein konstruktives Problem und einfacher ...

Konstruktiv eine Lösung erstellen. Nehmen Sie ein paar Teile, die Sie mögen, und füllen Sie das Puzzle, wie Sie möchten. Wirf dann genug einzelne Quadrate ein, um es auszufüllen, und du hast garantiert, dass es mindestens eine Lösung gibt. Oder besser gesagt, fügen Sie einige kleine Stücke in Ihren erlaubten Satz von Stücken ein.

Ein typischer Brute-Force-Ansatz zum Lösen / Auslegen der Teile besteht darin, sie von links nach rechts und dann von oben nach unten zu füllen. Suchen Sie die erste offene Zelle (nummeriert LR, TB) und versuchen Sie, Ihre zulässigen Teile in ihren zulässigen Ausrichtungen einzufügen (8 Ausrichtungen für ein asymmetrisches Teil, wenn Sie das Umdrehen zulassen). Überprüfen Sie möglicherweise zuerst die großen zulässigen Teile und greifen Sie bei Bedarf auf kleinere zurück. Wenn Sie einen Zustand erreichen, den Sie nicht mögen (Sackgasse, zu viele kleine Stücke oder was nicht), dann ziehen Sie sich zurück. Wenn ein bestimmtes Raster- / Stück-Set nicht Ihren Kriterien entspricht, dh ohne Fertigstellung vollständig zurückverfolgt wird, versuchen Sie es mit einem anderen Rechteck- und Stück-Set.

Eine Möglichkeit, ein Puzzle "einfacher" zu machen, könnte darin bestehen, größere Teile gegen kleinere Teile wie Monominos und Dominosteine ​​zu tauschen, da dies mehr Möglichkeiten zum Ausfüllen der letzten Löcher bietet. Oder erstellen Sie gleichwertig eine Lösung, die diese kleineren Teile bevorzugt.

Einige bekannte Polyominologen sind:

==> http://ee.usc.edu/faculty_staff/faculty_directory/golomb.htm Golomb hat ursprünglich den Begriff "Polyomino" geprägt.

==> http://www.eklhad.net/polyomino/ Dahlke hat einige Rechtecke gelöst, die mit identischen Teilen gefüllt sind (eine besonders seltene Kachelform).

David Van Rand
quelle
3

Dieser Artikel (Seite 11-13, Haftungsausschluss: Ich bin einer der Autoren) beschreibt einen Algorithmus, der dynamische Programmierung verwendet, um perfekt gekachelte rechteckige Bereiche der Breite w und Höhe h in einer Zeit zu erzeugen , die nach einer Vorverarbeitung in h linear ist dauert ungefähr 2 ( w . D ) Zeit / Raum ( D ist die längste Dimension einer einzelnen Form, z. B. 4 bei Tetris-Stücken).

Die Idee ähnelt der oben von David beschriebenen und konzentriert sich auf den oberen Streifen , wobei Teile platziert werden, die keine Löcher erzeugen . Das Wichtigste dabei ist, zunächst die zulässigen Alternativen für jeden Zustand des oberen Streifens vorab zu berechnen, damit Sie bei der Generierung der Regionen nicht mehr für die kombinatorische Explosion bezahlen.

Der Algorithmus funktioniert für jeden Satz von (konvexen) Formen.

Ein interessanter Aspekt einer einheitlichen Zufallsgenerierung ist auch, dass sie maximale Diversität zwischen aufeinanderfolgenden Generationen gewährleistet (Sie können die Generierung jedoch auch beliebig einschränken). Hier sind einige typische Ausgaben:

Einige zufällig erzeugte Tetrises der Breite 6

Fragen Sie einfach, ob Sie Probleme mit der Implementierung haben (möglicherweise liegt irgendwo eine schnelle und schmutzige Python-Implementierung herum ...)

Yann Ponty
quelle
Die von Ihnen erwähnte Python-Implementierung wäre sehr hilfreich
user2682863
1

Hier ist eine Technik, die wir in der Vergangenheit verwendet haben, um ein bisschen auf engere Hardware zu schummeln. Es ist nicht so rein wie die komplexeren Lösungen, hat aber den entscheidenden Vorteil, dass es viel einfacher zu implementieren ist und jedes Mal funktioniert.

Anstatt sich auf das gesamte Puzzle zu konzentrieren, teilen Sie es in kleinere, einheitliche Einheiten auf . Jede dieser Einheiten besteht aus einer festgelegten Anzahl von Teilen, die zu Quadraten oder Rechtecken zusammenpassen, die sich viel einfacher in ein Puzzle einfügen lassen. Wählen Sie zufällig aus den verschiedenen Konfigurationen, um die Breite des Puzzles zu füllen (Beispiele unten, aber es gibt viele, viele Konfigurationen). Unten finden Sie 4x4s, ein 5x4 und sogar ein 10x4 Beispiel.

Quadrate und Rechtecke

Die Idee ist, dass Sie das Puzzle "streifen" ... wählen Sie die Breiten zufällig basierend auf dem verfügbaren verbleibenden Raum. Sobald ein "Streifen" fertig ist, starten Sie einen neuen Streifen.

Sie geben jeweils einen Streifen frei, indem Sie in jedem "Streifensatz" eine Zufallsauswahl treffen. Wenn Sie den Schwierigkeitsgrad erhöhen möchten, lassen Sie zufällig zwei oder mehr Streifen gleichzeitig los.

Mit dieser Technik haben Sie nicht nur garantiert, dass das Rätsel lösbar ist, sondern auch dazu beigetragen, die Reihenfolge der Veröffentlichung zu "betrügen", um das Überleben zu erleichtern. Natürlich können die Spieler in der Praxis nicht jeden Streifen perfekt lösen, und so entsteht Chaos.

Generiere so lange Streifen, bis der Spieler verliert. Natürlich ist mein Beispiel ein 4 Block hoher Streifen, aber Sie können etwas Größeres und Komplexeres wählen:

Geben Sie hier die Bildbeschreibung ein

Rob Craig
quelle