예제 #1
0
    public static List <Vector2Int> GetNeighbors(Vector2Int pos, MapHandler mapHnd)
    {
        // check that pos is a valid coordinate
        if (pos.x < 0 || pos.x >= mapHnd.mapTileWidth || pos.y < 0 || pos.y >= mapHnd.mapTileHeight)
        {
            return(null);
        }

        List <Vector2Int> neighbors = new List <Vector2Int> ();

        foreach (char s in "NSEW")
        {
            IntPoint newPos = IntPoint.FromCardinal(pos.x, pos.y, s);
            if (mapHnd.CanMove(newPos))
            {
                neighbors.Add(new Vector2Int(newPos.x, newPos.y));
            }
        }

        return(neighbors);
    }
예제 #2
0
    // More accurate BFS lookup
    private List <IntPoint> MakeNewTravelPlan()
    {
        MapHandler mapHnd = MapHandler.GetComponent <MapHandler>();


        // TODO: Allow appearing NEXT to either of these.
        TokenHandler other1 = mapHnd.LeadDate.GetComponent <TokenHandler>();
        TokenHandler other2 = mapHnd.LeadPlayer.GetComponent <TokenHandler>();


        Vector2Int start    = new Vector2Int(TileX, TileY);
        Vector2Int dest     = new Vector2Int(other1.TileX, other1.TileY);
        int        infinity = 100 * 100;

        // Step 1: Make a new array with the "moves from destination" count.
        List <int> lookup = new List <int>();

        for (int i = 0; i < mapHnd.mapTileWidth * mapHnd.mapTileHeight; i++)
        {
            lookup.Add(infinity);
        }

        // Step 1.1: Start at the destination and work outwards
        List <Vector2Int>             todo      = new List <Vector2Int>();
        Dictionary <Vector2Int, bool> blacklist = new Dictionary <Vector2Int, bool>();

        todo.Add(dest);
        blacklist.Add(dest, true);
        lookup [mapHnd.GetTileIndex(dest.x, dest.y)] = 0;
        while (todo.Count > 0)
        {
            // Next tile to consider
            Vector2Int next = todo [0];
            todo.RemoveAt(0);

            // Consider all 4 neighbors
            foreach (char dir in "NSEW")
            {
                IntPoint   newPosI = IntPoint.FromCardinal(next.x, next.y, dir);
                Vector2Int newPos  = new Vector2Int(newPosI.x, newPosI.y);

                // Can we move here normally?
                if (!mapHnd.CanMove(newPosI))
                {
                    continue;
                }

                // Have we already queued up this tile?
                if (blacklist.ContainsKey(newPos))
                {
                    continue;
                }

                // Ok, enqueue it
                todo.Add(newPos);
                blacklist.Add(newPos, true);
                int newDist = lookup [mapHnd.GetTileIndex(next.x, next.y)] + 1;
                lookup [mapHnd.GetTileIndex(newPos.x, newPos.y)] = newDist;

                // TEMP: Useful debugging
                if (false)                   //mapHnd.showDebugMoves
                {
                    mapHnd.debugArray [mapHnd.GetTileIndex(newPos.x, newPos.y)].text = "" + newDist;
                }
            }
        }

        // Step 2: Start from the source, and try to find a path forward.
        // Choose the least-cost pat at east junction, unless there is none.
        List <IntPoint> res  = new List <IntPoint>();
        IntPoint        curr = new IntPoint(start.x, start.y);

        while (true)
        {
            // Are we done?
            if (lookup [mapHnd.GetTileIndex(curr.x, curr.y)] == 1)
            {
                return(res);
            }

            // Find the next jump
            List <IntPoint> options = new List <IntPoint>();
            foreach (char dir in "NSEW")
            {
                IntPoint next = IntPoint.FromCardinal(curr.x, curr.y, dir);
                if (next.x >= 0 && next.x < mapHnd.mapTileWidth && next.y >= 0 && next.y < mapHnd.mapTileHeight)
                {
                    int myDist = lookup [mapHnd.GetTileIndex(next.x, next.y)];
                    if (myDist != infinity)
                    {
                        // Compare it to the current best distance.
                        if (options.Count > 0)
                        {
                            int otherDist = lookup [mapHnd.GetTileIndex(options [0].x, options [0].y)];
                            if (myDist < otherDist)
                            {
                                // It's strictly better
                                options.Clear();
                            }
                            if (myDist <= otherDist)
                            {
                                // It's tied or better (we're considering it)
                                options.Add(next);
                            }
                        }
                        else
                        {
                            // No contest
                            options.Add(next);
                        }
                    }
                }
            }

            // Take it
            if (options.Count > 0)
            {
                IntPoint next = options[GameState.rng.Next(options.Count)];
                res.Add(next);
                curr = next;
            }
            else
            {
                // Shouldn't happen
                break;
            }
        }

        return(null);
    }