Làm thế nào để chia lưới hex đều giữa n người chơi?


15

Tôi đang tạo một trò chơi dựa trên lưới hex đơn giản và tôi muốn bản đồ được chia đều cho những người chơi. Bản đồ được tạo ngẫu nhiên và tôi muốn người chơi có số lượng ô bằng nhau, với diện tích tương đối nhỏ. Ví dụ: nếu có bốn người chơi và 80 ô trên bản đồ, mỗi người chơi sẽ có khoảng 20 ô (không nhất thiết phải chính xác tại chỗ). Ngoài ra, mỗi người chơi nên có không quá bốn ô liền kề. Điều đó có nghĩa là, khi bản đồ được tạo ra, các "khối" lớn nhất không thể nhiều hơn bốn ô mỗi ô.

Tôi biết điều này không phải lúc nào cũng có thể có cho hai hoặc ba người chơi (vì điều này giống với vấn đề "tô màu bản đồ") và tôi đồng ý thực hiện các giải pháp khác cho những người đó (như tạo bản đồ giải quyết vấn đề thay thế). Nhưng, đối với bốn đến tám người chơi, làm thế nào tôi có thể tiếp cận vấn đề này?


Cellular automata là một cách đơn giản, tương tự như thế này: Một bản đồ đơn giản, bốn quần xã sinh vật và cách phân phối chúng
MichaelHouse

Câu trả lời:


3

Đây là những gì tôi sẽ làm:

  1. Chỉ định tất cả các ô cho người chơi ngẫu nhiên. Trên các bản đồ lớn, điều này rất có khả năng tạo ra số lượng gạch khá chẵn cho tất cả người chơi, trên các bản đồ nhỏ hơn có thể bạn sẽ cần phải thực hiện một số chỉnh sửa.
  2. Chia nhỏ những khối quá lớn. Cách dễ nhất để làm là lấy tất cả các ô trong khối và một lần nữa gán ngẫu nhiên từng ô.
  3. Trong trường hợp số lượng ô không cân bằng (ví dụ: người chơi A có 24 ô, người chơi B có 16 ô), hãy chỉ định lại một vài ô từ người chơi được thể hiện quá mức cho đến người chơi bị thiếu.
  4. Kiểm tra lại cho chunk. Nếu bước 3 giới thiệu các đoạn mới, quay lại bước 2. Nếu không, bản đồ đẹp!

Tái bút: Tôi không nghĩ vấn đề này là không thể, vấn đề tô màu bản đồ khá khác biệt (đối với một điều, đó là cách khác, hình dạng-> màu sắc thay vì màu sắc-> bài tập gạch).
Junuxx

Tôi thích cách tiếp cận này khá nhiều, nhưng không có khả năng nó sẽ chạy trong một thời gian dài, cố gắng cân bằng kích thước khu vực?
manabreak

1
@manabreak: Tôi đã làm một cái gì đó để thử nó. Với một thay đổi nhỏ ở bước 2 (gán lại bằng cách đạp xe qua tất cả người chơi thay vì gán lại ngẫu nhiên), nó hoạt động khá tốt. Tôi sẽ cố gắng viết nó lên khi tôi có thời gian.
Junuxx

1
Điều đó trông chính xác những gì tôi đang tìm kiếm. :)
manabreak

1

Giả sử bạn có ntổng số hexmap của các ô và pngười chơi, ở đó p <= n, cách tốt nhất để giải quyết vấn đề này là phân phối vòng tròn thông qua automata di động (CA).

Khởi tạo

Ngẫu nhiên (và / hoặc sử dụng một số hoặc heuristic khác, chẳng hạn như khoảng cách từ trung tâm bản đồ) chọn một ô bắt đầu cho mỗi người chơi. Vì p <= n, đây không phải là một vấn đề.

Automata di động

Bạn yêu cầu kết nối đầy đủ giữa các ô hex của bạn. Tôi muốn đề xuất một mảng 6 hàng xóm cho mỗi ô:

class Cell
{
   //... other members...
   Cell[6] neighbours = new Cell[6];
}

Việc sử dụng các mảng kích thước cố định cho phép tồn tại khái niệm hướng địa hình giữa các ô, điều mà một danh sách hoặc vectơ sẽ không có. Tôi khuyên bạn nên điều này, vì nó có thể làm cho ops điều hướng nhất định dễ dàng hơn.

Bạn cũng có thể lưu trữ hexmap của mình trong một mảng 2D, với độ lệch trên mỗi hàng. Tuy nhiên, điều này có thể hơi ít trực quan hơn so với việc lưu trữ một mảng lân cận trên mỗi ô, chỉ vì phần bù hình học trên mỗi hàng khác.

Hãy chắc chắn rằng mọi tế bào được kết nối với tất cả mọi thứ là hàng xóm. Bạn có thể thực hiện hàng này theo từng hàng, từng ô khi bạn tạo hexmap đầy đủ. PS Nếu cuối cùng bạn muốn có một hình lục giác giới hạn không phải hình chữ nhật, thì bạn có thể chỉ cần loại bỏ các ô riêng lẻ và tham chiếu đến các ô đó, để tạo thành các không gian âm, cho phép bạn tạo một phác thảo bản đồ hữu cơ.

Phân phối vòng tròn

Mã giả:

count number of neutral cells in entire map, minus those starting cells taken by players
while neutral cells remain (or while true)
   for each player
      if player has not yet reached expected territory size in cells
         for each cell already constituting this player's territory
           if territory can grow by one cell into a neutral neighbour
              grow into neighbour
              reduce neutral cell count for entire map by one
              if no more neutral cells remain in map
                 break out of outermost while loop immediately
              else
                 continue to next player immediately
begin game

Thuật toán này sẽ cung cấp cho mỗi người chơi một cơ hội để phát triển lãnh thổ của mình, theo kiểu vòng tròn, với điều kiện là lãnh thổ của người chơi vẫn có không gian phát triển hợp lệ. Nếu người chơi nào đó bị chặn từ phát triển hơn nữa, thuật toán sẽ bất chấp điều này tiếp tục phát triển các vùng lãnh thổ của người chơi làm vẫn có không gian phát triển hợp lệ. Bạn có thể dễ dàng giới hạn mọi người chơi trong cùng một số ô ngay khi một trong số họ đạt đến giới hạn, nhưng điều đó đủ dễ để bạn tìm ra, nếu muốn.

Điều này sẽ cung cấp "lãnh thổ nhà" có kích thước tối đa cho mỗi người chơi. Ngoài ra, nếu bạn muốn có các lãnh thổ "đảo", để hoàn thành chỉ tiêu số lượng tế bào cho người chơi đó, thì một khi người chơi hết không gian cục bộ để phát triển, bạn có thể chọn một ô bắt đầu mới từ danh sách các ô trung tính và tiến hành quá trình "tăng trưởng" tương tự, từ đó. Bằng cách này, bạn sẽ kết thúc với các nhóm đảo kết hợp, có kích thước độc đáo cho mỗi người chơi, thay vì tiếng ồn ngẫu nhiên.


Trong khi bạn cung cấp tài liệu tuyệt vời và mã giả cho thuật toán của bạn, tôi không chắc điều này phù hợp với những gì người hỏi hỏi về. Câu hỏi đề cập đến "khối" lớn nhất không thể nhiều hơn bốn ô mỗi ', trong khi thuật toán của bạn tạo ra một nhóm kết nối càng lớn càng tốt.
fnord

@fnord Không, không. Bạn đã không đọc câu trả lời của tôi đúng. Tôi rõ ràng đặt một giới hạn trong mã giả: "nếu người chơi chưa đạt kích thước lãnh thổ dự kiến ​​trong các ô". Vui lòng xóa downvote của bạn. Vui lòng kiểm tra lịch sử sửa đổi về câu hỏi để thỏa mãn bản thân rằng đây là trường hợp kể từ trước khi bình luận và downvote của bạn.
Kỹ sư

Câu hỏi yêu cầu có "không quá bốn ô liền kề", nhưng mỗi người dùng sẽ có một phần dự kiến ​​của bản đồ. Điều này, với tôi, ngụ ý rằng e sẽ tìm kiếm một cái gì đó giống với cách các trò chơi Rủi ro ngẫu nhiên phân bổ bản đồ cho tất cả người chơi. Câu trả lời của bạn chia bản đồ thành "các lãnh thổ nhà" có kích thước tối đa ". Đúng, thuật toán của bạn dừng khi đạt đến giới hạn kích thước lãnh thổ dự kiến, nhưng tôi không thấy cách nào để người chơi đó có được "đảo" mới, mặc dù bạn có đề cập đến nó trong văn bản sau.
fnord

@fnord Logic của bạn có lỗi. Trong câu cuối cùng của bạn, bạn thừa nhận rằng thuật toán của tôi dừng ở kích thước đảo nvà sau đó mâu thuẫn với chính bạn bằng cách nói rằng bạn "không thấy một cách nào" mà tôi vẫn "đề cập đến [cách lấy đảo] trong văn bản sau". Tôi đã hoặc tôi chưa trả lời câu hỏi? Thuật toán tổng quát này có thể được sử dụng để phân tán các ô (bằng cách giới hạn nở 1) hoặc để tạo các đảo (bằng cách đặt n> 1). Vì vậy, bạn có, trong một thuật toán duy nhất, không chỉ khả năng phân tán, mà còn cả nhóm. Làm thế nào điều này không trả lời câu hỏi của OP? Làm thế nào là nó xứng đáng với một downvote?
Kỹ sư

Tôi sẽ chỉnh sửa nhận xét của tôi ở trên, nhưng đã quá muộn. "Tôi không thấy một cách trong thuật toán của bạn ". mặc dù bạn có đề cập đến khái niệm trong văn bản sau này.
fnord

0

Một cách tiếp cận khác là bắt đầu với một bản phân phối 'công bằng' nhưng thường xuyên, và sau đó sử dụng một thẩm định tương tự như Mô phỏng luyện kim để phá vỡ sự đều đặn mà không mất đi sự công bằng:

  • Bắt đầu bằng cách gán màu cho tất cả các ô của lưới của bạn theo mẫu thông thường (ví dụ: có mẫu '123412341234' lặp lại ở hàng đầu tiên, tiếp theo là '341234123412' trên tiếp theo, v.v.). Điều này có thể dẫn đến sự phân bố màu không đồng đều nếu bản đồ của bạn có hình dạng đặc biệt kém, nhưng tôi cho rằng bạn đang bắt đầu với một bản đồ cố định, vì vậy bạn sẽ có thể tìm thấy một số màu thường xuyên được phân bổ đều của nó.
  • Sau đó lặp lại các bước sau cho bao nhiêu bước bạn muốn (không có tiêu chí 'sự thân thiện' thực sự, vì vậy thử nghiệm sẽ cho bạn biết số bước hợp lý tối thiểu là bao nhiêu):
    • Chọn ngẫu nhiên hai phần tử của lưới
    • Nếu chúng có cùng màu, hãy thử lại (không có điểm nào khác, kể từ đó, việc hoán đổi sẽ là không có. Bạn chỉ có 1/4 cơ hội đánh cùng màu và 1/16 cơ hội đánh cùng màu hai lần liên tiếp, vì vậy bạn không bao giờ phải thử lại quá nhiều)
    • Tạm thời hoán đổi màu sắc của hai yếu tố đó
    • Kiểm tra kích thước của các khu vực mới được hình thành trong vị trí của các thành phần sau khi trao đổi:
      • thực hiện một trận lụt đơn giản - điền vào bên ngoài từ vị trí mới của từng yếu tố để xác định vùng trao đổi màu đó sẽ lớn đến mức nào.
    • Nếu một trong hai khu vực này lớn hơn ngưỡng của bạn, hãy hoàn tác trao đổi tạm thời; mặt khác, 'hoàn thiện' sự hoán đổi màu của hai yếu tố.

Chìa khóa ở đây là việc bạn hoán đổi hai điểm có nghĩa là bạn không bao giờ làm mất cân bằng màu sắc, và tương tự như bài kiểm tra mà bạn thực hiện trước khi hoàn tất việc hoán đổi của mình đảm bảo rằng bạn không bao giờ tạo ra các vùng quá lớn. Nếu bạn có một số phương tiện hiển thị lưới của mình, bạn thậm chí có thể hình dung quá trình này để xem cách nó 'xây dựng' các vùng của nó thông qua các giao dịch hoán đổi lặp đi lặp lại.

Nếu bạn không thể bắt đầu với việc tô màu đều đặn, ngẫu nhiên, thì bạn vẫn có thể làm một cái gì đó tương tự như phân phối màu: trong khi màu của bạn không được phân phối, hãy chọn một yếu tố ngẫu nhiên; sau đó, nếu đó là một trong những màu được biểu thị quá mức, hãy đặt tạm thời màu của nó thành một trong các màu được thể hiện dưới đó và sau đó kiểm tra để đảm bảo rằng không tạo ra một vùng quá lớn của màu mới.


Phương pháp tiếp cận ngẫu nhiên là không hiệu quả. Đối với một cách tiếp cận như của tôi có các bước được xem xét, thời gian chạy tiếp cận O (n) cho n ô bản đồ. Đối với thuật toán của bạn, đó là O (n * m), trong đó m là số lượng ô mong muốn trên mỗi đảo (thực tế, cho mỗi đảo tiềm năng). Luôn luôn tốt nhất để nhắm đến các thuật toán có thời gian chạy dễ ước tính. Thay vì sửa một bản đồ được tạo ra một cách ngớ ngẩn, tốt hơn là tạo một bản đồ không bị phá vỡ hoặc không phù hợp ở nơi đầu tiên, trong n bước, do đó duy trì một quy trình hiệu quả, được kiểm soát.
Kỹ sư
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.