Esempio n. 1
0
    public IEnumerator <YieldInstruction> CalculatePath()
    {
        if (Running)
        {
            yield break;
        }

        Running    = true;
        MasterPath = new Dictionary <int, Dictionary <int, Path> >();

        //for each entrance find path to every exit
        foreach (int i in Entrances)
        {
            Square     startSquare     = Grid.squares[i];
            Vector2Int dirFromEntrance = new Vector2Int(0, 1);

            if (GridUtilities.IsLeft(i))
            {
                dirFromEntrance = new Vector2Int(1, 0);
            }
            else if (GridUtilities.IsRight(i))
            {
                dirFromEntrance = new Vector2Int(-1, 0);
            }
            else if (GridUtilities.IsTop(i))
            {
                dirFromEntrance = new Vector2Int(0, -1);
            }
            else if (!GridUtilities.IsBottom(i))
            {
                Debug.Log("Enterance must be on edge of board");
            }

            startSquare = GridUtilities.GetNextSquare(startSquare, dirFromEntrance);

            if (startSquare.hasBox)
            {
                Debug.LogWarning("Enterance not valid");
                continue;
            }

            Dictionary <int, Path> currentPath = new Dictionary <int, Path>();
            foreach (int j in Exits)
            {
                Branches        = 0;
                MaxPath         = (Grid.width - 2) * (Grid.height - 2) + 2;
                LowestTotalPath = MaxPath;

                PathIds = new List <int>();

                Path head = new Path();

                Square current = startSquare;
                endSquare = Grid.squares[j];

                head.Current       = startSquare;
                head.FutureSquares = new List <Path>();

                Path newPath = new Path(current, head);
                head.FutureSquares.Add(newPath);

                forward = dirFromEntrance;
                if (GridUtilities.IsLeft(j))
                {
                    forward = new Vector2Int(-1, 0);
                }
                else if (GridUtilities.IsRight(j))
                {
                    forward = new Vector2Int(1, 0);
                }
                else if (GridUtilities.IsTop(j))
                {
                    forward = new Vector2Int(0, 1);
                }
                else if (GridUtilities.IsBottom(j))
                {
                    forward = new Vector2Int(0, -1);
                }
                else
                {
                    Debug.LogError("Exit must be on edge of board");
                }

                Square squareNextToExit = GridUtilities.GetNextSquare(endSquare, -forward);

                if (squareNextToExit.hasBox)
                {
                    Debug.LogWarning("Exit not valid");
                    continue;
                }

                left      = new Vector2Int(-forward.y, forward.x);
                diagLeft  = left + forward;
                right     = -left;
                diagRight = right + forward;
                back      = -forward;

                DownPath(newPath, 1, dirFromEntrance);

                if (newPath.FutureSquares.Count == 0)
                {
                    Debug.LogWarning($"No routes where found to exit {endSquare.gridCoord}");
                }
                else
                {
                    currentPath.Add(j, head);
                }

                yield return(null);
            }

            if (currentPath.Count != 0)
            {
                //add all paths from current entrance to all exits
                MasterPath.Add(i, currentPath);
            }
        }

        Running = false;
    }
Esempio n. 2
0
    Path DownPath(Path currentPath, int pathInt, Vector2Int lastTime)
    {
        pathInt++;

        if (pathInt > MaxPath)
        {
            return(null);
        }
        if (Branches >= MaxBranch)
        {
            return(null);
        }

        Vector2Int coord   = currentPath.Current.gridCoord;
        Square     current = currentPath.Current;

        if (coord == endSquare.gridCoord)
        {
            if (pathInt < LowestTotalPath)
            {
                MaxPath         = (int)(pathInt * 1.2f);
                LowestTotalPath = pathInt;
            }
            Branches++;
            return(currentPath);
        }

        Vector2Int difCoord = coord - endSquare.gridCoord;
        int        diff     = Mathf.Abs(difCoord.x) + Mathf.Abs(difCoord.y);

        if (pathInt + diff > MaxPath)
        {
            return(null);
        }

        PathIds.Add(GridUtilities.TwoToOne(coord));

        //squares on the edge of the map should either be boxes or
        //enterances/exits so there's no point in us checking them
        //if the straight distance to the exit will make out path too
        //long we shouldn't bother checking it either
        if (GridUtilities.IsOnEdge(current))
        {
            return(null);
        }

        if (RightIsBetter(current.gridCoord, endSquare.gridCoord, right))
        {
            Vector2Int temp = right;
            right = left;
            left  = temp;

            temp      = diagRight;
            diagRight = diagLeft;
            diagLeft  = temp;
        }

        Square forwardSquare       = GridUtilities.GetNextSquare(current, forward);
        Square leftSquare          = GridUtilities.GetNextSquare(current, left);
        Square diagLeftSquare      = GridUtilities.GetNextSquare(current, diagLeft);
        Square diagBackLeftSquare  = GridUtilities.GetNextSquare(current, -diagRight);
        Square rightSquare         = GridUtilities.GetNextSquare(current, right);
        Square diagRightSquare     = GridUtilities.GetNextSquare(current, diagRight);
        Square diagBackRightSquare = GridUtilities.GetNextSquare(current, -diagLeft);
        Square backSquare          = GridUtilities.GetNextSquare(current, back);

        currentPath.FutureSquares = new List <Path>();

        //FORWARD
        if (back != lastTime)
        {
            CheckNextPath(ref currentPath, forwardSquare, pathInt, forward);
        }
        //LEFT
        if (CheckDirection(left, forwardSquare, diagLeftSquare, lastTime, coord))
        {
            CheckNextPath(ref currentPath, leftSquare, pathInt, left);
        }
        //RIGHT
        if (CheckDirection(right, forwardSquare, diagRightSquare, lastTime, coord))
        {
            CheckNextPath(ref currentPath, rightSquare, pathInt, right);
        }
        //BACK
        if (forward != lastTime &&
            ((leftSquare != null && leftSquare.hasBox) ||
             (rightSquare != null && rightSquare.hasBox) ||
             (diagBackLeftSquare != null && diagBackLeftSquare.hasBox) ||
             (diagBackRightSquare != null && diagBackRightSquare.hasBox)))
        {
            CheckNextPath(ref currentPath, backSquare, pathInt, back);
        }

        PathIds.Remove(GridUtilities.TwoToOne(coord));

        if (currentPath.FutureSquares.Count > 0)
        {
            return(currentPath);
        }

        return(null);
    }