In der Tech-Demo, die ich erstellen möchte, werden vom Spieler Blöcke im Tetrominoe-Stil platziert. Zu diesem Zeitpunkt prüft das Spiel, ob sie ein Quad mit vorhandenen Formen auf dem Brett erstellt haben (ein 2D-Array). In diesem Fall sollte das Quad auf irgendeine Weise verarbeitet werden.
Ich habe ein 2D-Array wie folgt:
[ [0, 0, 0, 1, 1, 1],
[0, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 1, 1],
[1, 0, 0, 1, 0, 1] ]
Und ich muss 'Quad'-Muster wie das in der oberen rechten Ecke identifizieren, z
[ [1, 1, 1],
[1, 1, 1],
[1, 1, 1] ]
Ich bin mir nicht sicher, wie ich das am besten machen kann. Ich habe mir einige zweidimensionale Array-Muster-Matching-Algorithmen angesehen, die alle das 2D-Array in 1D zu reduzieren scheinen, und dann einen 1D-Textsuchalgorithmus (z. B. KMP) verwendet, um Übereinstimmungen zu identifizieren. Meine Probleme mit dieser Idee sind, dass das Quad jede Größe haben kann, solange es rechteckig und größer als ein beliebiges Minimum ist (in meinem Fall 2 x 2).
Ich dachte auch darüber nach, für jede Position der neu platzierten Tetrominoe eine Variante des 4-Wege-Flutfüllungsalgorithmus oder der Kennzeichnung verbundener Komponenten zu verwenden. Aber ich bin mir nicht ganz sicher, wie ich dem Pfad am besten folgen und die Grenzen eines Quads festlegen soll (zum Beispiel, um dies zu erfassen:
[ [1, 1, 1],
[1, 1, 1],
[1, 1, 1] ]
aus dieser:
[ [1, 1, 1, 1],
[1, 1, 1, 0],
[1, 1, 1, 0] ]
Meine letzte ist jedoch vielleicht eine Überflutung, um alle miteinander verbundenen Teile zu erhalten, nachdem eine Tetrominoe gelandet ist, und dann die gezackten Kanten abzurunden, indem Sie möglicherweise die Anzahl der Nachbarn jedes Blocks überprüfen. Wenn es 1 ist, entfernen Sie sie und wiederholen Sie den Vorgang, bis alle verbleibenden übrig sind Blöcke haben 2 oder mehr Nachbarn. Aber das scheint langsam zu sein.
Hat jemand Erfahrung mit diesem Problem oder Hinweise, wie diese Aufgabe am besten gelöst werden kann? Ich bin sicher, es gibt einen gemeinsamen oder zumindest anwendbaren Algorithmus, ich weiß es einfach nicht!
quelle
Antworten:
Ich habe es gezeichnet.
Was alles bedeutet
Was ist passiert?
Im ersten Diagramm (grün) hat es fantastisch geklappt. In der allerersten oberen linken Ecke, die wir überprüft haben, sind rechts unten Quadrate ausgefüllt, die einen
2x2
Block bilden. Wenn wir versuchen, noch ehrgeiziger zu sein und einen3x3
Block zu bilden, stellen wir fest, dass einige davon (die roten Kreuze) nicht gefüllt sind. Alles was wir haben ist ein2x2
.Im zweiten Diagramm (blau) lief es auch leicht. Außer diesmal stimmte sogar der zweite Umriss unten rechts auf allen Quadraten überein: Wir haben einen
3x3
Block. Der Versuch, einen4x4
Fehler zu machen, schlägt fehl, da nicht alle Felder gefüllt sind.Im dritten Diagramm (lila) haben wir nichts. Wir hatten keine ausgefüllten Quadrate mehr, um die Ecke zu platzieren, bevor wir eines fanden, das einen Umriss unten rechts hat.
Im vierten Diagramm (gelb) funktionierten die Dinge nach einigen Versuchen. Die ersten drei Quadrate, in die wir Ecken einfügen wollten, hatten keinen Umriss unten rechts. Der vierte tat es jedoch. Dies gibt uns eine
2x2
. Der Versuch, eine zu erhalten,3x3
schlägt wie im ersten Diagramm fehl.Wie würden Sie das umsetzen?
Wenn Ihre Ecke ist
grid[0][0]
,n
besteht der Umriss unten rechts aus Quadraten, in denen eine oder beide Koordinaten liegenn
.Dies verallgemeinert Folgendes: Wenn sich Ihre Ecke in befindet
grid[x][y]
, ist der Umriss unten rechts eine Vereinigung dieser Quadratsätze:grid[x+n][yVariable]
, woy <= yVariable < y+n
(die rechte Seite)grid[xVariable][y+n]
, wox <= xVariable < x+n
(die Unterseite)grid[x+n][y+n]
(die untere rechte Ecke)Es sollte einfach sein, diese zu durchlaufen. Wenn Sie ein Quad haben, geben die Koordinaten der oberen rechten und unteren rechten Ecke an, wo es sich befindet.
Das funktioniert aber nur für Quadrate!
Verallgemeinern auf Rechtecke
Diese drei oben genannten Aufzählungspunkte können auch einzeln überprüft werden:
Dies bedeutet natürlich, dass sich aus jedem Überprüfungszustand 3 (anstelle von 1) mögliche weitere Zustände entwickeln können:
Jeder dieser drei Zustände kann durch ein ähnliches Verfahren weiter auf bis zu drei Zustände erweitert werden.
Ihr Code könnte die beiden anderen Zustände für später speichern und den ersten bis zur Erschöpfung verarbeiten, bevor Sie mit dem nächsten fortfahren. Am Ende wäre das Quad mit der größten Fläche die Ausgabe. (Dies ist in der Computerfachsprache ein Depth-First - Traversal eines trinären Baum.)
quelle
y <= yVariable < y+n
! Ich werde das beheben!Nur als Folge - ich habe schließlich ein paar Lösungen codiert, von denen eine im Grunde eine Javascript-Implementierung des in diesem Artikel über Dr. Dobbs beschriebenen Maximal Rectangle-Algorithmus war . Mein Problem schien im Grunde das Problem zu sein, das dieser Algorithmus auf den Punkt bringen soll!
Ich habe ein kurzes Blog-Stück darüber geschrieben, wie ich es in Javascript gemacht habe, und den daraus resultierenden Code, der hier in meinem Blog verfügbar ist .
quelle