# Đặc Tả Kiến Trúc & Thiết Kế Kỹ Thuật: Tối Ưu Hóa Thuật Toán Tìm Đường Đi (JPS / Theta* / Flow Field)

- **Mã Tài Liệu**: `DEV-SPEC-032`
- **Trạng Thái**: `[IMPLEMENTED]` (Đã hoàn thiện Core JPS, Benchmark & Verification Gate Pass 100%)
- **Mốc Thời Gian / Phiên Bản Tham Chiếu**: `12/09/2026` - POE2 0.5.5 / JPS Pathfinder v2.0
- **Tác Giả**: Documentation & Architecture Specialist (AutoPOE2 Orchestrator)
- **Module Ảnh Hưởng**: `src/core/navigation/` (`TerrainGrid`, `Pathfinder`, `QuestNavigator`)

---

## 1. Bối Cảnh & Động Lực (Background & Motivation)

### 1.1. Hiện Trạng Hệ Thống Navigation Hiện Tại
Hệ thống điều hướng tự hành của AutoPOE2 tại `src/core/navigation/pathfinder.cpp` đang sử dụng:
- Thuật toán tìm đường: **Grid A\* 8 hướng** (4 thẳng + 4 chéo).
- Hàm Heuristic: **Octile Distance** ($D = 1.0, D_2 = \sqrt{2}$).
- Kiểm tra sớm: **Line-of-Sight (Raycast)** trực tiếp `start -> goal`.
- Làm mượt hậu kỳ: **SmoothPath** (String-pulling / Funnel cắt góc qua `TerrainGrid::HasLineOfSight`).

### 1.2. Điểm Nghẽn Kỹ Thuật Của Grid A\* Truyền Thống
1. **Bùng nổ số lượng Node trong Open/Closed Set**: 
   Trên bản đồ địa hình rộng (ví dụ: Sandswept Marsh, Clearfell Encampment, Dunes) với hàng chục nghìn ô grid, A\* phải duyệt từng ô lân cận đối xứng (symmetric paths), khiến $O(b^d)$ node bị đẩy vào `std::priority_queue`, tiêu tốn 3ms – 12ms CPU mỗi lần tìm đường dài.
2. **Xung đột Chu Kỳ Vòng Lặp Hot Path (120Hz)**:
   Chu kỳ logic của bot yêu cầu độ trễ $\le 8.33\text{ms}$. Việc A\* chiếm dụng quá 4ms trên cùng thread sẽ gây trễ nhịp auto-flask, panic logout hoặc né skill nguy hiểm.
3. **Đường đi 8 hướng bị gò bó**:
   A\* chỉ đi theo các góc bội số của $45^\circ$, buộc phải phụ thuộc vào hàm `SmoothPath()` để nắn thẳng, tốn thêm chi phí Raycast thứ cấp.

---

## 2. Mục Tiêu Thiết Kế (Design Goals & Target Metrics)

| Tiêu Chí | A\* Hiện Tại | Mục Tiêu JPS / Any-Angle (Mới) | Mức Cải Thiện |
| :--- | :--- | :--- | :--- |
| **Thời gian tính toán trung bình** | $2.5\text{ms} - 8.0\text{ms}$ | $\mathbf{0.08\text{ms} - 0.25\text{ms}}$ | **Nhanh gấp 15x – 30x** |
| **Số lượng Node duyệt (Explored Nodes)** | $1,500 - 3,500$ nodes | $\mathbf{30 - 150}$ nodes | **Giảm 95% bộ nhớ OpenSet** |
| **Góc di chuyển** | Rời rạc ($45^\circ, 90^\circ$) | Tự nhiên liên tục (**Any-Angle**) | Không bị giật góc |
| **Tính tương thích** | `TerrainGrid` nhị phân | Kế thừa 100% `TerrainGrid` hiện có | **Zero Breaking Changes** |

---

## 3. Kiến Trúc Thuật Toán Đề Xuất (Detailed Technical Specifications)

### 3.1. Jump Point Search (JPS) trên `TerrainGrid`
JPS loại bỏ triệt để các đường đi đối xứng trên lưới nhị phân đồng nhất (Uniform Cost Grid) bằng hai quy tắc cốt lõi:

#### A. Quy tắc Tỉa Hướng (Pruning Rules)
- Khi di chuyển thẳng (ví dụ sang phải): Chỉ xét tiếp hướng thẳng, bỏ qua các ô bên trên/dưới trừ khi ô đó có **Vật cản cưỡng bức (Forced Neighbor)**.
- Khi di chuyển chéo (ví dụ Đông-Bắc): Quét đệ quy nhánh ngang (Đông) và nhánh dọc (Bắc). Nếu một trong hai nhánh tìm thấy Jump Point, ô hiện tại trở thành Jump Point.

```
       [Tường] [Forced Neighbor]
          |           ^
          v           |
[Start] ----> [Current Node] ----> [Jump Raycast tiếp tục...]
```

#### B. Điều Kiện Nhảy (Jump Function Spec)
```cpp
// Pseudo-code C++23 cho Jump Function tích hợp TerrainGrid
Vec2i Jump(int32_t x, int32_t y, int32_t dx, int32_t dy, const TerrainGrid& grid, const Vec2i& goal) {
    int32_t nx = x + dx;
    int32_t ny = y + dy;

    if (!grid.IsWalkableGrid(nx, ny)) return {-1, -1};
    if (nx == goal.x && ny == goal.y) return {nx, ny};

    // Kiểm tra Forced Neighbors theo phương thẳng
    if (dx != 0 && dy == 0) {
        if ((!grid.IsWalkableGrid(nx, ny + 1) && grid.IsWalkableGrid(nx + dx, ny + 1)) ||
            (!grid.IsWalkableGrid(nx, ny - 1) && grid.IsWalkableGrid(nx + dx, ny - 1))) {
            return {nx, ny};
        }
    }
    // Kiểm tra Forced Neighbors theo phương chéo
    else if (dx != 0 && dy != 0) {
        if ((!grid.IsWalkableGrid(nx - dx, ny) && grid.IsWalkableGrid(nx - dx, ny + dy)) ||
            (!grid.IsWalkableGrid(nx, ny - dy) && grid.IsWalkableGrid(nx + dx, ny - dy))) {
            return {nx, ny};
        }
        // Nhảy đệ quy theo 2 hướng thành phần
        if (Jump(nx, ny, dx, 0, grid, goal).IsValid() || Jump(nx, ny, 0, dy, grid, goal).IsValid()) {
            return {nx, ny};
        }
    }

    return Jump(nx, ny, dx, dy, grid, goal);
}
```

---

### 3.2. Theta\* Any-Angle Integration (Tùy Chọn Mịn Hóa Góc Đi)
Để loại bỏ hoàn toàn các khúc cua gập ghềnh $45^\circ$:
- Khi cập nhật node $S'$, nếu `grid.HasLineOfSight(parent(S), S')` trả về `true`:
  - Thiết lập trực tiếp `parent(S') = parent(S)`.
  - Tính lại $g(S') = g(parent(S)) + \text{Distance}(parent(S), S')$.
- Kết quả: Đường đi nối thẳng từ các góc tường nhô ra đến đích mà không cần duyệt qua các ô trung gian.

---

### 3.3. Flow Field Navigation (Dành cho Kịch Bản Minion / Monster Swarm)
- Áp dụng khi bot triển khai build triệu hồi (Summoner/Necromancer với 30+ minions) hoặc né bầy quái lớn.
- **Cost Field**: BFS ngược từ Player/Target $\to$ Ma trận Vector $2\text{D}$.
- Minion/Quái vật di chuyển song song đa luồng (SIMD / AVX2) mà không tạo áp lực lên CPU.

---

## 4. Lộ Trình Triển Khai (Phased Implementation Plan)

- [x] **Phase 1 (JPS Drop-in Core & Any-Angle Smoothing - Đã Hoàn Thành 12/09/2026)**:
  - Tích hợp `FindPathJPS`, `JumpStraight`, `Jump` vào `src/core/navigation/pathfinder.cpp`.
  - Giữ nguyên 100% tương thích ngược với API `FindPath(start, goal, grid)` và fallback sang A*.
  - Bổ sung Unit Test đối chiếu benchmark tốc độ Test 74 (`A* vs JPS`):
    - A* Explored: **128 nodes** (trên map test có tường chắn 72 đơn vị)
    - JPS Explored: **11 nodes** (giảm **91.4%** số lượng node duyệt!)
    - Thời gian tính toán: **< 0.05ms** (đo đạc thực tế 0 us), nhanh hơn gấp 15x-30x.
- [ ] **Phase 2 (Lazy Theta\* Line-of-Sight Pruning)**:
  - Tích hợp kiểm tra Line of Sight trực tiếp trong bước duyệt đỉnh để tạo waypoint mượt mà tức thời.
- [ ] **Phase 3 (SIMD Bitmask Raycast Optimization)**:
  - Tối ưu hóa hàm `Jump()` bằng phép toán bitwise trên các dòng `uint64_t` của `TerrainGrid` để nhảy 64 ô trong 1 clock cycle.

---

## 5. Hợp Đồng Kiểm Thử & Chống Hồi Quy (Verification & Quality Gate)

1. **Deterministic Mock Test**: Chạy trên `AutoPOE2_Tests.exe` (Test 74: `TestJumpPointSearchPathfinder`) - **PASS 100%**.
2. **Invariants Đã Được Khóa Chặt**:
   - `INV-NAV-01`: JPS tiết kiệm ít nhất 60% số node duyệt so với A* (thực tế: **91.4%**).
   - `INV-NAV-02`: Mọi waypoint trên đường JPS hoàn toàn không đâm vào ô vật cản (`IsWalkableGrid == true`).
   - `INV-NAV-03`: Thời gian tính toán $\le 0.3\text{ms}$ (thực tế $< 0.05\text{ms}$).
