Şu anda Tetris benzeri basit bir oyunum var ve çözemediğim bir sorunla karşılaştım.
Tek bir düşen şeklin olduğu Tetris'in aksine, düşmesi gereken çoklu, potansiyel olarak birbirine kenetlenen şekillerim var; Onların son konumlarını hesaplamam gerekiyor. Aşağıdakileri göz önünde bulundur:
Yeşil şeklin son konumunu hesaplamak için, başka bir kareye veya tahtanın kenarına çarpana kadar her kare için aşağı doğru tararım. Bitti
Birden çok, basit şekiller için tahta yukarı doğru çalışırım. Böylece kırmızının hareket etmesine gerek olmadığı bulunur, turuncu birer birer aşağı, yeşil üçte bir aşağı gider. Bitti
Kilitli yeşil ve kırmızı şekillerin nasıl tedavi edileceğini bilmiyorum. # 2 mantığını kullanarak sonunda havada yüzen "sıkışmış" olurdu. Eğer yeşil şekli aşağıya tararsam, kırmızı ile karşılaşırım ve bu nedenle hareket etmezim ve tersi kırmızı için. Çözüm, iki şekli tek olarak ele almak olabilir.
# 3'e benzer şekilde, bu senaryoda nesneleri bir olarak ele alarak da başarabilirim.
# 3 ve # 4'ün aksine, turuncu şekil bir kare çok yüksek yüzer gibi olacağı için şekli bir olarak ele alamadım ...
Sorun # 6'nın başka bir varyasyonu.
Giderek daha karmaşık senaryolarda iç içe geçen birçok şekle sahip olduğum başka senaryolar da olabilir, ancak bence yukarıdakiler sorunun en temel kısımlarını kapsıyor.
Henüz karşılaşmadığım / düşünmediğim ve herhangi bir görüş, fikir veya kaynakta minnettar olacağım zarif bir çözüm var gibi hissediyorum.
ÇÖZÜM
Geldiğim çözüm, @ user35958'in aşağıdaki cevabına dayanarak gerçekten zarif, aşağıdaki özyinelemeli işlevi (sahte kod) oluşturdum
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);
}
Çözümün her geçişini gösteren animasyonlu GIF
Özetle:
- Bir kareyi "durdururken", biz de duruyoruz:
- Üzerinde HERHANGİ BİR kare. HER ZAMAN.
- Bağlandığımız komşu kare (yani aynı şekil).
- Tüm alt satırı durdururuz ve fonksiyon kareler boyunca tekrarlanır.
- Tüm kareler durana kadar tekrarlıyoruz.
- Sonra canlandırıyoruz.