Kiến trúc đặt hàng lệnh của pháo đài lùn


21

Cách thanh lịch nhất để thực hiện một hệ thống đặt hàng lệnh cho AI là gì? ví dụ trong pháo đài lùn khi bạn đánh dấu một khu vực có rừng để chặt gỗ, những người lùn sau đó sẽ thực hiện theo trình tự sau:

  1. Đi đến cái cây
  2. Chặt cây
  3. Cung cấp gỗ cho kho
  4. Đi đến cây khác
  5. và v.v.

Tôi đã có một lệnh stack làm việc không. 1 đi từ trạng thái nhàn rỗi để đến ô đích của cây.

Điều tôi sợ là làm thế nào điều này sẽ trở nên lộn xộn khi tôi tạo ra nhiều đơn hàng như thế này:

Xây nhà

  1. Đi dự trữ
  2. mang gỗ đến khu vực thi công
  3. quay trở lại kho
  4. Mang đá đến khu vực thi công
  5. animate xây dựng sprite

Trồng cây

  1. Đi dự trữ
  2. mang hạt giống đến lô đất trang trại

Sản xuất bia

  1. Đi dự trữ
  2. Mang cây đến
  3. animate ủ sprite

Vì vậy, câu hỏi của tôi là, làm thế nào để tôi thực hiện một hệ thống đặt hàng lệnh như pháo đài lùn và tránh mã spaghetti cùng một lúc? Có cấu trúc dữ liệu nào mà tôi cần nghiên cứu không? Tôi có cần đặt chuỗi lệnh trên một tệp xml riêng không?


1
Pháo đài lùn thực sự không có một hệ thống như vậy. Người lùn được giao một nhiệm vụ tại một thời điểm và những người lùn nhàn rỗi sẽ tìm kiếm một cái gì đó để làm. ( "Hey, có một cây được đánh dấu để cắt - Tôi nên chặt nó!" / "Này, có một số gỗ không trong một kho dự trữ - Tôi nên mang nó đến một!")
user253751

1
Người lùn không được người chơi gán bất cứ thứ gì, nhưng được hệ thống "giao" nhiệm vụ, đó chính xác là kiến ​​trúc mà Jed T. mô tả ở trên. Tạo thứ tự và hệ thống gán các nhiệm vụ thành phần riêng lẻ để thực hiện thứ tự đó.
Tấn công

2
Lưu ý rằng điều này được gọi là Phân bổ nhiệm vụ và lập lịch, và được nghiên cứu rộng rãi trong một số lĩnh vực kỹ thuật. Bạn sẽ tìm thấy rất nhiều bài báo thảo luận về vấn đề này, có thể được quan tâm.
TonioElGringo

@Attackfarm Hệ thống không quyết định trước tất cả các nhiệm vụ; Nó cũng không gán nhiều nhiệm vụ cho cùng một người lùn. Một nhiệm vụ ban đầu được chỉ định và khi hoàn thành, nó có kết quả là làm cho một nhiệm vụ khác có sẵn.
dùng253751

2
Điều này nghe có vẻ như là một trường hợp sử dụng tuyệt vời cho Kế hoạch hành động hướng
Có vấn đề vào

Câu trả lời:


27

Lúc đầu, bạn thấy rằng các lệnh của bạn ở dạng danh sách , vì vậy bản năng đầu tiên của bạn có thể là tạo lại cấu trúc đó và mỗi chú lùn sẽ chạy qua danh sách đó theo trình tự. Điều tôi đề nghị là chia danh sách thành các bước , với mỗi bước có (các) điều kiện tiên quyết , và sau đó bạn chạy toàn bộ lệnh ngược lại . Hãy để tôi chứng minh bằng một ví dụ:

Cắt gỗ

  • Tôi có mang gỗ không, và tại một kho dự trữ? : thả nó ra
  • Tôi có mang gỗ không? : đi đến một kho dự trữ
  • Tôi đang ở một cái cây? Vâng : chặt nó
  • Không cho tất cả ở trên : đi đến một cái cây

Ưu điểm của việc này là:

  • Rất đơn giản để thực hiện
  • Linh hoạt - bạn có thể tự do phân tách danh sách này, thêm các mục, xóa các mục, kết hợp các mục
  • Không có tiểu bang - bạn có thể chạy danh sách này từ đầu cho bất kỳ người lùn nào ở bất kỳ tiểu bang nào và người lùn sẽ chỉ thực hiện TM đúng

Nhược điểm:

  • Rất dễ bị mắc kẹt trong các vòng lặp, vì không có trạng thái và không có ý thức về việc bị mắc kẹt

Về mặt logic, bạn có thể biểu diễn các lệnh này dưới dạng biểu đồ luồng, được chạy từ đầu mỗi lần và những gì bạn làm phụ thuộc vào việc bạn có trả lời có / không ở mỗi bước hay không. Cho dù bạn thực hiện điều này trong mã hoặc trong một tệp bên ngoài như XML là tùy thuộc vào bạn.


2
Điều này cũng có lợi thế là để cho các lệnh ghi đè trạng thái, Tôi có đói không? nếu có, bỏ tất cả mọi thứ và đặt nhiệm vụ "ăn" với ăn tương tự như công việc kéo gỗ.
ratchet freak

7
@ratchetfreak "Tôi biết sự an toàn của pháo đài của tôi dựa vào tôi chiến đấu với con quái vật này để nó không tấn công thường dân, nhưng trời ạ, bụng tôi cứ réo lên!" Cố gắng đừng làm cho nó quá giống DF về vấn đề đó: P
Đại tá Ba mươi Hai

Tôi nghĩ rằng điều này giống với những gì sử dụng (hoặc ít nhất là được sử dụng) cho phép tạo tác bị lỗi của máy bay (điều này là do một vật phẩm bị cấm, gây ra vòng lặp nói trên)
Destrictor

3
@ColonelThentyTwo Bạn đang funở đâu trong đó? ;)
Lasse

Tôi thực sự khuyên bạn không nên sử dụng kế hoạch hành động mang tính biểu tượng cho việc này. Về cơ bản là không thể gỡ lỗi và hành vi không mong muốn có thể dễ dàng phát sinh. Dễ dàng hơn nhiều để mã hóa các chuỗi hành động cho từng nhiệm vụ theo cách thủ tục.
mklingen

10

Nếu bạn có thể tạo ra các chuỗi khá chung chung, thì không có nhiều mã spaghetti.

Trong trường hợp giao hàng, ví dụ: WorkTask hoạt động với WorkPlan. Workplan cho biết loại đơn vị tài nguyên nào phải chọn, từ loại nhà nào, sử dụng hoạt hình đi bộ nào, sử dụng hoạt hình nào, thời gian để làm việc và tất cả các chi tiết như vậy. Vì vậy, cuối cùng WorkTask có thể trông giống như:

  1. Tìm% resource1% trên bản đồ
  2. Chuyển đến vị trí đó bằng% animation_1%
  3. Làm việc tại chỗ bằng cách sử dụng% animation_2% cho% time%
  4. Lấy% req_resource1% trong số% req_count1%
  5. Chuyển đến% home% bằng% hoạt hình%
  6. Bắt đầu% animation_6% bên trong cho% time_2%
  7. v.v.

Chúng tôi sử dụng thành công phương pháp mô tả. Chúng tôi có ~ 15 nhiệm vụ trong trò chơi của chúng tôi. Một số điểm nổi bật:

  • Nhiệm vụ đưa ra các hành động của đơn vị (đến đó, nhập, thoát, đi đến đây, ở lại, làm việc, đi)
  • Hành động kết thúc với trạng thái Xong hoặc Bị hủy bỏ và chuyển nó đến Tác vụ
  • Mọi thứ đều được mã hóa cứng (không cần phải viết trình phân tích cú pháp, phương thức giao diện, khả năng tương thích ngược)
  • Mỗi tác vụ thực hiện lớp Nhiệm vụ trừu tượng chỉ bằng một vài phương thức phổ biến (tạo, thực thi, lưu, tải)
  • Nói chung một nhiệm vụ cho mỗi mô-đun, nhưng các nhiệm vụ tương tự nằm trong một mô-đun
  • Các nhiệm vụ rất giống nhau nằm trong một lớp và được cai trị bởi một vài IF (giao đến tận nhà hoặc giao cho đơn vị)
  • Mỗi tác vụ cần khóa và mở khóa tài nguyên thích hợp (nếu đơn vị chết ở bất kỳ bước nào, tài nguyên mà anh ta khóa phải được giải phóng)

2
Đây là hệ thống chúng tôi sử dụng trong trò chơi giống như pháo đài lùn của chúng tôi. Nhiệm vụ được thực hiện bằng cây hành vi. Tài nguyên bị khóa bởi các hành vi và bị mở khóa bởi thất bại. Nó mạnh mẽ và dễ gỡ lỗi hơn nhiều so với phương pháp lập kế hoạch hành động được mô tả bởi câu trả lời hàng đầu
mklingen

5

Vì vậy, đây là vấn đề sắp xếp địa hình cơ bản.

Bạn có một biểu đồ, mỗi nút là một nhiệm vụ cần được thực hiện và một số nút phụ thuộc vào một số nút khác (điều này được thể hiện bằng một cạnh trong biểu đồ từ nút phụ thuộc đến nút mà nó phụ thuộc). Bạn muốn thực hiện tất cả các tác vụ, vì vậy bạn cần tạo ra MỘT SỐ thứ tự của các nút có tính địa hình OK (các nút phụ thuộc nằm sau các nút mà chúng phụ thuộc).

Bây giờ, thường có nhiều thứ tự như vậy (vì một số nút không có sự phụ thuộc và có thể được đặt ở bất cứ đâu, và một số nút có cùng sự phụ thuộc và không phụ thuộc vào nhau để chúng có thể theo bất kỳ thứ tự nào giữa chúng và bất kỳ nút nào cũng có thể được đặt ở bất kỳ nơi nào sau khi nó phụ thuộc xong và trước khi các nút phụ thuộc vào nó được thực hiện).

Cũng có thể không có cách nào để sắp xếp địa hình đồ thị - điều này xảy ra khi có chu kỳ trong biểu đồ (bạn không có gỗ, để lấy gỗ, bạn cần chặt cây, chặt cây bạn cần rìu, để làm rìu cần gỗ). Trong trường hợp như vậy, thuật toán có thể chỉ ra cho người chơi rằng những nhiệm vụ này không thể thực hiện được.

Bạn cũng có thể thêm các ưu tiên cho các nút và nhiệm vụ có thể là tìm thứ tự như vậy, trong số tất cả các thứ tự chứa đầy các phụ thuộc, có các nút ưu tiên lớn hơn được thực hiện trước.

Bạn cũng có thể thêm các tác vụ nhận - cách dễ nhất có thể là chỉ thêm tác vụ với thời gian chờ một lần nữa vào biểu đồ mỗi khi nó được thực hiện.

Bây giờ làm thế nào để giải quyết nó - http://en.wikipedia.org/wiki/Topological_sorting

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.