Esempio n. 1
0
        public int AStarBinarySearch(List<AStarTile> openList, AStarTile tileToInsert)
        {
            //            List<AStarTile> list = openList; //The AStarTile list to consider
            //            AStarTile tile = tileToInsert; //The tile to insert
            //            bool done = false; //Loop condition
            //            int min = 0; //The minimum index number to look at
            //            int max = list.Count - 1; //The maximum index number to look at
            //            int range = max - min; //The range between max and min
            //
            //            int f = tile.f; //The f cost to insert and compare with
            //            //bool totalIsEven; //Whether the number of insert points is even or odd
            //            //if ((range + 1) % 2 == 0) //If insert points is even
            //            //{
            //            //    totalIsEven = true;
            //            //}
            //            //else //If odd
            //            //{
            //            //    totalIsEven = false;
            //            //}
            //
            //            while (!done) //Loop until done with the search
            //            {
            //                if (list.Count == 0) //If nothing's there, then obviously the new Tile will have the lowest f cost
            //                {
            //                    done = true; //Nothing's there already, so we're done
            //                }
            //
            //                if (list.Count == 1)
            //                {
            //                    if (f < list[0].f)
            //                    {
            //                        indexToInsertAt = 0;
            //                    }
            //                    else if (f > list[0].f)
            //                    {
            //                        indexToInsertAt = 1;
            //                    }
            //                    else
            //                    {
            //                        indexToInsertAt = random.Next(0, 1);
            //                    }
            //                }
            //
            //                if (list.Count == 2)
            //                {
            //
            //                }
            //            }

            return -1; //Error if it gets here
        }
Esempio n. 2
0
        public Stack<byte> AStarPathfind(Creature creature, Vector2 pointA, Vector2 pointB)
        {
            Stack<byte> path = new Stack<byte>();

            if (ConvertAbsolutePosToRelative(pointA, pointB) > 0)
            {
                path.Push((byte)ConvertAbsolutePosToRelative(pointA, pointB));
                return path;
            }

            if (pointA.X == pointB.X && pointA.Y == pointB.Y)
            {
                path.Push(5);
                return path;
            }

            #region Variables
            //int g = 0;
            //int h = (int)(Math.Abs(pointB.X - pointA.X) + (int)Math.Abs(pointB.Y - pointA.Y));
            bool done = false;
            AStarTile currentTile = new AStarTile(pointA, new Vector2(-1, -1), 0,
                100 * ((int)(Math.Abs(pointB.X - pointA.X) + (int)Math.Abs(pointB.Y - pointA.Y))));
            List<AStarTile> openList = new List<AStarTile>();
            List<AStarTile> closedList = new List<AStarTile>();
            #endregion

            openList.Add(currentTile); //Add the current tile

            while (!done)
            {
                #region Find new current tile
                currentTile = openList[0]; //The lowest F cost tile is the current tile
                openList.RemoveAt(0); //Removed from the open list
                closedList.Add(currentTile); //And placed in the closed list
                #endregion

                if (currentTile.pos == pointB) //If target has been just added to closed list
                {
                    done = true;
                }

                #region Define adjacent vectors
                Vector2[] adjacent = new Vector2[8];
                adjacent[0] = new Vector2(currentTile.pos.X - 1, currentTile.pos.Y + 1); //Adjacent tile at position 1
                adjacent[1] = new Vector2(currentTile.pos.X, currentTile.pos.Y + 1);     //Adjacent tile at position 2
                adjacent[2] = new Vector2(currentTile.pos.X + 1, currentTile.pos.Y + 1); //Adjacent tile at position 3
                adjacent[3] = new Vector2(currentTile.pos.X - 1, currentTile.pos.Y);     //Adjacent tile at position 4
                adjacent[4] = new Vector2(currentTile.pos.X + 1, currentTile.pos.Y);     //Adjacent tile at position 6
                adjacent[5] = new Vector2(currentTile.pos.X - 1, currentTile.pos.Y - 1); //Adjacent tile at position 7
                adjacent[6] = new Vector2(currentTile.pos.X, currentTile.pos.Y - 1);     //Adjacent tile at position 8
                adjacent[7] = new Vector2(currentTile.pos.X + 1, currentTile.pos.Y - 1); //Adjacent tile at position 9
                #endregion

                #region Process adjacent tiles to Current Tile
                for (int i = 0; i <= 7; i++) // the adjacent tiles 0-7, all 8
                {
                    if (adjacent[i].X < 0 || adjacent[i].X > GRIDW-1 || adjacent[i].Y < 0 || adjacent[i].Y > GRIDH-1)
                    {
                        i++;
                        break;
                    }

                    bool shouldBeOpen = true;
                    bool isAlreadyOpen = false;
                    bool closedDoor = false; //Whether this tile has a door in it.
                    int indexOnOpen = -1;

                    //if (tileArray[(int)adjacent[i].X, (int)adjacent[i].Y].fixtureLibrary.Count > 0)
                    //{
                    //    foreach (Fixture fixture in tileArray[(int)adjacent[i].X, (int)adjacent[i].Y].fixtureLibrary)
                    //    {
                    //        if (fixture is Door) //If it's a door
                    //        {
                    //            Door door = (Door)fixture;
                    //            if (!door.isOpen) //If the door is closed
                    //                closedDoor = true;
                    //        }
                    //    }
                    //}

                    if (tileArray[(int)adjacent[i].X, (int)adjacent[i].Y] == null)
                    {
                        shouldBeOpen = false;
                    }
                    else if (this.tileArray[(int)adjacent[i].X, (int)adjacent[i].Y].isPassable == false &&
                        !(closedDoor && creature.isDextrous)) //If not passable
                    {
                        shouldBeOpen = false; //It's not a candidate if not blocked by door
                    }
                    else //If passable
                    {
                        foreach (AStarTile j in closedList) //For each closedList item
                        {
                            if (j.pos == adjacent[i]) //If a closedList item is the same as the potential tile
                            {
                                shouldBeOpen = false; //Not a candidate
                            }
                        }

                        foreach (Creature c in creatures)
                            if (c.pos == adjacent[i] && adjacent[i] != pointB) //If a creature is in the way
                                shouldBeOpen = false;

                        int openListCount = openList.Count;
                        for (int j = 0; j < openListCount; j++)
                        {
                            if (openList[j].pos == adjacent[i]) //If an openList item is the same as the potential tile
                            {
                                isAlreadyOpen = true; //Mark it as already on the open list
                                indexOnOpen = j;
                            }
                        }
                    }

                    if (shouldBeOpen) //If it should go on the open list
                    {
                        int g = 100; //Weight of tile ***IMPROVE THIS LATER***
                        int h = 100 * ((int)(Math.Abs(pointB.X - adjacent[i].X) + (int)Math.Abs(pointB.Y - adjacent[i].Y))); //Heuristic guess
                        //int f = g + h; //Definition of f cost
                        AStarTile newTile = new AStarTile(adjacent[i], currentTile.pos, currentTile.g + g, h, g); //Make an official tile for it

                        if (isAlreadyOpen) //If already on the open list
                        {
                            if (newTile.g < openList[indexOnOpen].g) //If this path to the tile is cheaper than its previous g
                            {
                                openList[indexOnOpen] = newTile; //Overwrite its old info with this cheaper info
                            }
                        }

                        else
                        {
                            openList.Insert(AStarSequentialSearch(openList, newTile), newTile); //Insert in openList a sequential search according to f cost

                            //Calculate where this new tile should go with a binary search. ***UNFINISHED***
                            //AStarBinarySearch(openList, newTile);
                        }
                    }
                }
                if (openList.Count == 0) //If no more tiles to look at, there's no path
                {
                    path.Push(0);
                    return path;
                }
                #endregion
            }

            #region Trace back to starting tile
            int oldIndex = -1;
            int index = 0;

            while (currentTile.parentpos != new Vector2(-1, -1)) //Until parent is starting tile
            {
                int closedListCount = closedList.Count;
                for (int j = 0; j < closedListCount; j++)
                {
                    if (closedList[j].pos == currentTile.parentpos)
                    {
                        oldIndex = index;
                        index = j;
                        path.Push((byte)ConvertAbsolutePosToRelative(closedList[index].pos, currentTile.pos));
                        break;
                    }
                }

                currentTile = closedList[index];
            }
            #endregion

            currentTile = closedList[oldIndex];

            openList.Clear();
            closedList.Clear();
            return path;
        }
Esempio n. 3
0
        public static int AStarSequentialSearch(List<AStarTile> openList, AStarTile tileToInsert)
        {
            int max = openList.Count - 1;

            if (openList.Count == 0) //If the list is empty
            {
                return 0; //Insert at zero, since nothing's there to mess up
            }

            if (openList.Count == 1)
            {
                if (tileToInsert.f < openList[0].f)
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            }

            for (int i = 0; i <= max; i++)
            {
                if (i == max) //If at the far right of the list
                {
                    if (tileToInsert.f >= openList[i].f) //newtile.f > farrightnumber.f
                    {
                        return i + 1; //Insert it just to the right of the max number, bumping nothing
                    }
                    else
                    {
                        return i;
                    }
                }
                else if (i == 0) //If at the far left of the list
                {
                    if (tileToInsert.f <= openList[i].f) //newtile.f < farleftnumber.f
                    {
                        return 0; //Insert it at index zero, bumping everything to the right one
                    }
                    else
                    {
                        return 1;
                    }
                }
                else
                {
                    if (openList[i - 1].f < tileToInsert.f && tileToInsert.f <= openList[i].f) //If between two
                    {
                        return i; //Bump everything it's less than to the right.
                    }
                }
            }
            return -1; //Error if it makes it here
        }