Thuật toán đường dẫn dài nhất cho thế hệ mê cung roguelike


10

Tôi có một bản đồ dựa trên lưới đơn giản bao gồm các phòng, như thế này (A = lối vào, B = lối ra):

   0 1 2 3
  #########
0 # B # #####
  #########
1 # ### #
  #########
2 # # #
  # # #
3 # # #
  #########
4 # ### #
  #########
5 ### A #
  ### #
6 ### #
  #########

Và tôi bị mắc kẹt khi cố gắng tạo ra một thuật toán phù hợp để tạo ra một lối đi giữa các phòng, theo cách mà người chơi phải khám phá hầu hết bản đồ trước khi tìm thấy lối ra.

Nói cách khác, tôi đang cố gắng để tìm ra con đường tốt nhất từ A đến B .

(Tôi biết rằng vấn đề này có thể được giải quyết cho các đồ thị theo chu kỳ; tuy nhiên, trong trường hợp này có thể có các chu kỳ.)

EDIT: Một ví dụ khác mà các phòng được kết nối bằng cách sử dụng bãi chôn lấp và lối ra được chọn là phòng xa nhất từ ​​lối vào:

   0 1 2 3
  #########
0 # B # #
  # # - #####
1 # | # #
  ### # #
2 ### # #
  ### - # - ###
3 # | ###
  # - #######
4 #A | #
  # # #
5 # # #
  # # #
6 # # #
  #########

Lưu ý rằng đường dẫn đến lối ra không phải là đường dẫn dài nhất có thể.


Nếu bạn buộc người chơi đi theo con đường dài nhất có thể, bạn thực sự đang xây dựng một con đường thẳng giả vờ phức tạp. Thật tệ.
o0 '.

Nó không tệ (ví dụ, nó là nền tảng của thể loại game bắn súng đường sắt), nhưng bạn cần lưu ý rằng bạn đang làm điều đó và thiết kế phần còn lại của trò chơi để hoạt động tốt với nó.

Nó cũng dễ dàng hơn để kiểm soát tốc độ của trò chơi khi các cấp độ chủ yếu là tuyến tính. Nó làm cho nó có thể thêm, ví dụ, một phòng phục hồi sau một phòng quái vật đặc biệt khó khăn. Nếu không có một con đường chính, việc phân phối các thử thách và phần thưởng sẽ là ngẫu nhiên.
Người dùng không tìm thấy

Câu trả lời:


11

Tôi nghĩ rằng bạn đang đi về điều này sai cách. Đường dẫn tối đa trong biểu đồ có chu kỳ không được xác định về mặt kỹ thuật vì nó là vô hạn nếu chu trình nằm giữa điểm bắt đầu và điểm kết thúc. Có thể có những cách thông minh mà bạn có thể mở rộng / hạn chế định nghĩa về đường dẫn tối đa, nhưng tôi không nghĩ đó là cách tiếp cận tốt nhất ở đây.

Bạn không cố gắng mô hình hóa một con đường dài thực sự (ví dụ: robot cố gắng khám phá càng nhiều khu vực trong bản đồ càng tốt). Bạn chỉ đang cố gắng để người chơi khám phá nhiều phòng.

Vì vậy, hãy tạo cơ hội cho người chơi tìm thấy lối ra tỷ lệ thuận với tỷ lệ phần trăm của bản đồ được khám phá cho đến nay . Giả sử có các phòng X ở một cấp độ và nhân vật người chơi đã khám phá Y. Lần tới khi nhân vật vào một phòng, hãy đặt lối ra ở đó với xác suất f (Y, X). Một ví dụ tầm thường của f có thể là (Y * Y) / (X * X) - ví dụ: đối với 10 phòng, có 100% cơ hội thoát ra ở phòng cuối cùng, 81% cơ hội ở phòng kế bên - và chỉ một 1% cơ hội đó là trong phòng đầu tiên.

Bạn có thể điều chỉnh phương trình tuy nhiên bạn muốn làm cho trò chơi cảm thấy đúng, và thậm chí có thể cung cấp cho người chơi một số khả năng để làm cho nó có nhiều khả năng tạo ra hơn. Phần quan trọng là, không tạo ra lối ra cho đến khi nhân vật thực sự bước vào phòng. Phương pháp này cũng miễn dịch với kiến ​​thức của người chơi về thuật toán tạo ngục tối; ngay cả khi người chơi có các kiểu di chuyển kỳ lạ như nhảy của hiệp sĩ trong NetHack hoặc dịch chuyển tức thời, họ sẽ phải khám phá nhiều phòng hơn để tìm lối ra.

Nếu bạn phải tạo ra lối thoát tĩnh, bạn có thể sử dụng cùng một ý tưởng với một ký tự ảo. Hãy tưởng tượng một trận lụt bắt đầu từ vị trí của nhân vật, di chuyển một lần mỗi ô mỗi lần lặp. Căn phòng cuối cùng được lấp đầy là căn phòng nơi lối ra (thực tế, ô cuối cùng được lấp đầy là ô nơi xa nhất với người chơi). Tuy nhiên, trong trường hợp này, người chơi có nhiều thông tin hơn về lối ra - nếu họ ở bên trái, rất có thể ở bên phải - và nếu họ có thể dịch chuyển tức thời, thực sự có thể đến đó nhanh hơn so với đi bộ ngẫu nhiên bình thường.

Cuối cùng, tôi vừa hoàn thành một roguelike nơi lối ra xuất hiện ở phía bên kia của bản đồ từ nhân vật người chơi, và sau đó lang thang ngẫu nhiên. Một số vật phẩm trong ngục tối khiến nó hiển thị trên bản đồ, với chi phí bị đói nhanh hơn. Tôi đã không thực hiện bất kỳ phân tích nào, nhưng chắc chắn cảm giác như tôi phải khám phá thêm bản đồ để tìm thấy nó, và nó mang lại cho các cấp độ một cảm giác độc đáo.


Thế hệ động dường như là một ý tưởng khá hay, miễn là người chơi không chú ý. Nếu không tôi nghĩ rằng họ sẽ cảm thấy khá lừa dối. Tôi yêu ý tưởng lũ lụt, mặc dù.
Không tìm thấy người dùng

2
Vâng, toàn bộ đề xuất của bạn trong một số ý nghĩa là lừa dối người chơi. Đừng đổ lỗi cho tôi vì đã tinh chỉnh toán học để không yêu cầu một mô hình thế giới. ;) Nhưng bạn có thể sử dụng các thủ thuật thiết kế để làm cho nó trở nên ngon miệng hơn - ví dụ: lối ra được đặt một ưu tiên, nhưng một khóa cần thiết để sử dụng nó được tạo ra trong phương pháp tôi mô tả hoặc đặt vào một con quái vật chỉ sinh ra sau khi khám phá X phòng / giết quái vật X, hoặc mở cửa đòi hỏi phải bật công tắc X, mỗi cái một cái, v.v ...

Tôi đã thử một cách tiếp cận lũ lụt. Nó thực hiện tốt việc kết nối mọi phòng và tạo ra các nhánh ngắn, nhưng nó không thực sự tạo ra con đường dài nhất có thể đến lối ra ngay cả khi lối ra là nút cuối cùng được truy cập (hoặc, trong triển khai của tôi, là nơi xa nhất). (ví dụ được thêm vào câu hỏi của tôi)
Người dùng không tìm thấy

Tôi là tất cả cho mê cung dựa trên khóa / chuyển đổi, mặc dù. Có vẻ như dễ dàng hơn để thực hiện loại điều đó với cây, bởi vì sau đó nếu bạn có hai nhánh, bạn có thể phát hiện nhánh nào dẫn đến lối ra, chặn nó và đặt khóa vào nhánh khác.
Người dùng không tìm thấy

Nhưng tôi thừa nhận rằng tôi đã sai khi nghĩ rằng đó là vấn đề tìm đường "từ A đến B". Tôi nhận ra rằng sẽ có ý nghĩa hơn khi tìm lối ra là kết quả của thuật toán chứ không phải là mục tiêu.
Người dùng không tìm thấy

6

Một cách khác có thể là tạo một cây bao trùm (tối đa?) Bằng cách sử dụng Prim / Kruskal (để loại bỏ chu kỳ) và áp dụng thuật toán đường dẫn dài nhất truyền thống trên cây bao trùm.

Tuy nhiên, tôi lo lắng rằng thuật toán cây bao trùm sẽ có xu hướng tạo ra các nhánh cụt, buộc người chơi phải quay lại liên tục.

EDIT: Kết quả của việc sử dụng thuật toán dựa trên Kruskal và đặt lối ra ở cuối nhánh dài nhất:

   0 1 2 3
  #########
0 #A | #
  # ##### - #
1 # # #
  ### #
2 ### #
  ### #
3 ### #
  ### - #####
4 # | #
  # - ##### - #
5 # ### #
  # - #######
6 # # B #
  # # - #
7 # | #
  #########

1
Tôi cũng sẽ đề xuất Primm :-), +1, tôi nghĩ rằng backtrack cũng là một phần quan trọng của rất nhiều trò chơi ... hãy kiểm tra diablo 2.
Mr.Gando

2

Đây là một cái gì đó để mân mê:

Connect each room with a door to another room.
N = 0.75*TotalNumberOfRooms
Until (pathSize > N) {
  Use A* pathing to get a path from A to B. (G being size of room, or # of monsters)
  if (pathSize < N) remove a connection/door
  if (noPath) choose a different door/connection
  if (room.doors < 1) choose a different door/connection
}

Tôi sẽ loại bỏ các cánh cửa ngẫu nhiên dọc theo lối đi, nếu không, bạn sẽ có 1 cửa ở lối ra và hàng tấn cửa khi bắt đầu.

Tôi nghĩ rằng điều này là O(n^2)không tuyệt vời cho bản đồ lớn.


Một giải pháp rất thanh lịch về nguyên tắc. Lần tới tôi nên cố gắng nghĩ về một cái gì đó như thế này trước khi đi cho các kỹ thuật phức tạp.
Người dùng không tìm thấy

Chà, thanh lịch có thể nhưng nó sẽ là một con heo xử lý. O (n ^ 2) sẽ không mở rộng tốt với các bản đồ lớn.
Stephen Furlani


1

Tôi tin rằng bạn đã có câu trả lời tuyệt vời, nhưng đây là giải pháp lý thuyết 0,02 đô la của tôi cho vấn đề này.

Những gì bạn muốn KHÔNG phải là con đường dài nhất, mà là con đường ngắn nhất dài nhất. Bạn muốn căn phòng ở xa nhất, vì bạn đang xem xét con đường ngắn nhất đến phòng. Điều này có vẻ khó hiểu, nhưng nó rất dễ tính toán.

  1. Bắt đầu tại phòng bắt đầu của bạn. Đánh dấu mỗi hàng xóm của nó 1. Họ cách phòng bắt đầu 1 khoảng cách.
  2. Đối với mỗi phòng được đánh dấu 1, hãy truy cập vào từng hàng xóm KHÔNG GIỚI HẠN của họ và đánh dấu họ 2. Họ cách nơi bắt đầu 2 khoảng cách.
  3. Tiếp tục cho đến khi bạn đã bao phủ tất cả các phòng. Phòng có số lượng tối đa là xa nhất từ ​​đầu.

Việc tính toán một con đường dài nhất thực tế (sẽ không mất quá nhiều thời gian để nói 10 phòng) sẽ không hoạt động vì bạn không thể khiến người chơi đi theo con đường dài nhất đó. Vì vậy, đặt lối vào và lối ra trong hai phòng cách xa nhau là cách tốt nhất của bạn. Để tìm thấy điều này, tính toán phòng xa nhất từ ​​một phòng ngẫu nhiên. Sau đó, từ căn phòng đó, tìm căn phòng xa nhất. Điều này được gọi là tìm đường kính của đồ thị, xin vui lòng Google nó.

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.