Exemplo n.º 1
0
        /// <summary>
        /// returns the edge coordinate between the input tiles
        /// </summary>
        public Vector3Int BetweenNeighbouringTiles(Vector3Int tileA, Vector3Int tileB)
        {
            if (GetTileDistance.Grid(tileA, tileB) != 1)
            {
                throw new System.ArgumentException("Tiles don't have a distance of 1, therefore and not neighbours and share no Edge");
            }
            Vector3Int edgeCoordinate = tileA + tileB;

            if (coordinateWrapper != null)
            {
                edgeCoordinate = coordinateWrapper.WrapEdgeCoordinate(edgeCoordinate);
            }
            return(edgeCoordinate);
        }
        /// <summary>
        /// returns an list of each contiguous border path of the input Tile Coordinates. Each individual path is ordered in clockwise direction with an arbitrary starting point. The different Paths are returned in an arbitrary order
        /// </summary>
        /// ![green = input tiles , blue = result](Map_GetEdges_BorderPaths.png)
        public List <List <Vector3Int> > BorderPaths(IEnumerable <Vector3Int> tiles, out List <List <EdgeDirection> > pathDirections)
        {
            if (coordinateWrapper == null)
            {
                return(HexGrid.GetEdges.BorderPaths(tiles, out pathDirections));
            }

            pathDirections = new List <List <EdgeDirection> >();
            List <List <Vector3Int> > borderPaths    = new List <List <Vector3Int> >();
            List <Vector3Int>         edgesUnordered = TileBorders(tiles);
            HashSet <Vector3Int>      unusedEdges    = new HashSet <Vector3Int>(edgesUnordered); //we remove every edge which we used from this collection to find out which are still left after we finished a path

            //we do it as long as we didn't use all edges because that means we didn't get all paths yet.
            while (unusedEdges.Count > 0)
            {
                List <Vector3Int>    borderPath      = new List <Vector3Int>();
                List <EdgeDirection> borderDirection = new List <EdgeDirection>();
                Vector3Int           topRightEdge    = new Vector3Int();

                //can we just use any edge instead? -> nah we want to ensure it being clockwise...

                int maxYsoFar       = int.MinValue;
                int maxXOfmaxYsoFar = int.MinValue;
                //now we pick one of the top most edges which is parallel to the X-axis of our cube
                foreach (Vector3Int edge in unusedEdges)
                {
                    EdgeAlignment orientation = HexUtility.GetEdgeAlignment(edge);
                    if (orientation != EdgeAlignment.ParallelToCubeX)
                    {
                        continue;
                    }
                    if (edge.y > maxYsoFar)
                    {
                        topRightEdge    = edge;
                        maxXOfmaxYsoFar = edge.x;
                        maxYsoFar       = edge.y;
                    }
                    else if (edge.y == maxYsoFar && edge.x > maxXOfmaxYsoFar)
                    {
                        topRightEdge    = edge;
                        maxXOfmaxYsoFar = edge.x;
                        maxYsoFar       = edge.y;
                    }
                }

                Vector3Int    currentEdge      = topRightEdge;
                EdgeDirection currentDirection = EdgeDirection.BottomRight;
                bool          targetReached    = false;
                int           safety           = 0;

                while (!targetReached)
                {
                    safety++;
                    if (safety > 250)
                    {
                        Debug.Log("safety reached!!! Error in while loop, preventing going infinite");
                        break;
                    }
                    borderPath.Add(currentEdge);
                    borderDirection.Add(currentDirection);
                    unusedEdges.Remove(currentEdge);

                    Vector3Int offsetClockwise                    = HexGrid.ClockWiseNeighbourOfEdgeByEdgeDirection[(int)currentDirection];
                    Vector3Int offsetCounterClockwise             = HexGrid.CounterClockWiseNeighbourOfEdgeByEdgeDirection[(int)currentDirection];
                    Vector3Int potentialClockwiseNeighbour        = coordinateWrapper.WrapEdgeCoordinate(currentEdge + offsetClockwise);
                    Vector3Int potentialCounterClockwiseNeighbour = coordinateWrapper.WrapEdgeCoordinate(currentEdge + offsetCounterClockwise);

                    if (unusedEdges.Contains(potentialCounterClockwiseNeighbour))
                    {
                        currentEdge      = potentialCounterClockwiseNeighbour;
                        currentDirection = (EdgeDirection)((int)(currentDirection + 5) % 6);
                    }
                    else if (unusedEdges.Contains(potentialClockwiseNeighbour))
                    {
                        currentEdge      = potentialClockwiseNeighbour;
                        currentDirection = (EdgeDirection)((int)(currentDirection + 1) % 6);
                    }
                    else //we didn't found any unused edge so we must be at end (change to flag I guess and replace do while with normal while
                    {
                        targetReached = true;
                    }
                }

                borderPaths.Add(borderPath);
                pathDirections.Add(borderDirection);
            }

            for (int i = 1; i < borderPaths.Count; i++)
            {
                borderPaths[i].Reverse();
                pathDirections[i].Reverse();
                for (int j = 0; j < pathDirections[i].Count; j++)
                {
                    pathDirections[i][j] = (EdgeDirection)(((int)pathDirections[i][j] + 3) % 6);
                }
            }
            return(borderPaths);
        }