All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.neko233.toolchain.game.map.util.MapSearchUtil Maven / Gradle / Ivy

package com.neko233.toolchain.game.map.util;

import com.neko233.toolchain.game.map.key.Map2DKey;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;

/**
 * 图搜索工具
 *
 * @author SolarisNeko on 2022-12-11
 */
public class MapSearchUtil {

    private MapSearchUtil() {
    }

    /**
     * DFS 2D 地图
     *
     * @param target  目标起点
     * @param map     地图 : 是否可走
     * @param markMap 地图标记 : 是否已经走过
     * @param out     输出的 list, 请务必清空. Java 弊端
     */
    public static void dfs2D(Map2DKey target, Map map, Map markMap, List out) {
        if (out == null) {
            return;
        }
        // init
        if (markMap == null) {
            markMap = new HashMap<>();
        }
        if (target == null) {
            return;
        }

        // check
        if (isComeHere(markMap, target)) {
            return;
        }
        if (isCanGo(map, target)) {
            return;
        }

        // mark
        markMap.put(target, true);

        List toTravelList = Map2DKey.generateXyAroundGridList(Map2DKey.builder()
                .mapId(target.getMapId())
                .x(target.getX())
                .y(target.getY())
                .build()
        );

        out.add(target);

        for (Map2DKey newGrid : toTravelList) {
            dfs2D(newGrid, map, markMap, out);
        }
    }


    /**
     * BFS 2D 地图
     *
     * @param target   目标点
     * @param map2D    2D 地图
     * @param markMap  标记地图哪些已经走过, can null
     * @param bfsQueue 队列, can null
     * @param out      输出的结果
     */
    public static void bfs2D(Map2DKey target, Map map2D, Map markMap, Queue bfsQueue, List out) {
        // init
        if (markMap == null) {
            markMap = new HashMap<>();
        }
        if (bfsQueue == null) {
            bfsQueue = new ConcurrentLinkedDeque<>();
        }
        if (target == null && bfsQueue.size() == 0) {
            return;
        }
        if (target == null) {
            target = bfsQueue.remove();
        }
        if (target == null) {
            return;
        }
        // check
        if (isComeHere(markMap, target)) {
            return;
        }
        if (isCanGo(map2D, target)) {
            return;
        }

        // mark
        markMap.put(target, true);

        List toTravelList = Map2DKey.generateXyAroundGridList(Map2DKey.builder()
                .mapId(target.getMapId())
                .x(target.getX())
                .y(target.getY())
                .build()
        );

        // exclude have mark visit node
        for (Map2DKey newGrid : toTravelList) {
            // 是否访问过 | 默认没访问过
            if (isComeHere(markMap, newGrid)) {
                continue;
            }
            // 是否可以走
            if (isCanGo(map2D, newGrid)) {
                continue;
            }
            bfsQueue.add(newGrid);
            out.add(newGrid);
        }

        int snapshotSize = bfsQueue.size();
        for (int i = 0; i < snapshotSize; i++) {
            bfs2D(null, map2D, markMap, bfsQueue, out);
        }

    }

    private static boolean isCanGo(Map map, Map2DKey newGrid) {
        return !map.getOrDefault(newGrid, false);
    }

    private static boolean isComeHere(Map markMap, Map2DKey newGrid) {
        return markMap.getOrDefault(newGrid, false);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy