Tìm đường đi ngắn nhất trên lưới lục giác


14

Tôi đang viết một trò chơi theo lượt có một số yếu tố mô phỏng. Một nhiệm vụ hiện tại tôi đang thực hiện là tìm đường. Những gì tôi muốn làm là di chuyển mỗi lượt một nhà thám hiểm AI một ô gần hơn với mục tiêu của mình bằng cách sử dụng x, y và mục tiêu x, y hiện tại của mình.

Khi cố gắng tự mình tìm ra điều này, tôi có thể xác định 4 hướng không có vấn đề gì bằng cách sử dụng

dx = currentX - targetY
dy = currentY - targetY

nhưng tôi không chắc chắn làm thế nào để xác định hướng nào trong 6 hướng thực sự là tuyến đường "tốt nhất" hay "ngắn nhất".

Ví dụ, cách thiết lập hiện tại, tôi sử dụng Đông, Tây, NE, Tây Bắc, SE, SW nhưng để đến được ô NE tôi di chuyển về phía Đông rồi đến Tây Bắc thay vì chỉ di chuyển theo hướng Tây Bắc.

Tôi hy vọng đây không phải là tất cả lan man. Thậm chí chỉ cần một hoặc hai liên kết để giúp tôi bắt đầu sẽ tốt đẹp. Hầu hết các thông tin tôi tìm thấy là về việc vẽ các lưới và dò tìm hệ thống tọa độ kỳ lạ cần thiết.


5
A * cung cấp cho bạn đường dẫn ngắn nhất bất kể hình dạng của biểu đồ của bạn (lưới, hex, dạng tự do ..)
Jari Komppa

Câu trả lời:


21

Một vài câu trả lời!

Hệ thống tọa độ mà tôi thấy thường xuyên nhất cho di chuyển dựa trên hex là một nơi mà người chơi có thể di chuyển theo mọi hướng NSEW bình thường, cũng như NW và SE. Sau đó, bạn chỉ cần hiển thị mỗi hàng bù một nửa hình vuông. Ví dụ: vị trí (2,7) được coi là liền kề với (1,7), (3,7), (2,6), (2,8) và các vị trí kỳ lạ: (1,6) và (3,8). Trong khi đó, nếu chúng ta giả sử (2,7) được hiển thị ở giữa màn hình, (2,6) sẽ được hiển thị ngược và phải, (2,8) sẽ được hiển thị từ trên xuống dưới -the-left, (1,7) và (3,7) sẽ đặt nó ở bên trái và bên phải, và (1,6) và (3,8) sẽ tự đặt tương ứng trên cùng bên trái và dưới cùng bên phải.

Một sơ đồ của những gì tôi có nghĩa là:

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

Nếu bạn đang thực hiện theo cách này, việc tìm đường đi trực tiếp ngắn nhất không khó - di chuyển khoảng cách NA / SE tối đa mà bạn có thể mà không vượt quá mục tiêu của mình dọc theo trục chính, sau đó di chuyển trực tiếp dọc theo trục đó đến mục tiêu.

Nhưng tất nhiên điều đó sẽ vui vẻ đưa bạn đi thẳng qua những ngọn núi hoặc địa hình hiểm trở khác. Để trả lời một câu hỏi mà bạn chưa hỏi: Thuật toán tìm kiếm A * là một cách tiếp cận phổ biến và hợp lý để tìm đường. Nó sẽ xử lý không chỉ các bố cục phi lưới kỳ lạ, mà còn vui vẻ đối phó với các chướng ngại vật và thậm chí bị tắc nghẽn / mặt đất chậm.


Cảm ơn các liên kết đến thuật toán tìm kiếm A *. Cách duy nhất tôi có thể tưởng tượng là có thể đi qua nsew và nw / se là một hình lục giác nghiêng. Mà có vẻ kỳ lạ trong đầu tôi. Bạn có thể liên kết tôi với một ví dụ về điều đó?
Ti-mô-thê Mayes

4
Tôi đang nói rằng hình ảnh được hiển thị của bạn không cần phải giống với cấu trúc bên trong. Tôi đề nghị rằng bên trong bạn sử dụng NSEW và NW / SE, nhưng bạn hiển thị nó cho người dùng như thể đó là một lưới. Đính kèm sơ đồ giải thích cho câu trả lời ban đầu :)
ZorbaTHut

2
Đại diện thú vị cho một lưới hex. Tôi thường tạo ra một mô hình lởm chởm, do đó, kề là khác nhau cho các hàng lẻ và chẵn. Điều này giới thiệu một độ phức tạp tối thiểu bổ sung trong tìm kiếm đường dẫn, nhưng sử dụng mảng hai chiều hiệu quả hơn (giả sử toàn bộ khu vực chơi là một hình chữ nhật.
Panda Pajama

2
@PandaPajama: răng cưa không hoạt động tốt hơn để lưu trữ hiệu quả các bản đồ hình chữ nhật; bạn có thể làm cho các tọa độ không bị lởm chởm hoạt động độc đáo với thủ thuật này
amitp

2
@PandaPajama, có một mẹo thú vị khác mà bạn có thể sử dụng - bạn có thể sử dụng biểu diễn không bị lởm chởm cho tọa độ, sau đó trừu tượng hóa việc sao lưu cho lưu trữ dữ liệu của bạn đằng sau một cái gì đó sử dụng phương pháp "lởm chởm". Tôi đã tìm thấy hệ thống tọa độ không bị lởm chởm dễ xử lý hơn nhưng tất nhiên một khi nó bị trừu tượng hóa, phần phụ trợ có thể làm bất cứ điều gì nó muốn để làm cho mọi thứ hiệu quả :)
ZorbaTHut

5

Tôi vừa đăng một thư viện sử dụng lưới hex trên CodePlex.com tại đây: https://hexgridutilities.codeplex.com/ Thư viện bao gồm tìm đường dẫn (sử dụng A- * a la Eric Lippert) và bao gồm các sử dụng để chuyển đổi tự động giữa răng cưa (người dùng được gọi là thuật ngữ) và tọa độ không bị lởm chởm (được gọi là Canonical). Thuật toán tìm đường dẫn cho phép chi phí bước cho mỗi nút thay đổi cả với hex hex nhập và te đi qua phía hex (mặc dù ví dụ được cung cấp đơn giản hơn). Ngoài ra, chế độ xem trường nâng cao bằng cách sử dụng đổ bóng được cung cấp, [sửa: xóa từ].

Đây là một mẫu mã có thể chuyển đổi dễ dàng giữa ba hệ tọa độ lưới hex:

static readonly IntMatrix2D MatrixUserToCanon = new IntMatrix2D(2,1, 0,2, 0,0, 2);
IntVector2D VectorCanon {
  get { return !isCanonNull ? vectorCanon : VectorUser * MatrixUserToCanon / 2; }
  set { vectorCanon = value;  isUserNull = isCustomNull = true; }
} IntVector2D vectorCanon;
bool isCanonNull;

static readonly IntMatrix2D MatrixCanonToUser  = new IntMatrix2D(2,-1, 0,2, 0,1, 2);    
IntVector2D VectorUser {
  get { return !isUserNull  ? vectorUser 
             : !isCanonNull ? VectorCanon  * MatrixCanonToUser / 2
                            : VectorCustom * MatrixCustomToUser / 2; }
  set { vectorUser  = value;  isCustomNull = isCanonNull = true; }
} IntVector2D vectorUser;
bool isUserNull;

static IntMatrix2D MatrixCustomToUser = new IntMatrix2D(2,0, 0,-2, 0,(2*Height)-1, 2);
static IntMatrix2D MatrixUserToCustom = new IntMatrix2D(2,0, 0,-2, 0,(2*Height)-1, 2);
IntVector2D VectorCustom {
  get { return !isCustomNull ? vectorCustom : VectorUser * MatrixUserToCustom / 2; }
  set { vectorCustom  = value;  isCanonNull = isUserNull = true; }
} IntVector2D vectorCustom;
bool isCustomNull;

IntMatrix2D và IntVector2D là [chỉnh sửa: đồng nhất] triển khai số nguyên của Vector và ma trận đồ họa affine2D. Sự phân chia cuối cùng cho 2 trên các ứng dụng vectơ là để chuẩn hóa lại các vectơ; điều này có thể bị chôn vùi trong quá trình triển khai IntMatrix2D, nhưng sau đó lý do cho đối số thứ 7 đối với các hàm tạo của IntMatrix2D là ít rõ ràng hơn. Lưu ý kết hợp bộ nhớ đệm và đánh giá lười biếng của các công thức không hiện hành.

Các ma trận này là dành cho trường hợp:

  • Hạt lục giác thẳng đứng;
  • Xuất xứ ở phía trên bên trái cho tọa độ Canonical & Người dùng, phía dưới bên trái cho các tọa độ Tùy chỉnh;
  • Trục Y thẳng đứng xuống;
  • Trục X hình chữ nhật nằm ngang; và
  • Trục X Canonical về phía Đông Bắc (tức là lên và sang phải, ở 120 độ CCW từ trục Y).

Thư viện mã được đề cập ở trên cung cấp một cơ chế thanh lịch tương tự để chọn hex (tức là xác định hex được chọn bằng một cú nhấp chuột).

Trong tọa độ Canonical, 6 vectơ định hướng chính là (1,0), (0,1), (1,1) và nghịch đảo của chúng cho tất cả các hình lục giác, không có sự đối xứng của các tọa độ răng cưa.


Ồ Net bỏ phiếu cho việc đăng một thư viện mã làm việc, với các ví dụ và tài liệu, trả lời câu hỏi / vấn đề do OP đặt ra.
Pieter Geerkens

5
Mặc dù tôi không phải là người downvoter (và nghi thức thường đề nghị để lại một bình luận giải thích về một downvote), tôi nghi ngờ rằng downvote là vì (a) bài đăng phát ra âm thanh quảng cáo và (b) đặt phần lớn câu trả lời cho người khác mặt của một liên kết thường được tán thành bởi vì các liên kết có xu hướng bị thối rữa và các trang web SE cố gắng khép kín. Thông tin được cung cấp ở đây rất thú vị, nhưng nó không trả lời câu hỏi của người dùng và thông tin duy nhất có thể trả lời câu hỏi nằm ở phía bên kia của liên kết.
Steven Stadnicki

Điểm tốt; cảm ơn bạn. Tôi đã mở rộng bài đăng với các trích đoạn giải quyết câu hỏi về cách duy trì hiệu quả nhiều tọa độ lưới hex. Thư viện mã được đăng là phần mềm miễn phí
Pieter Geerkens

Giáo sư! Các chia-by-2 chỉ hoạt động fo nguyên dương. (Cảm ơn bạn một lần nữa, K & R.) Nó nên được thay thế bằng một cuộc gọi đến phương thức Chuẩn hóa () trong IntVector2D:
Pieter Geerkens

public IntVector2D Normalize() { if (Z==1) return this; else { var x = (X >= 0) ? X : X - Z; var y = (Y >= 0) ? Y : Y - Z; return new IntVector2D(x/Z, y/Z); } }
Pieter Geerkens

0

Đây là một vấn đề được giải quyết, với nhiều tài liệu để sao lưu nó. Tài nguyên tốt nhất tôi biết là trên Red Blob Games: https://www.redblobgames.com/grids/hexagons/ .

Tóm lại, lý do rất có thể là bạn đã bắt đầu với hệ thống tọa độ sai. Sử dụng hệ tọa độ Cube thực hiện thuật toán A * khá đơn giản. Xem bản demo trực tiếp trên liên kết trên.

Nếu bạn thực sự muốn sử dụng một số hệ thống khác, sau đó chuyển đổi sang và từ khi cầ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.