Saat ini saya memiliki permainan sederhana seperti Tetris dan telah menemukan masalah yang tidak bisa saya selesaikan.
Tidak seperti Tetris di mana ada satu bentuk jatuh, saya memiliki beberapa bentuk yang berpotensi saling bertautan yang perlu jatuh; Saya perlu menghitung posisi akhir mereka. Pertimbangkan yang berikut ini:
Untuk menghitung posisi akhir dari bentuk hijau, saya cukup memindai ke bawah untuk setiap kotak sampai saya menekan kotak lain atau tepi papan. Selesai
Untuk beberapa bentuk sederhana saya bekerja dengan cara saya naik papan. Jadi merah ditemukan tidak perlu bergerak, oranye turun satu, hijau turun tiga. Selesai
Saya tidak tahu bagaimana memperlakukan bentuk hijau dan merah yang saling terkait. Menggunakan logika # 2 kita akan berakhir "terjebak" mengambang di udara. Jika saya memindai ke bawah untuk bentuk hijau, saya menemukan merah dan karenanya tidak bergerak, dan sebaliknya untuk merah. Solusinya mungkin memperlakukan dua bentuk sebagai satu.
Mirip dengan # 3, dalam skenario ini saya juga bisa berhasil dengan memperlakukan objek sebagai satu.
Tidak seperti # 3 dan # 4 saya tidak bisa memperlakukan bentuk sebagai satu karena bentuk oranye akan berakhir mengambang satu-persegi terlalu tinggi ...
Variasi lain dari masalah # 6.
Mungkin ada skenario lain di mana saya memiliki banyak bentuk yang terjalin dalam skenario yang lebih kompleks, tetapi saya pikir di atas mencakup bagian paling mendasar dari masalah.
Saya merasa ada solusi elegan yang belum saya temui / pikirkan dan akan sangat berterima kasih atas wawasan, ide, atau sumber daya apa pun.
LARUTAN
Solusi yang saya buat memang elegan, berdasarkan jawaban @ user35958 di bawah ini, saya telah membuat fungsi rekursif berikut (kode semu)
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 animasi yang menunjukkan setiap celah solusi
Untuk meringkas:
- Saat "menghentikan" kotak, kami juga berhenti:
- SETIAP persegi di atasnya. SELALU.
- Tetangga tetangga tempat kita terhubung (yaitu bentuk yang sama).
- Kami menghentikan seluruh baris bawah, dan fungsinya berulang melalui kotak.
- Kami ulangi sampai semua kotak dihentikan.
- Lalu kita hidup.