…bir oyun haritasını grafa çevirebilecek, A*’ı yazıp ızgarada çalıştırabilecek, doğru sezgiyi seçebilecek, bulunan yolu yumuşatıp steering ile izletebilecek ve büyük haritalarda yol bulmayı hızlandırmanın yollarını tanıyacaksınız.
Ne bekliyorsunuz? Ne olursa oyunu “bozuk” bulursunuz?
Yeşil = gerekli · kesikli = faydalı ama şart değil. Tıklayınca ilgili sunuma gider.
| pathfinding | yol bulma | Başlangıçtan hedefe engellere çarpmadan giden (en ucuz) yolu bulmak |
| node · edge · cost | düğüm · kenar · maliyet | Gidilebilir yer · iki yer arası geçiş · geçişin “pahası” (mesafe, arazi) |
| g · h · f | — | g: başlangıçtan buraya gerçek maliyet · h: buradan hedefe tahmin · f = g + h |
| heuristic · admissible | sezgi · kabul edilebilir | Kalan maliyet tahmini · tahminin asla fazla olmaması (en kısa yolu garanti eder) |
| open / closed list | açık / kapalı liste | Keşfedilmiş ama işlenmemiş düğümler · işi bitmiş düğümler |
| Manhattan · octile · Euclidean | — | 4 yönlü · 8 yönlü · her açıda mesafe tahminleri |
| path smoothing / string pulling | yol yumuşatma / ip germe | Izgara yolunun gereksiz köşelerini kaldırmak |
| hierarchical pathfinding | hiyerarşik yol bulma | Önce kaba haritada (odalar), sonra ayrıntıda arama |
| JPS · flow field | sıçrama noktası araması · akış alanı | Izgarada simetrik yolları atlayan hızlı A* · binlerce birim için yön haritası |
Bedeli: çok düğüm, “basamaklı” yollar.
Bedeli: elle bakım; noktaların dışındaki alanı “bilmez”.
Bedeli: üretmesi karmaşık (motorlar yapar).
A* üçünde de aynı çalışır: sadece “komşular kim, geçiş maliyeti ne?” sorusunun cevabı değişir. Bu sunumda ızgara kullanıyoruz çünkü görmesi en kolayı.
Yola çıktınız ve bir kavşaktasınız. Hangi yöne sapacağınıza karar verirken iki şeye bakarsınız:
A* her adımda, bildiği bütün kavşaklar içinden f’si en küçük olanı seçip oradan devam eder. Hepsi bu.
| algoritma | öncelik | en kısa yolu garanti eder mi? | hız |
|---|---|---|---|
| BFS | önce keşfedilen (kuyruk) | Sadece bütün adımlar eşit maliyetliyse | yavaş: her yöne dalga |
| Dijkstra | en küçük g | Evet (negatif maliyet yoksa) | yavaş: her yöne, maliyete göre |
| Greedy best-first | en küçük h | Hayır: “hedefe en yakın görünen” yolu seçer | çok hızlı ama aptal olabilir |
| A* | en küçük f = g + h | Evet (h kabul edilebilirse) | hızlı ve doğru |
Dördü de aynı kod: bir öncelik kuyruğu, komşulara bak, daha iyi yol bulursan güncelle. Sadece kuyruğun “sıralama ölçütü” değişir.
Dördü de aynı döngüyü çalıştırır; tek fark bir sonraki kareyi neye göre seçtikleri:
A* Pathfinding (E01: algorithm explanation)
Sebastian Lague · 11 dk 38 sn · YouTube’da aç
Elle yaptığımız g, h, f hesabının ızgara üzerinde kare kare, çok temiz çizimlerle anlatımı. Açık ve kapalı listeler, komşu maliyetleri (10 ve 14) ve yolun geriye izlenmesi.
Aynı konuyu başka bir anlatımla, kendi elinizle oynayarak görmek çok işe yarar. Kartlar yeni sekmede açılır; çoğu İngilizce ama görsel ve etkileşimli.
h, bir kareden hedefe “daha ne kadar yol kaldı?” sorusuna verilen tahmindir; A* bunu yolu henüz bilmeden, her kare için hesaplar. Tahminin iyisi, gerçek kalan yola eşit olanıdır. Gerçekten az tahmin etmek güvenlidir ama A* gereğinden çok kareye bakar; fazla tahmin etmek A*’ı hızlandırır ama bulduğu yol en kısa olmayabilir.
yeşil: 8 yönde gerçek en kısa yol = 2 çapraz + 2 düz = 2·1,41 + 2 = 4,83
turuncu: yalnızca 4 yönde gerçek en kısa yol = 4 + 2 = 6
mor: kuş uçuşu = √(4² + 2²) = 4,47
| sezgi | formül | bu örnekte h | 8 yönlü ızgarada (gerçek 4,83) | 4 yönlü ızgarada (gerçek 6) |
|---|---|---|---|---|
| Manhattan | dx + dy | 6 | fazla ✗ yol yanlış olabilir | tam ✓ |
| Octile | max + 0,41·min | 4,83 | tam ✓ | az doğru, biraz yavaş |
| Chebyshev | max(dx, dy) | 4 | az (çapraz da 1 sayılıyorsa tam) | az |
| Öklid | √(dx² + dy²) | 4,47 | az | az doğru ama en yavaşı |
f = g + w · h, w > 1. Arama hedefe daha aç gözlü koşar: çok daha az düğüm.Elle izlemesi için iki slayt önceki “Elle A*” demosuna bakın.
heapq, C# PriorityQueue (.NET 6+; Unity’de yoksa kendi yığınınız), JS’de kendi yığınınız. Öncelik Kuyrukları sunumundaki ikili yığın.edgeTo.“Kuyrukta aynı düğüm iki kez olabilir mi?” Evet: basit uygulamalarda düğümü güncellemek yerine yeniden eklenir; çıkarken “zaten kapalıysa atla” denir (tembel silme). Kod bunu yapıyor.
| heapq.heappush / heappop | yığın | En küçük öncelikli elemanı O(log n)’de verir |
| yield | üreteç | Fonksiyon bir liste döndürmek yerine elemanları tek tek “verir”; for döngüsüyle kullanılır |
| g.get(k, math.inf) · TryGetValue | güvenli okuma | Hiç görülmemiş düğüm için “sonsuz” varsay |
| path[::-1] | ters çevirme | Hedeften başlangıca toplanan yolu başlangıçtan hedefe çevirir |
| Vector2Int · Dictionary | Unity tam sayılı vektör · sözlük | Izgara koordinatı ve anahtar → değer tablosu |
| grid[ny]?.[nx] | isteğe bağlı zincirleme | Satır yoksa hata vermeden undefined |
| a ?? b | boşsa varsayılan | a undefined/null ise b |
A*’ın tamamı bu döngüdür. Üç tablo: open (sırada bekleyenler), g (buraya en ucuz maliyet), cameFrom (buraya nereden geldim). heuristic’i 0 yaparsanız Dijkstra olur.
▶ Eksiksiz örneği aç — yaklaşık 110 satır: fareyle duvar çizin, sarı ajan farenin olduğu kareye yol bulup yürüsün. Açık mavi kareler A*’ın baktığı yerler.
Deneyin:
h) tam olarak budur. İpucu: Math.abs.path.reverse()).max + (√2 − 1)·min. Sağda üç harita sırayla aranıyor; sizin sezginizle A*’ın genişlettiği düğüm sayısını ve yolun en kısa olup olmadığını izleyin. Sonra deney: 3 * octile yapın; düğüm azalır ama yol hâlâ en kısa mı?g + h koyuyorsunuz ama çekince g’ye ihtiyacınız var; best[(x, y)]’den okuyun. Testlerde bataklıkta dolaşmanın daha ucuz olduğu, yolun olmadığı ve başlangıç = hedef olan ızgaralar var.Patrick Wyatt’ın (Blizzard) 2013 blog yazısından:
Kırmızı: A*’ın ızgara yolu (45° basamaklı). Mor: “ip germe” (string pulling): görüş hattı olan en uzak noktaya düz git. Sarı ajan yolu steering ile izler (Y7). Renkli kareler A*’ın baktığı yerler: mavi = başlangıca yakın, yeşil = uzak; açık sarı = sırada bekleyen; beyaz = hiç bakılmadı.
Steve Rabin ve Nathan Sturtevant (Game AI Pro, 17. bölüm): DigiPen Teknoloji Enstitüsü’nde giriş YZ dersinin ilk ödevlerinden biri sabit bir ızgarada A* yazmak. Ek puan için “en hızlı A*” yarışması yapılıyor. Yıllar içinde yüzlerce öğrenciden çıkan sonuç:
| aynı haritada süre | |
|---|---|
| en hızlılar | ~200 µs |
| ortalama | ~2.500 µs |
| en yavaşlar | 20.000 µs’den fazla |
Aynı algoritma, aynı sonuç; arada 100 kat. “Nerede olurdunuz?”
Ve “kötü fikir”: on aramayı aynı anda yarım yarım yürütmek; birini bitirip sonrakine geçmek genelde daha hızlı.
| ad | platform | ne yapar / sınırları | nasıl eklenir |
|---|---|---|---|
| A* Pathfinding Project | Unity · ücretsiz + Pro | Aron Granberg’in yaygın eklentisi: ızgara, navmesh, nokta grafı; yol yumuşatma, çok iş parçacıklı arama, RVO kaçınması (Pro). Unity NavMesh’ten esnek. | Asset Store ya da sitesinden UnityPackage |
| Godot AStarGrid2D / AStar2D | Godot 4 · yerleşik | Izgara için hazır A* (çapraz kuralları, sezgi seçimi, ağırlıklı hücreler); AStar2D/3D kendi nokta grafınız için. | Kodda AStarGrid2D.new() |
| Unreal Navigation System | Unreal · yerleşik | Recast/Detour tabanlı navmesh + A*; AI MoveTo ile hazır. Izgara oyunları için kendi A*’ınızı yazarsınız. | Haritaya NavMeshBoundsVolume |
| Recast & Detour | C++ · açık kaynak | Unreal ve birçok motorun kullandığı navmesh üretici + yol bulucu (Y9). | CMake |
| PathFinding.js | JavaScript · açık kaynak | Izgarada A*, Dijkstra, BFS, JPS, iki yönlü arama; görsel demo sayfası ünlü. | npm install pathfinding |
| python-pathfinding | Python · açık kaynak | Pygame projeleri için ızgara A*, Dijkstra, JPS vb. | pip install pathfinding |
| NetworkX | Python · açık kaynak | Genel graf kütüphanesi; nx.astar_path(G, a, b, heuristic). Prototip ve analiz için. | pip install networkx |
| Moving AI benchmarks | veri seti | Gerçek oyunlardan (Dragon Age, StarCraft vb.) çıkarılmış haritalar ve test senaryoları: kendi A*’ınızı ölçmek için. | İndir |
Godot örneğinde dil GDScript; renklendirme için Python sözdizimi kullanılıyor. Sürüm farklarına dikkat: yukarıdaki API’ler Godot 4.2+, A* Pathfinding Project 4.x/5.x içindir.
“Unity 6, C#. 2B ızgara (bool[,] walkable, float[,] cost) için A* yaz: 8 yön, köşe kesme yok, octile sezgisi, kendi ikili yığınını kullan (PriorityQueue kullanma). Ulaşılamaz hedef için önceden flood fill ile bölge kimlikleri hesapla ve farklı bölgedeyse hedefe en yakın ulaşılabilir hücreyi hedef yap. Sonucu string pulling ile yumuşat (Bresenham görüş testi). Aramayı coroutine’de kare başına en fazla 1 ms çalıştır. Açık/kapalı hücreleri ve yolu OnDrawGizmos ile çiz.”
Adı geçen oyunu tanımıyorsanız: oyuncuların kullandığı wiki sayfası ve oyunu kısaca gösteren bir video. ▶ video slaydın üstünde açılır (Esc ile kapanır); 🎯 işaretli bağlantılar doğrudan bu sunumdaki konuya gider.
A* Pathfinding (E01: algorithm explanation)
A* Pathfinding (E03: algorithm implementation)
A* (A Star) Search Algorithm
Pathfinding — Understanding A* (A star)
Path Planning — A* (A-Star)
The hidden beauty of the A* algorithmEtkileşimli: Red Blob Games — Introduction to A* (Amit Patel; muhtemelen internetteki en iyi A* anlatımı) · PathFinding.js görsel demo