public void Play()
    {
        //Sanitize the input
        OptionsController.instance.MapSize = Mathf.Max(mapSize.text == "" ? OptionsController.instance.defaultMapSize : int.Parse(mapSize.text), 2);
        int MapSizeLocal = OptionsController.instance.MapSize;

        OptionsController.instance.XStart = Mathf.Clamp(startX.text == "" ? OptionsController.instance.defaultXStart : int.Parse(startX.text), 0, OptionsController.instance.MapSize - 1);
        OptionsController.instance.YStart = Mathf.Clamp(startY.text == "" ? OptionsController.instance.defaultYStart : int.Parse(startY.text), 0, OptionsController.instance.MapSize - 1);

        OptionsController.instance.XEnd = Mathf.Clamp(endX.text == "" ? OptionsController.instance.defaultXEnd : int.Parse(endX.text), 0, OptionsController.instance.MapSize - 1);
        OptionsController.instance.YEnd = Mathf.Clamp(endY.text == "" ? OptionsController.instance.defaultYEnd : int.Parse(endY.text), 0, OptionsController.instance.MapSize - 1);

        int distanceFromStartToEnd = PathfinderHelper.ManhattanDistance(OptionsController.instance.XStart, OptionsController.instance.YStart, OptionsController.instance.XEnd, OptionsController.instance.YEnd);

        OptionsController.instance.NumberOfObstacles = Mathf.Clamp(numberOfObstacles.text == "" ? OptionsController.instance.defaultNumberOfObstacles : int.Parse(numberOfObstacles.text), 0, MapSizeLocal * MapSizeLocal - distanceFromStartToEnd + 1);

        //load the simulation scene
        SceneManager.LoadScene("SimulationScene");
    }
    private void GenerateMap()
    {
        //Generate map filled with blockers
        List <Vector2Int> blockers = new List <Vector2Int>();

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                map[i, j] = TileType.Blocked;
                blockers.Add(new Vector2Int(i, j));
            }
        }

        //Here we "dig" through blocked, generating a random path that is always guided towards the end.
        //This effectivelly removes minimum number of blockers to ensure the path exists
        int StartEndDistance = PathfinderHelper.ManhattanDistance(StartX, StartY, EndX, EndY);
        int xOffset          = EndX - StartX;
        int yOffset          = EndY - StartY;

        int DigX = 0;
        int DigY = 0;

        Random.InitState(System.DateTime.Now.Second);
        map[StartX, StartY] = TileType.Free;
        blockers.Remove(new Vector2Int(StartX, StartY));

        for (int i = 0; i < StartEndDistance; i++)
        {
            if (Random.value < 0.5)
            {
                if (xOffset == 0)
                {
                    if (yOffset > 0)
                    {
                        DigY++;
                        yOffset--;
                    }
                    if (yOffset < 0)
                    {
                        DigY--;
                        yOffset++;
                    }
                }
                else
                {
                    if (xOffset > 0)
                    {
                        DigX++;
                        xOffset--;
                    }
                    if (xOffset < 0)
                    {
                        DigX--;
                        xOffset++;
                    }
                }
            }
            else
            {
                if (yOffset == 0)
                {
                    if (xOffset > 0)
                    {
                        DigX++;
                        xOffset--;
                    }
                    if (xOffset < 0)
                    {
                        DigX--;
                        xOffset++;
                    }
                }
                else
                {
                    if (yOffset > 0)
                    {
                        DigY++;
                        yOffset--;
                    }
                    if (yOffset < 0)
                    {
                        DigY--;
                        yOffset++;
                    }
                }
            }
            map[StartX + DigX, StartY + DigY] = TileType.Free;
            blockers.Remove(new Vector2Int(StartX + DigX, StartY + DigY));
        }


        //Randomly remove blockers so that only specified amount is left
        int numBlockersToRemove = n * n - OptionsController.instance.NumberOfObstacles - StartEndDistance - 1;

        for (int i = 0; i < numBlockersToRemove; i++)
        {
            int        indexToRemove   = Random.Range(0, blockers.Count - 1);
            Vector2Int elementToRemove = blockers[indexToRemove];
            map[elementToRemove.x, elementToRemove.y] = TileType.Free;
            blockers.RemoveAt(indexToRemove);
        }
    }
Example #3
0
    public void GreedyManhattanAlgorithm(Vector2Int start, Vector2Int end)
    {
        Queue <Vector2Int> frontier = new Queue <Vector2Int>();

        frontier.Enqueue(start);

        Dictionary <Vector2Int, Vector2Int> cameFrom = new Dictionary <Vector2Int, Vector2Int>();

        cameFrom.Add(start, start);

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

        while (frontier.Count != 0)
        {
            Vector2Int current = frontier.Dequeue();

            visited.Add(current);
            pathFollowed.Add(current);

            List <Vector2Int> neighbours = GetNeighbours(current);

            Vector2Int cameFromLocal;
            cameFrom.TryGetValue(current, out cameFromLocal);

            neighbours.Remove(cameFromLocal);

            //Remove visited neighbours
            List <Vector2Int> neighboursToRemove = new List <Vector2Int>();
            foreach (Vector2Int neighbour in neighbours)
            {
                if (visited.Contains(neighbour))
                {
                    neighboursToRemove.Add(neighbour);
                }
            }
            foreach (Vector2Int neighbour in neighboursToRemove)
            {
                neighbours.Remove(neighbour);
                FoundPath.Remove(current);
            }

            //Sort neighbours so the element closest to the end (Using Manhattan distance) is first
            neighbours.Sort(delegate(Vector2Int a, Vector2Int b)
            {
                int aManhattan = PathfinderHelper.ManhattanDistance(a.x, a.y, end.x, end.y);
                int bManhattan = PathfinderHelper.ManhattanDistance(b.x, b.y, end.x, end.y);

                if (aManhattan > bManhattan)
                {
                    return(1);
                }
                if (aManhattan < bManhattan)
                {
                    return(-1);
                }
                return(0);
            });

            //If there is a neighbour, check him. Otherwise, backtrack
            if (neighbours.Count > 0)
            {
                Vector2Int nextNeighbour = neighbours[0];
                FoundPath.Add(current);
                if (nextNeighbour == end)
                {
                    pathFollowed.Add(nextNeighbour);
                    return;
                }
                else
                {
                    frontier.Enqueue(nextNeighbour);
                    cameFrom.Add(nextNeighbour, current);
                    visited.Add(current);
                }
            }
            else
            {
                frontier.Enqueue(cameFromLocal);
                FoundPath.Remove(current);
            }
        }
    }