Ich habe derzeit ein einfaches Tetris-ähnliches Spiel und bin auf ein Problem gestoßen, das ich nicht lösen kann.
Im Gegensatz zu Tetris, wo es eine einzelne fallende Form gibt, habe ich mehrere, möglicherweise ineinandergreifende Formen, die fallen müssen. Ich muss ihre endgültigen Positionen berechnen. Folgendes berücksichtigen:
Um die endgültige Position der grünen Form zu berechnen, scanne ich einfach nach jedem Quadrat, bis ich auf ein anderes Quadrat oder die Kante des Bretts stoße. Erledigt
Für mehrere einfache Formen arbeite ich mich nach oben. Somit muss sich das Rot nicht bewegen, das Orange sinkt um eins, das Grün um drei. Erledigt
Ich weiß nicht, wie ich die ineinandergreifenden grünen und roten Formen behandeln soll. Mit der Logik von # 2 würden wir am Ende in der Luft "stecken bleiben". Wenn ich nach der grünen Form scanne, stoße ich auf die rote und bewege mich daher nicht und umgekehrt nach der roten. Die Lösung könnte darin bestehen, die beiden Formen als eine zu behandeln.
Ähnlich wie bei # 3 könnte es mir in diesem Szenario auch gelingen, die Objekte als eins zu behandeln.
Im Gegensatz zu # 3 und # 4 konnte ich die Form nicht als eine behandeln, da die orange Form ein Quadrat zu hoch schweben würde ...
Eine weitere Variante von Problem Nr. 6.
Es könnte andere Szenarien geben, in denen ich viele verschiedene Formen habe, die sich in immer komplexeren Szenarien verweben, aber ich denke, dass das Obige die grundlegendsten Teile des Problems abdeckt.
Ich habe das Gefühl, dass es eine elegante Lösung gibt, die ich noch nicht gefunden / mir ausgedacht habe, und wäre für jeden Einblick, jede Idee oder jede Ressource sehr dankbar.
LÖSUNG
Die Lösung, die ich gefunden habe, ist in der Tat elegant. Basierend auf der Antwort von @ user35958 unten habe ich die folgende rekursive Funktion (Pseudocode) erstellt.
function stop(square1, square2){
// Skip if we're already stopped
if(square1.stopped){
return;
}
// Are we comparing squares?
if(!square2){
// We are NOT comparing squares, simply stop.
square1.stopped = true;
} else {
// Stop IF
// square1 is directly above square2
// square1 is connected to square2 (part of the same complex shape)
if(square1.x == square2.x && square1.y == (square2.y+1) || isConnected(square1, square2)){
square1.stopped = true;
}
}
// If we're now stopped, we must recurse to our neighbours
stop(square1, squareAbove);
stop(square1, squareBelow);
stop(square1, squareRight);
stop(square1, squareDown);
}
Animiertes GIF, das jeden Durchgang der Lösung zeigt
Zusammenfassen:
- Wenn wir ein Quadrat "stoppen", stoppen wir auch:
- JEDES Quadrat darüber. IMMER.
- Nachbarquadrat, mit dem wir verbunden sind (dh dieselbe Form).
- Wir stoppen die gesamte untere Reihe und die Funktion wiederholt sich durch die Quadrate.
- Wir wiederholen, bis alle Quadrate gestoppt sind.
- Dann animieren wir.