예제 #1
0
    public Tile[] FillArea(Tile[] outerPoint)
    {
        if (outerPoint.Length > 2)
        {
            TileArray perimeter           = new TileArray();
            SearchAbleArray <Tile> corner = new SearchAbleArray <Tile>();
            for (int i = 0; i < outerPoint.Length; i++)
            {
                int nextPoint = i + 1;
                if (nextPoint == outerPoint.Length)
                {
                    nextPoint = 0;
                }
                Tile[] tempPerimeter = GetBestPath(outerPoint[i], outerPoint[nextPoint], PathType.IgnoreAll);
                int    precedingIndex;
                int    afterIndex;
                if (nextPoint == 0)
                {
                    precedingIndex = outerPoint.Length - 1;
                }
                else
                {
                    precedingIndex = nextPoint - 1;
                }
                if (nextPoint == outerPoint.Length - 1)
                {
                    afterIndex = 0;
                }
                else
                {
                    afterIndex = nextPoint + 1;
                }
                while (outerPoint[afterIndex].GetX() == outerPoint[nextPoint].GetX())
                {
                    corner.Add(outerPoint[afterIndex]);
                    if (++afterIndex >= outerPoint.Length)
                    {
                        afterIndex = 0;
                    }
                }
                if ((outerPoint[precedingIndex].GetX() <= outerPoint[nextPoint].GetX() && outerPoint[afterIndex].GetX() <= outerPoint[nextPoint].GetX()) ||
                    (outerPoint[precedingIndex].GetX() >= outerPoint[nextPoint].GetX() && outerPoint[afterIndex].GetX() >= outerPoint[nextPoint].GetX()))
                {
                    corner.Add(outerPoint[nextPoint]);
                }
                for (int j = 0; j < tempPerimeter.Length; j++)
                {
                    //if the end tile just addhave already assigned a corner or not
                    if (j == tempPerimeter.Length - 1)
                    {
                        perimeter.AddTile(tempPerimeter[j]);
                    }
                    //else if not the startTile
                    else if (j != 0)
                    {
                        //if it is inline with the following tile or with the endTile
                        int  temp1 = tempPerimeter[j].GetX();
                        int  temp2 = tempPerimeter[j + 1].GetX();
                        bool temp3 = (tempPerimeter[j].GetX() == tempPerimeter[j + 1].GetX());
                        if (tempPerimeter[j].GetX() == tempPerimeter[j + 1].GetX() ||
                            (tempPerimeter[j].GetX() == outerPoint[nextPoint].GetX() && corner.Contains(outerPoint[nextPoint])))
                        {
                            corner.Add(tempPerimeter[j]);
                        }
                        perimeter.AddTile(tempPerimeter[j]);
                    }
                }
            }
            Tile[] area = new Tile[0];
            for (int i = 0; i < perimeter.GetAmountofRows(); i++)
            {
                Tile[] rowArray = perimeter.IterateThroughRows(i);
                for (int j = 0; j < rowArray.Length; j++)
                {
                    if (!corner.Contains(rowArray[j]))
                    {
                        Tile currTile = rowArray[j];
                        Tile endTile  = rowArray[j + 1];
                        while (corner.Contains(endTile))
                        {
                            j++;
                            endTile = rowArray[j + 1];
                        }
                        for (int k = currTile.GetY(); k <= endTile.GetY(); k++)
                        {
                            Position currPos = new Position(currTile.GetX(), k);
                            TestMain.AddElement <Tile>(ref area, GetTile(currPos));
                        }

                        j++;
                    }
                    else
                    {
                        TestMain.AddElement <Tile>(ref area, rowArray[j]);
                    }
                }
            }
            return(area);
        }
        else
        {
            return(null);
        }
    }
예제 #2
0
    public KeyValuePair <float, Tile[]> GetDijkstraPath(Tile source, Tile destination, PathType givenPathType)
    {
        bool pathFound = false;
        int  count     = 0;

        Tile[] bestPath = new Tile[0];
        float  distance = -1;

        float[][]              distanceMap     = new float[MAPWIDTH][];
        Position?[][]          previousTilePos = new Position?[MAPWIDTH][];
        SearchAbleArray <Tile> queue           = new SearchAbleArray <Tile>();
        SearchAbleArray <Tile> diagonalQueue   = new SearchAbleArray <Tile>();
        SearchAbleArray <Tile> sidewaysQueue   = new SearchAbleArray <Tile>();
        SearchAbleArray <Tile> backwardsQueue  = new SearchAbleArray <Tile>();
        TileArray              explored        = new TileArray();

        queue.Add(source);
        for (int i = 0; i < MAPWIDTH; i++)
        {
            distanceMap[i]     = new float[MAPHEIGHT];
            previousTilePos[i] = new Position?[MAPHEIGHT];
            for (int j = 0; j < MAPHEIGHT; j++)
            {
                distanceMap[i][j]     = -1;
                previousTilePos[i][j] = null;
            }
        }
        previousTilePos[source.GetX()][source.GetY()] = new Position(source.GetX(), source.GetY());
        distanceMap[source.GetX()][source.GetY()]     = 0;
        while ((queue.GetSize() > 0 || sidewaysQueue.GetSize() > 0 || backwardsQueue.GetSize() > 0) && !pathFound)
        {
            Tile[] currQueueArray;
            SearchAbleArray <Tile> currentQueue;
            if (queue.GetSize() > 0)
            {
                currentQueue = queue;
            }
            else if (diagonalQueue.GetSize() > 0)
            {
                currentQueue = diagonalQueue;
            }
            else if (sidewaysQueue.GetSize() > 0)
            {
                currentQueue = sidewaysQueue;
            }
            else
            {
                currentQueue = backwardsQueue;
            }
            currQueueArray = currentQueue.GetOrderedArray();
            Tile  currentElement   = currQueueArray[0];
            float minQueueDistance = distanceMap[currQueueArray[0].GetX()][currQueueArray[0].GetY()];
            for (int i = 0; i < currQueueArray.Length; i++)
            {
                if (distanceMap[currQueueArray[i].GetX()][currQueueArray[i].GetY()] < minQueueDistance)
                {
                    currentElement = currQueueArray[i];
                }
            }
            explored.AddTile(currentElement);
            if (currentElement == destination)
            {
                pathFound = true;
            }
            else
            {
                Tile[] queueAdjacent = GetAdjacent(currentElement, destination);

                for (int i = 0; i < queueAdjacent.Length; i++)
                {
                    float currToNextTravelDistance = GetAdjacentTravelDistance(currentElement, queueAdjacent[i], givenPathType);
                    if (currToNextTravelDistance > 0)
                    {
                        if (previousTilePos[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()] == null)
                        {
                            if (i < 1)
                            {
                                queue.Add(queueAdjacent[i]);
                            }
                            else if (i < 3)
                            {
                                diagonalQueue.Add(queueAdjacent[i]);
                            }
                            else if (i < 5)
                            {
                                sidewaysQueue.Add(queueAdjacent[i]);
                            }
                            else
                            {
                                backwardsQueue.Add(queueAdjacent[i]);
                            }
                            float alteredDistance = distanceMap[currentElement.GetX()][currentElement.GetY()] + currToNextTravelDistance;
                            if (distanceMap[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()] < 0 || alteredDistance < distanceMap[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()])
                            {
                                distanceMap[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()]     = alteredDistance;
                                previousTilePos[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()] = new Position(currentElement.GetX(), currentElement.GetY());
                            }
                        }
                    }
                }
            }
            currentQueue.Remove(currentElement);
        }
        Tile[] tempBestPath = new Tile[0];
        Tile   previousTile = destination;

        do
        {
            if (previousTilePos[previousTile.GetX()][previousTile.GetY()] != null)
            {
                TestMain.AddElement <Tile>(ref tempBestPath, previousTile);
                previousTile = GetTile((Position)previousTilePos[previousTile.GetX()][previousTile.GetY()]);
            }
            else
            {
                throw new NoPathException("There is no path between " + source + " and " + destination + " when travelling by " + givenPathType);
            }
        }while (previousTile != source);
        if (tempBestPath.Length > 5)
        {
            Debug.Log("cool");
        }
        TestMain.AddElement <Tile>(ref tempBestPath, source);
        bestPath = new Tile[tempBestPath.Length];
        for (int i = tempBestPath.Length - 1; i >= 0; i--)
        {
            bestPath[i] = tempBestPath[i];
        }
        return(new KeyValuePair <float, Tile[]>(distance, bestPath));
    }