Perintah Memerintahkan Arsitektur Benteng Kerdil

21

Apa cara yang paling elegan untuk menerapkan sistem pemesanan perintah untuk AI? misalnya di benteng katai ketika Anda menandai area hutan untuk memotong kayu, maka katai akan melakukan urutan berikut:

  1. Pergi ke pohon
  2. Potong pohonnya
  3. Kirimkan kayu ke stockpile
  4. Pergi ke pohon lain
  5. dan seterusnya..

Saya sudah memiliki perintah stack no. 1 yang beralih dari status siaga ke mencapai ubin tujuan pohon.

Yang saya takutkan adalah bagaimana ini akan berantakan ketika saya membuat lebih banyak pesanan seperti ini:

Membangun sebuah rumah

  1. Pergi ke stockpile
  2. bawa kayu ke area konstruksi
  3. kembali ke persediaan
  4. Bawa batu ke area konstruksi
  5. menghidupkan sprite bangunan

Penanaman

  1. Pergi ke stockpile
  2. bawa benih ke lahan pertanian

Pembuatan bir

  1. Pergi ke stockpile
  2. Bawa tanaman diam
  3. menghidupkan sprite pembuatan bir

Jadi pertanyaan saya adalah, bagaimana cara menerapkan sistem pemesanan perintah seperti benteng kerdil dan menghindari kode spageti pada saat yang sama? apakah ada struktur data yang perlu saya pelajari? Apakah saya perlu meletakkan urutan perintah pada file xml yang terpisah?

Jed T.
sumber
1
Benteng Kerdil sebenarnya tidak memiliki sistem seperti itu. Kurcaci ditugaskan satu tugas pada satu waktu, dan kurcaci yang menganggur akan mencari sesuatu untuk dilakukan. ("Hei, ada pohon yang ditandai untuk memotong - aku harus memotongnya!" / "Hei, ada beberapa kayu yang tidak ada dalam tumpukan - aku harus membawanya ke satu!")
user253751
1
Kurcaci tidak ditugaskan apa pun oleh pemain, tetapi "ditugaskan" tugas oleh sistem, yang persis seperti yang dijelaskan Jed T. di atas. Buat pesanan, dan sistem menetapkan tugas komponen individu untuk memenuhi pesanan itu.
Attackfarm
2
Perhatikan bahwa ini disebut Alokasi Tugas dan Penjadwalan, dan dipelajari secara luas di beberapa bidang teknik. Anda akan menemukan banyak makalah yang membahas masalah ini, yang mungkin menarik.
TonioElGringo
@Attackfarm Sistem tidak memutuskan semua tugas di muka; juga tidak menugaskan banyak tugas ke katai yang sama. Satu tugas pada awalnya ditugaskan, dan ketika selesai, itu memiliki konsekuensi membuat tugas lain tersedia.
user253751
2
Ini kedengarannya seperti kasus penggunaan yang sangat baik untuk Perencanaan Tindakan yang Berorientasi Tujuan
Bermasalah

Jawaban:

27

Pada awalnya Anda melihat bahwa perintah Anda dalam bentuk daftar , jadi insting pertama Anda mungkin untuk membuat ulang struktur itu, dan setiap kurcaci akan menjalankan daftar itu secara berurutan. Yang saya sarankan adalah memecah daftar menjadi beberapa langkah , dengan setiap langkah memiliki prasyarat , dan kemudian Anda menjalankan seluruh perintah secara terbalik . Izinkan saya menunjukkan dengan sebuah contoh:

Memotong kayu

  • Apakah saya membawa kayu, dan menimbun? Ya : jatuhkan
  • Apakah saya membawa kayu? Ya : pergilah ke stockpile
  • Apakah saya di pohon? Ya : potong itu
  • Tidak untuk semua di atas : pergi ke pohon

Kelebihan dari ini adalah:

  • Sangat mudah diimplementasikan
  • Fleksibel - Anda dapat dengan bebas menguraikan daftar ini, menambah item, menghapus item, menggabungkan item
  • Tanpa status - Anda dapat menjalankan daftar ini dari atas untuk katai apa pun di negara mana pun, dan katai itu akan Melakukan Hal yang Benar TM

Kekurangan:

  • Sangat mudah terjebak dalam lingkaran, karena tidak ada keadaan dan tidak ada kesadaran terjebak

Secara logis, Anda dapat mewakili perintah ini sebagai diagram alur, yang dijalankan dari atas setiap kali, dan apa yang Anda lakukan tergantung pada apakah Anda menjawab ya / tidak pada setiap langkah. Apakah Anda menerapkan ini dalam kode atau dalam file eksternal seperti XML, itu terserah Anda.

congusbongus
sumber
2
Ini juga memiliki keuntungan dari membiarkan status mengabaikan perintah, Apakah saya lapar? jika ya tinggalkan semuanya dan tetapkan tugas untuk "makan" dengan makan yang mirip dengan pekerjaan mengangkut kayu.
ratchet freak
7
@ scratchetfreak "Saya tahu keselamatan benteng saya bergantung pada saya melawan monster ini sehingga tidak menyerang warga sipil, tapi astaga, perut saya baru saja menggeram!" Cobalah untuk tidak membuatnya terlalu seperti DF dalam hal itu: P
Kolonel Thirty Two
Saya pikir ini menyerupai apa yang menggunakan (atau setidaknya digunakan) yang memungkinkan artefak disadap planepacked (ini adalah karena item terlarang, yang menyebabkan perulangan kata)
Destrictor
3
@ColonelThirtyTwo Di mana funitu? ;)
Lasse
Saya sangat menyarankan untuk tidak menggunakan perencanaan tindakan simbolis deklaratif untuk ini. Pada dasarnya tidak mungkin untuk melakukan debug, dan perilaku yang tidak diinginkan dapat dengan mudah muncul. Jauh lebih mudah untuk meng-hardcode urutan tindakan untuk setiap tugas dengan cara prosedural.
mklingen
10

Jika Anda dapat membuat urutan yang cukup umum, tidak ada banyak kode spageti.

Dalam hal pengiriman misalnya: WorkTask beroperasi dengan WorkPlan. Workplan mengatakan unit sumber daya apa yang harus dipilih, dari rumah seperti apa, menggunakan animasi jalan mana, menggunakan animasi kerja mana, waktu bekerja dan semua detail lainnya. Jadi pada akhirnya WorkTask mungkin terlihat seperti:

  1. Temukan% resource1% di peta
  2. Pergi ke lokasi itu menggunakan% animation_1%
  3. Bekerja di tempat menggunakan% animation_2% untuk% waktu%
  4. Ambil% req_resource1% dalam% req_count1% hitung
  5. Buka% home% menggunakan% animasi%
  6. Mulai% animation_6% di dalam untuk% time_2%
  7. dll ..

Kami berhasil menggunakan pendekatan yang dijelaskan. Kami memiliki ~ 15 tugas dalam game kami. Beberapa hal penting:

  • Tugas memberikan aksi unit (pergi ke sana, masuk, keluar, ke sini, tinggal, bekerja, pergi)
  • Tindakan diakhiri dengan status Selesai atau dibatalkan dan meneruskannya ke Tugas
  • Semuanya hardcoded (tidak perlu menulis parser, metode antarmuka, kompabilitas mundur)
  • Setiap tugas mengimplementasikan kelas Tugas abstrak hanya dengan beberapa metode umum (buat, jalankan, simpan, muat)
  • Umumnya satu tugas per modul, tetapi tugas serupa dalam satu modul
  • Tugas yang sangat mirip berada dalam satu kelas dan diperintah oleh beberapa IF (dikirim ke rumah atau dikirim ke unit)
  • Setiap tugas membutuhkan penguncian dan pembukaan sumber daya yang tepat (jika unit mati pada langkah APAPUN, sumber daya yang dikunci harus dilepaskan)
Kromster berkata mendukung Monica
sumber
2
Ini adalah sistem yang kami gunakan dalam permainan seperti benteng kerdil kami. Tugas diselesaikan oleh pohon perilaku. Sumber daya dikunci oleh perilaku, dan dikunci oleh kegagalan. Ini jauh lebih kuat dan mudah untuk di-debug daripada pendekatan perencanaan tindakan yang dijelaskan oleh jawaban teratas
mklingen
5

Jadi ini pada dasarnya adalah masalah penyortiran topografi.

Anda memiliki grafik, setiap node adalah tugas yang perlu dilakukan, dan beberapa node tergantung pada beberapa node lain (ini diwakili oleh tepi dalam grafik dari tergantung node ke node itu tergantung pada). Anda ingin melakukan semua tugas, jadi Anda perlu menghasilkan BEBERAPA pemesanan node yang topografis OK, (node ​​tergantung adalah setelah node mereka bergantung pada).

Sekarang, ada banyak urutan seperti itu biasanya (karena beberapa node tidak memiliki ketergantungan dan dapat diletakkan di mana saja, dan beberapa node memiliki ketergantungan yang sama dan tidak tergantung satu sama lain sehingga mereka dapat berada dalam urutan antara mereka sendiri, dan setiap node dapat diletakkan di sembarang tempat setelah dependensi selesai, dan sebelum node bergantung padanya selesai).

Mungkin juga tidak ada cara untuk menyortir grafik secara topografi - ini terjadi ketika ada siklus dalam grafik (Anda tidak punya kayu, untuk mendapatkan kayu Anda perlu memotong pohon, memotong pohon Anda perlu kapak, untuk membuat kapak Anda butuh kayu). Dalam kasus seperti itu, algoritma mungkin harus menunjukkan kepada pemain bahwa tugas-tugas ini tidak dapat dilakukan.

Anda juga dapat menambahkan prioritas ke node, dan tugasnya mungkin untuk menemukan pemesanan tersebut, di antara semua pemesanan yang memenuhi dependensi, yang memiliki prioritas lebih besar node dilakukan terlebih dahulu.

Anda juga dapat menambahkan tugas recuring - cara termudah mungkin adalah dengan menambahkan tugas dengan timeout lagi ke grafik setiap kali selesai.

Sekarang bagaimana mengatasinya - http://en.wikipedia.org/wiki/Topological_sorting

Sebastian Pidek
sumber