Dün gece, oyunumdaki bir köylü NPC'sine biraz daha "zeki" diyaloglar yazayım dedim. Tüm konuşma dallarını temiz bir JSON dosyasında yapılandırdım. Her diyalog nodu, kendi `id`sini, metnini ve gidebileceği sonraki diyalog `id`lerini içeren bir array tutuyordu. Mantık basit gibiydi: recursive (özyinelemeli) bir fonksiyonla ağacı gez, player'ın seçimine göre bir sonraki nodu bul, ekrana bas. Ne güzel.
İlk testler harika gidiyordu. Ta ki, köylüye "Hava nasıl?" diye sorana kadar. Cevap verdikten sonra, aynı soruya geri dönmem gerekiyordu ama ekran dondu. Konsola baktığımda o meşhur, yürek burkan hatayı gördüm. Kafayı yiyecektim! Hemen debug moda geçtim.
JavaScript:
function navigateDialog(nodeId) {
let currentNode = dialogData[nodeId];
displayText(currentNode.text);
// ... sonraki seçenekleri göster
let choice = getPlayerChoice();
navigateDialog(choice.nextNodeId); // İŞTE BURASI!
}
Sorun şuydu: JSON'ımı kontrol ettiğimde, masum bir yazım hatası yapmışım. Bir diyalog nodunun `nextNodeId` array'inde, yanlışlıkla kendi `id`sini işaret eden bir değer vardı. Yani sistem, "A" nodundan "A" noduna giden bir sonsuz döngüye girdi ve recursive fonksiyonumuz kısa sürede call stack'i doldurup patladı. StackOverflow sitesinde bile böyle saçma bir bug için arama yapmak zorunda kaldım, şaka gibi.
Çözüm aslında çok basitti. Graph traversal'da cycle (döngü) tespiti gibi, daha önce ziyaret ettiğim nodları takip etmem gerekiyordu. Fonksiyona basit bir Set parametresi ekledim.
JavaScript:
function navigateDialog(nodeId, visited = new Set()) {
if (visited.has(nodeId)) {
console.error("Döngü tespit edildi!", nodeId);
return fallbackDialog();
}
visited.add(nodeId);
// ... geri kalan mantık
}
Bu küçük kontrol, recursive çağrının sonsuza gitmesini engelledi. Meğerse sorun, JSON veri yapımda değil, onu işleyen algoritmanın saf halindeymiş.
Siz de böyle "kendi kendine referans veren" veya beklenmedik bir döngü yaratan veri yapıları yüzünden stack overflow yediniz mi? Özellikle recursive fonksiyonlarda başka nasıl önlemler alıyorsunuz? Yoksa iterative (döngülü) çözümlere mi geçiş yapmak daha mı güvenli?