Hiển thị phạm vi trên lưới lục giác


10

Đây là tình huống.

Tôi có bảng hình lục giác, và một đơn vị trên đó, với tốc độ hoặc giá trị di chuyển 4. Địa hình khác nhau có chi phí khác nhau. Khi tôi nhấp vào đơn vị, trò chơi sẽ hiển thị cho tôi phạm vi di chuyển.

Giải pháp của tôi là kiểm tra từng hex trong phạm vi 4, với tìm đường dẫn A * và nếu chi phí đường dẫn nhỏ hơn 4 thì hex này nằm trong phạm vi. Cuối cùng, trò chơi sẽ cho tôi thấy phạm vi của đơn vị đó.

Câu hỏi của tôi là: Có giải pháp nào khác để tìm kiếm phạm vi trên lưới hex hoặc lưới vuông không, bởi vì ngay cả khi tôi thực sự tự hào về những gì tôi đã làm trong giải pháp của mình, tôi nghĩ, đó là một chút phóng đại? :))

Điều gì khiến tôi hỏi câu hỏi này? Tôi nhận thấy rằng khi tốc độ đơn vị là 4 hoặc 6 hoặc thậm chí 8, thời gian để phạm vi tính toán cho máy tính của tôi thực sự tốt, nhưng khi tốc độ là 10 và hơn nữa tôi nhận thấy rằng tôi cần đợi vài giây để tính toán .Well trong các trò chơi thực tế, tôi không thấy điều gì như thế này và tính năng tìm đường A * của tôi được tối ưu hóa tốt, vì vậy tôi nghĩ rằng giải pháp của tôi là sai.

Cảm ơn cho bất kỳ trả lời.


1
Tôi đồng ý với Byte56 rằng thuật toán tìm kiếm đầu tiên rộng là một giải pháp tốt. Điều này không có nghĩa là bạn không nên cố gắng sáng tạo, nhưng theo như các thuật toán nổi tiếng thì đó là một thuật toán tốt được áp dụng tốt.
theJollySin

Câu trả lời:


11

Bạn đúng rằng A * là một chút quá mức, nhưng không nhiều. Bạn không nên thấy sự chậm trễ như bạn. A * thực sự chỉ là một thuật toán của Dijikstra đã được sửa đổi . Vì bạn không sử dụng vị trí kết thúc (vì vị trí cuối của bạn chỉ là "càng xa càng tốt"), nên sử dụng A * với thêm heuristic là không cần thiết. Chỉ cần sử dụng Dijikstra hoặc tìm kiếm đầu tiên đơn giản là đủ.

Ví dụ: Dikikstra sẽ trải đều theo mọi hướng:

nhập mô tả hình ảnh ở đây

(Một tìm kiếm đầu tiên đơn giản sẽ trông tương tự như thế này)

Theo dõi chi phí để đi đến từng nút. Khi một nút có chi phí đi lại tối đa, đừng xử lý các nút được kết nối của nó nữa. (Tương tự như nơi các nút chạy vào tường bên dưới).

Nếu bạn đang gặp vấn đề về hiệu suất chỉ với 10 nút, bạn sẽ muốn xem cách bạn truy cập vào các nút. Một tìm kiếm đầu tiên có thể điều hướng hàng trăm nút mà không có độ trễ đáng chú ý (chắc chắn không phải là vài giây). Cân nhắc việc lưu trữ một phiên bản đơn giản của thế giới của bạn ở định dạng biểu đồ, để duyệt nhanh.


bạn có thể tìm thấy khoảng cách giữa hai nút bằng BFS và nhận các chướng ngại vật / trọng lượng khác nhau không?
Luke B.

Chi phí di chuyển giữa các nút nên được tính toán trước cho hầu hết các phần. Chi phí không được tính bằng BFS, BFS là một thuật toán để duyệt qua các nút. Cách bạn xác định chi phí cho việc di chuyển từ nút này sang nút khác độc lập với cách bạn đi qua các nút.
MichaelHouse

Cảm ơn, bây giờ tôi hiểu tại sao suy nghĩ của tôi sai, chìa khóa cho câu nói này là "Vì bạn không sử dụng vị trí kết thúc (vì vị trí cuối của bạn chỉ là" càng xa càng tốt ")". có một vị trí kết thúc, đó là đơn vị. Tôi chỉ giải quyết vấn đề từ hướng sai. Trước tiên tôi xác định đường viền, và sau đó tôi quay trở lại đơn vị của mình, theo cách đó có lẽ tôi đã đi nhiều lần qua các nút tương tự. Khi tốc độ của tôi tăng lên, số lượng tính toán cũng tăng lên rất nhiều. Cách bạn chỉ cho tôi, tôi sẽ luôn truy cập nút một lần. Tôi chỉ có quan điểm sai lầm, thực sự cảm ơn, điều này rất đơn giản.
user23673

4

Amit Patel đã cung cấp một nguồn tài nguyên tuyệt vời để có được phạm vi trên trang web của mình . Trong bài viết, ông sử dụng thuật toán sau để thu thập các ô lục giác trong phạm vi:

for each -N  Δx  N:
    for each max(-N, x-N)  Δy  min(N, x+N):
        Δz = xy
        results.append(H.add(Cubex, Δy, Δz)))

Điều này tạo ra các giới hạn phù hợp với lưới hex:

nhập mô tả hình ảnh ở đây

Điều này sẽ tìm thấy tất cả các hình lục giác trong một khoảng cách nhất định của hình lục giác trung tâm, nếu bạn muốn xem xét các chướng ngại vật, hãy sử dụng tìm kiếm đầu tiên từ câu trả lời khác của tôi.


1

Trong trường hợp bất cứ ai cần nó, đây là triển khai C # của thuật toán Patel:

IEnumerable<Hex> GetRange(Hex center, int range)
    {
        var inRange = new List<Hex>();
        for (int q = -range; q <= range; q++)
        {
            int r1 = Math.Max(-range, -q - range);
            int r2 = Math.Min(range, -q + range);
            for (int r = r1; r <= r2; r++)
            {
                inRange.Add(center.Add(new Hex(q, r, -q - r)));
            }
        }

        return inRange;
    }
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.