You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于HashMap存储的相邻领地间距离计算方案咨询

Efficient Territory Distance Calculation for Your Board Game

Hey there! Let's work through this distance calculation problem for your board game—this is a super common challenge when dealing with networked game spaces, so I’ve got some practical, efficient approaches tailored to your setup.

The Go-To: Breadth-First Search (BFS)

Since each adjacent territory has a distance of 1 (unweighted graph), BFS is perfect here. It naturally finds the shortest path (which translates directly to your distance metric) efficiently, with a time complexity of O(N + E) where N is the number of territories and E is the number of adjacent connections.

Here’s a Java implementation that fits your Territory class and HashMap<String, Territory> setup:

import java.util.*;

public class BoardGameDistanceCalculator {
    public int calculateShortestDistance(String startName, String targetName, HashMap<String, Territory> territoryMap) {
        // Handle edge cases first
        if (!territoryMap.containsKey(startName) || !territoryMap.containsKey(targetName)) {
            throw new IllegalArgumentException("One or both territory names are invalid");
        }
        if (startName.equals(targetName)) {
            return 0; // Distance to self is 0
        }

        // BFS essentials: queue for traversal, visited to avoid cycles, distance tracker
        Queue<String> traversalQueue = new LinkedList<>();
        Set<String> visitedTerritories = new HashSet<>();
        Map<String, Integer> distanceMap = new HashMap<>();

        // Initialize with starting territory
        traversalQueue.add(startName);
        visitedTerritories.add(startName);
        distanceMap.put(startName, 0);

        while (!traversalQueue.isEmpty()) {
            String currentTerritory = traversalQueue.poll();
            int currentDistance = distanceMap.get(currentTerritory);

            // Check all adjacent territories
            for (String neighborName : territoryMap.get(currentTerritory).adjacentTerritories) {
                // Found our target: return immediately (BFS guarantees shortest path)
                if (neighborName.equals(targetName)) {
                    return currentDistance + 1;
                }
                // If we haven't visited this neighbor yet, add it to the queue
                if (!visitedTerritories.contains(neighborName)) {
                    visitedTerritories.add(neighborName);
                    distanceMap.put(neighborName, currentDistance + 1);
                    traversalQueue.add(neighborName);
                }
            }
        }

        // If we exit the loop without finding the target, it's unreachable
        return -1;
    }
}

Optimize with Caching

If you’re going to query the same territory pairs multiple times (which is almost guaranteed in a board game), adding a cache will save you from redundant BFS runs. We can store computed distances in a nested map:

private Map<String, Map<String, Integer>> distanceCache = new HashMap<>();

public int getCachedDistance(String startName, String targetName, HashMap<String, Territory> territoryMap) {
    // Check if we already have this distance calculated
    if (distanceCache.containsKey(startName) && distanceCache.get(startName).containsKey(targetName)) {
        return distanceCache.get(startName).get(targetName);
    }

    // Calculate the distance if not cached
    int distance = calculateShortestDistance(startName, targetName, territoryMap);

    // Update the cache (store both directions since distance is symmetric)
    distanceCache.computeIfAbsent(startName, k -> new HashMap<>()).put(targetName, distance);
    if (distance != -1) {
        distanceCache.computeIfAbsent(targetName, k -> new HashMap<>()).put(startName, distance);
    }

    return distance;
}

Precompute All Distances (For Static Boards)

If your board’s territory adjacency never changes during gameplay (which is standard for most board games), precomputing all pairwise distances during game initialization is the most efficient option. Queries become O(1) lookups afterward.

Here’s how to implement that:

public Map<String, Map<String, Integer>> precomputeAllTerritoryDistances(HashMap<String, Territory> territoryMap) {
    Map<String, Map<String, Integer>> allDistances = new HashMap<>();

    for (String startTerritory : territoryMap.keySet()) {
        Map<String, Integer> distancesFromStart = new HashMap<>();
        Queue<String> queue = new LinkedList<>();
        Set<String> visited = new HashSet<>();

        queue.add(startTerritory);
        visited.add(startTerritory);
        distancesFromStart.put(startTerritory, 0);

        while (!queue.isEmpty()) {
            String current = queue.poll();
            int currentDist = distancesFromStart.get(current);

            for (String neighbor : territoryMap.get(current).adjacentTerritories) {
                if (!visited.contains(neighbor)) {
                    visited.add(neighbor);
                    distancesFromStart.put(neighbor, currentDist + 1);
                    queue.add(neighbor);
                }
            }
        }

        allDistances.put(startTerritory, distancesFromStart);
    }

    return allDistances;
}

Which Approach Should You Choose?

  • Use BFS alone if your board’s adjacency can change dynamically (e.g., territories get blocked/unlocked during gameplay).
  • Add caching if you have frequent repeat queries but still need dynamic adjacency support.
  • Precompute all distances if your board is static—this gives you the fastest possible query times once the game is initialized.

内容的提问来源于stack exchange,提问作者evictedSaint

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:37:01