Al momento ho un semplice gioco simile a Tetris e ho riscontrato un problema che non posso risolvere.
A differenza di Tetris, dove esiste una singola forma che cade, ho forme multiple, potenzialmente ad incastro, che devono cadere; Devo calcolare le loro posizioni finali. Considera quanto segue:
Per calcolare la posizione finale della forma verde, eseguo semplicemente la scansione di ogni quadrato fino a quando non colpisco un altro quadrato o il bordo del tabellone. Fatto
Per forme multiple e semplici lavoro a modo mio sulla tavola. Quindi il rosso non ha bisogno di muoversi, l'arancione scende di uno, il verde di tre. Fatto
Non so come trattare le forme verdi e rosse interconnesse. Usando la logica del n. 2 finiremmo per "bloccarci" fluttuando a mezz'aria. Se cerco la forma verde verso il basso, incontro il rosso e quindi non mi muovo, e viceversa per il rosso. La soluzione potrebbe essere quella di trattare le due forme come una.
Simile al n. 3, in questo scenario sono riuscito anche a trattare gli oggetti come uno.
A differenza del n. 3 e del n. 4, non potevo considerare la forma come una poiché la forma arancione finiva per galleggiare di un quadrato troppo in alto ...
Un'altra variante del problema n. 6.
Potrebbero esserci altri scenari in cui ho molte forme che si intrecciano in scenari sempre più complessi, ma penso che quanto sopra copre le parti più fondamentali del problema.
Sento che esiste una soluzione elegante che devo ancora incontrare / pensare e che sarei molto grato a qualsiasi intuizione, idea o risorsa.
SOLUZIONE
La soluzione che ho trovato è davvero elegante, basata sulla risposta di @ user35958 di seguito, ho creato la seguente funzione ricorsiva (pseudo codice)
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);
}
GIF animata che mostra ogni passaggio della soluzione
Riassumere:
- Quando "fermiamo" un quadrato, ci fermiamo anche:
- QUALSIASI quadrato sopra di esso. SEMPRE.
- Quadrato vicino al quale siamo collegati (cioè la stessa forma).
- Interrompiamo l'intera riga inferiore e la funzione ricorre nei quadrati.
- Ripetiamo fino a quando tutti i quadrati non vengono fermati.
- Quindi animiamo.