Saya mengerjakan game dengan peta yang menyerupai kunci dan teka-teki kunci . AI perlu menavigasi ke tujuan yang mungkin berada di belakang pintu merah yang terkunci, tetapi kunci merah mungkin di belakang pintu biru yang terkunci, dan seterusnya ...
Teka-teki ini mirip dengan penjara bawah tanah gaya Zelda, seperti gambar ini:
Untuk mencapai Goal, Anda harus mengalahkan Bos, yang mengharuskan Anda melewati pit, yang membutuhkan pengumpulan Bulu, yang membutuhkan pengumpulan Kunci
Penjara bawah tanah Zelda cenderung linier. Namun, saya perlu menyelesaikan masalah dalam kasus umum. Begitu:
- Tujuannya mungkin memerlukan salah satu dari serangkaian kunci. Jadi mungkin Anda perlu mendapatkan kunci merah atau biru. Atau mungkin ada pintu yang tidak terkunci sepanjang jalan!
- Mungkin ada beberapa pintu dan kunci sejenis. Misalnya mungkin ada beberapa kunci merah di peta, dan mengumpulkan satu akan memberikan akses ke semua pintu merah.
- Tujuannya mungkin tidak dapat diakses karena kunci yang tepat ada di balik pintu yang terkunci
Bagaimana saya melakukan penelusuran jalan di peta seperti itu? Seperti apa grafik pencarian?
Catatan: poin terakhir tentang mendeteksi tujuan yang tidak dapat diakses adalah penting; A *, misalnya, sangat tidak efisien jika tujuannya tidak dapat diakses. Saya ingin menangani ini secara efisien.
Asumsikan bahwa AI tahu di mana semuanya ada di peta.
sumber
Jawaban:
Pathfinding standar adalah Cukup Baik - negara Anda adalah lokasi Anda saat ini + inventaris Anda saat ini. "Memindahkan" adalah mengubah kamar atau mengubah inventaris. Tidak tercakup dalam jawaban ini, tetapi tidak terlalu banyak upaya tambahan, menulis heuristik yang baik untuk A * - itu benar-benar dapat mempercepat pencarian dengan lebih memilih untuk mengambil barang-barang daripada bergerak menjauh dari itu, lebih memilih untuk membuka kunci pintu di dekat target mencari lebih jauh, dll.
Jawaban ini telah mendapatkan banyak peningkatan sejak datang pertama dan memiliki demo, tetapi untuk solusi yang jauh lebih dioptimalkan dan khusus, Anda juga harus membaca jawaban "Melakukannya mundur jauh lebih cepat" /gamedev/ / a / 150155/2624
Bukti Javascript yang sepenuhnya operasional konsep di bawah ini. Maaf untuk jawabannya sebagai dump kode - Saya telah benar-benar menerapkan ini sebelum saya yakin itu adalah jawaban yang baik, tetapi tampaknya cukup fleksibel bagi saya.
Untuk memulai ketika memikirkan pathfinding, ingatlah bahwa hirarki algoritma pathfinding sederhana adalah:
Dalam kasus kami, hanya penyandian "keadaan" sebagai "lokasi + inventaris" dan "jarak" sebagai "perpindahan atau penggunaan item" memungkinkan kami untuk menggunakan Djikstra atau A * untuk menyelesaikan masalah kami.
Berikut adalah beberapa kode aktual yang menunjukkan level contoh Anda. Cuplikan pertama hanya untuk perbandingan - lompat ke bagian kedua jika Anda ingin melihat solusi akhir. Kami memulai dengan implementasi Djikstra yang menemukan jalan yang benar, tetapi kami mengabaikan semua hambatan dan kunci. (Cobalah, Anda bisa melihatnya hanya untuk garis finish, dari kamar 0 -> 2 -> 3-> 4-> 6-> 5)
Jadi, bagaimana kita menambahkan item dan kunci ke kode ini? Sederhana! alih-alih setiap "keadaan" memulai hanya nomor kamar, sekarang menjadi tupel ruangan dan status inventaris kami:
Transisi sekarang berubah dari tuple (biaya, kamar) menjadi tupel (biaya, status), sehingga dapat menyandikan "pindah ke kamar lain" dan "mengambil item"
akhirnya, kami membuat beberapa perubahan kecil yang berhubungan dengan tipe pada fungsi Djikstra (misalnya, masih cocok dengan nomor ruang tujuan alih-alih keadaan penuh), dan kami mendapatkan jawaban lengkap kami! Perhatikan hasil cetakan pertama pergi ke kamar 4 untuk mengambil kunci, kemudian pergi ke kamar 1 untuk mengambil bulu, kemudian pergi ke kamar 6, membunuh bos, lalu pergi ke kamar 5)
Secara teori, ini bekerja bahkan dengan BFS dan kami tidak memerlukan fungsi biaya untuk Djikstra, tetapi memiliki biaya memungkinkan kami untuk mengatakan "mengambil kunci itu mudah, tetapi melawan bos sangat sulit, dan kami lebih memilih mundur 100 langkah daripada melawan bos, jika kita punya pilihan ":
sumber
Mundur A * akan melakukan trik
Seperti dibahas dalam jawaban ini untuk pertanyaan tentang maju dan mundur pathfinding , merintis jalan mundur adalah solusi yang relatif sederhana untuk masalah ini. Ini bekerja sangat mirip dengan GOAP (Goal Oriented Action Planning), perencanaan solusi yang efisien sambil meminimalkan bertanya-tanya tanpa tujuan.
Di bagian bawah jawaban ini saya memiliki rincian tentang bagaimana menangani contoh yang Anda berikan.
Secara terperinci
Temukan dari tujuan ke awal. Jika, di pathfinding Anda, Anda menemukan pintu yang terkunci, Anda memiliki cabang baru ke pathfinding Anda yang berlanjut melalui pintu seolah-olah tidak terkunci, dengan cabang utama terus mencari jalan lain. Cabang yang terus melewati pintu seolah-olah tidak dikunci tidak lagi mencari agen AI - sekarang mencari kunci yang dapat digunakan untuk melewati pintu. Dengan A *, heuristik barunya adalah jarak ke kunci + jarak ke agen AI, bukan hanya jarak ke agen AI.
Jika cabang pintu terbuka menemukan kunci, maka terus mencari agen AI.
Solusi ini dibuat sedikit lebih rumit ketika ada beberapa kunci yang layak tersedia, tetapi Anda dapat melakukan percabangan yang sesuai. Karena cabang memiliki tujuan tetap, itu masih memungkinkan Anda menggunakan heuristik untuk mengoptimalkan pencarian jalan (A *), dan jalur yang mustahil semoga akan terpotong dengan cepat - jika tidak ada jalan di sekitar pintu yang terkunci, cabang yang tidak bisa melewati pintu kehabisan pilihan dengan cepat dan cabang yang melewati pintu dan mencari kunci terus sendiri.
Tentu saja, di mana ada berbagai pilihan yang tersedia (beberapa kunci, item lain untuk menghindari pintu, jalan panjang di sekitar pintu), banyak cabang akan dipertahankan, yang mempengaruhi kinerja. Tetapi Anda juga akan menemukan opsi tercepat, dan dapat menggunakannya.
Beraksi
Dalam contoh spesifik Anda, merintis jalan dari Sasaran ke Mulai:
Kami dengan cepat menemukan pintu bos. Cabang A berlanjut melalui pintu, sekarang mencari bos untuk bertarung. Cabang B tetap tersangkut di ruangan, dan akan segera kedaluwarsa ketika menemukan tidak ada jalan keluar.
Cabang A menemukan bos dan sekarang sedang mencari Start, tetapi bertemu lubang.
Cabang A berlanjut di atas lubang, tetapi sekarang mencari bulu, dan akan membuat garis lebah ke arah bulu yang sesuai. Cabang C dibuat yang mencoba menemukan jalan di sekitar lubang, tetapi segera kedaluwarsa karena tidak bisa. Itu, atau akan diabaikan untuk sementara waktu, jika heuristik A * Anda menemukan bahwa Cabang A masih terlihat paling menjanjikan.
Cabang A menjumpai pintu yang terkunci, dan terus melalui pintu yang terkunci seolah-olah tidak dikunci, tetapi sekarang sedang mencari kuncinya. Cabang D terus melalui pintu yang terkunci juga, masih mencari bulu, tetapi kemudian akan mencari kuncinya. Ini karena kita tidak tahu apakah kita perlu menemukan kunci atau bulu terlebih dahulu, dan sejauh menyangkut pathfinding, Start bisa berada di sisi lain dari pintu ini. Cabang E mencoba menemukan jalan di sekitar pintu yang terkunci, dan gagal.
Cabang D dengan cepat menemukan bulu dan terus mencari kuncinya. Diperbolehkan melewati pintu yang terkunci lagi, karena masih mencari kuncinya (dan itu bekerja dengan cara mundur dalam waktu). Tetapi begitu ia memiliki kunci, ia tidak akan dapat melewati pintu yang terkunci (karena ia tidak dapat melewati pintu yang terkunci sebelum ia menemukan kunci itu).
Cabang A dan D terus bersaing, tetapi ketika Cabang A mencapai kunci, ia mencari bulu, dan ia akan gagal mencapai bulu karena harus melewati pintu yang terkunci lagi. Cabang D, di sisi lain, setelah mencapai kunci, mengalihkan perhatiannya ke Start, dan menemukannya tanpa kerumitan.
Cabang D menang. Ia telah menemukan jalan sebaliknya. Jalur terakhir adalah: Mulai -> Kunci -> Bulu -> Bos -> Sasaran.
sumber
Sunting : Ini ditulis dari sudut pandang AI yang keluar untuk menjelajahi dan menemukan tujuan, dan tidak tahu lokasi kunci, kunci, atau tujuan sebelumnya.
Pertama, anggaplah bahwa AI memiliki semacam tujuan keseluruhan. Misalnya ,, "Temukan bos" dalam contoh Anda. Ya, Anda ingin mengalahkannya, tetapi sebenarnya ini tentang menemukannya. Anggaplah ia tidak tahu bagaimana mencapai tujuan, hanya saja itu ada. Dan itu akan mengetahuinya ketika menemukannya. Begitu tujuan tercapai, AI dapat berhenti bekerja untuk menyelesaikan masalah.
Juga, saya akan menggunakan istilah umum "kunci" dan "kunci" di sini, bahkan jika itu mungkin jurang dan bulu. Yaitu, bulu "membuka" jurang "kunci".
Pendekatan Solusi
Sepertinya Anda akan mulai pertama hanya dengan AI yang pada dasarnya adalah penjelajah labirin (jika Anda menganggap peta Anda sebagai labirin). Menjelajahi dan memetakan semua tempat yang bisa dituju akan menjadi fokus utama AI. Itu bisa didasarkan murni pada sesuatu yang sederhana seperti, "Selalu pergi ke jalan terdekat yang pernah saya lihat tetapi belum dikunjungi."
Namun, beberapa aturan akan muncul saat menjelajah yang mungkin mengubah prioritas ...
Catatan tentang poin terakhir itu. Jika harus memilih antara akan memeriksa area yang belum dijelajahi yang terlihat sebelumnya (tetapi tidak dikunjungi) versus area yang belum dijelajahi di belakang jalur yang baru dibuka, itu harus menjadikan jalur yang baru dibuka menjadi prioritas. Itu mungkin di mana ada kunci baru (atau kunci) yang akan berguna. Ini mengasumsikan jalan yang terkunci mungkin tidak akan menjadi jalan buntu yang sia-sia.
Memperluas Ide dengan Kunci "Dapat Dikunci"
Anda dapat berpotensi memiliki kunci yang tidak dapat diambil tanpa kunci lain. Atau kunci yang terkunci. Jika Anda tahu Gua Kolosal lama Anda, Anda perlu memiliki sangkar burung untuk menangkap burung - yang Anda butuhkan nanti untuk seekor ular. Jadi Anda "membuka" burung dengan kandang (yang tidak menghalangi jalan tetapi tidak dapat diambil tanpa kandang), dan kemudian "membuka" ular (yang menghalangi jalan Anda) dengan burung.
Jadi menambahkan beberapa aturan ...
Saya bahkan tidak akan membahas semuanya tentang bagaimana membawa kunci tertentu dapat meniadakan efek kunci lain (Gua Colossal, batang menakut-nakuti burung dan harus dijatuhkan sebelum burung dapat diambil, tetapi diperlukan kemudian untuk membuat jembatan ajaib) .
sumber