Пример #1
0
        /// <summary>
        /// Get the Command.Move direction that moves from fromsq to tosq,
        /// or null if none exists.
        /// </summary>
        Command.Move GetMoveDirection(PathSquare fromsq, PathSquare tosq)
        {
            if (fromsq.X == tosq.X)
            {
                if (fromsq.Y == tosq.Y - 1)
                {
                    return(Command.Move.Up);
                }
                else if (fromsq.Y == tosq.Y + 1)
                {
                    return(Command.Move.Down);
                }
            }
            else if (fromsq.Y == tosq.Y)
            {
                if (fromsq.X == tosq.X - 1)
                {
                    return(Command.Move.Right);
                }
                else if (fromsq.X == tosq.X + 1)
                {
                    return(Command.Move.Left);
                }
            }

            return(Command.Move.Stay); // no legal move from fromsq to tosq
        }
Пример #2
0
        /// <summary>
        /// Move along MyPath - always turn to face the direction of travel (or else I can get stuck
        /// behind a block that I cannot see).
        /// Return false if this move is likely to fail because the next square is blocked
        /// </summary>
        public bool MoveAlongMyPath()
        {
            if (MyPath != null && MyPathIndex < MyPath.Count) // not yet at end of path
            {
                PathSquare nextsquare = MyPath[MyPathIndex];
                if (nextsquare.IsBlocked)
                {
                    return(false); // next square is blocked so find a new path
                }
                Command.Move dir = GetMoveDirection(nextsquare.Parent, nextsquare);
                Command.Move rot = GetMoveRotation(dir);
                if (rot != Command.Move.Stay)
                {
                    MyCommand = new Command(rot, false); // rotate to face direction of travel
                }
                else
                {
                    MyCommand = new Command(dir, false); // move along path
                    MyPathIndex++;                       // so go to next square of path
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #3
0
 /// <summary>
 /// Check whether the path from parent to P is cheaper than the current path, for P on the open list.
 /// Note parent must be adjacent to P.
 /// </summary>
 /// <param name="P"></param>
 /// <param name="parent"></param>
 public void UpdateOpenListEntry(PathSquare P, PathSquare parent)
 {
     if (P.G > parent.G + 1)
     {
         P.Parent = parent;
         P.G      = parent.G + 1;
     }
 }
Пример #4
0
        /// <summary>
        /// Finds a path from grid square (fromX,fromY) to grid square (toX,toY), avoiding all fixed
        /// obstacles, and returns the result as an ArrayList. The start and finish points are not included
        /// in the path (since the start point will usually be an Ant and the finish point will usually
        /// be food, and anthill or another ant).
        /// </summary>
        /// <param name="fromX">The X co-ordinate of the start square.</param>
        /// <param name="fromY">The Y co-ordinate of the start square.</param>
        /// <param name="toX">The X co-ordinate of the target square.</param>
        /// <param name="toY">The Y co-ordinate of the target square.</param>
        /// <returns>Returns an ArrayList storing the path, if one has been found, or null otherwise.
        /// This ArrayList is also held in the Path class variable.</returns>
        public List <PathSquare> FindPath(int fromX, int fromY, int toX, int toY)
        {
            if (GetEstimatedDistance(fromX, fromY, toX, toY) == 0)
            {
                return(new List <PathSquare>()); // already at goal so return empty path
            }
            // New path so increment this so that marks in Map[,] can be distinguished from those
            // of previous paths.
            PathIndex++;

            // Note that if you change terrain without reloading your AI the Map will
            // not be updated and you will get (weird!) results for the previous terrain.

            // set the target square - we want to get adjacent to this square.
            TargetSquare = MyMap[toX, toY];

            // label destination square. Note that there can be more than one, but here, only one is considered.
            MyMap[toX, toY].G            = -1;
            MyMap[toX, toY].H            = 1;
            MyMap[toX, toY].IsGoal       = PathIndex; // this square is a goal for this path.
            MyMap[toX, toY].OnClosedList = -1;
            MyMap[toX, toY].OnOpenList   = -1;
            MyMap[toX, toY].Parent       = null;

            // set the start square - the first square the the path will be adjacent
            // to this square.
            StartSquare = MyMap[fromX, fromY];

            StartSquare.G = 0; // Distance from StartSquare to StartSquare is zero
            StartSquare.H = GetEstimatedDistanceToGoal(StartSquare);

            // Now initialise the OpenList with the neighbours of StartSquare
            // and put StartSquare on the closed list.
            List <PathSquare> fromsq = GetReachableNeighbours(fromX, fromY);

            if (fromsq.Count == 0)
            {
                return(null); // no reachable squares adjacent to (fromX, fromY)
            }
            OpenList.Clear();
            foreach (PathSquare ps in fromsq)
            {
                if (ps.IsGoal == PathIndex)
                {
                    // path (of length 1) found.
                    ps.Parent = StartSquare;
                    List <PathSquare> path = new List <PathSquare>();
                    path.Add(ps);
                    return(path);
                }

                AddToOpenList(ps, StartSquare);
            }

            StartSquare.OnClosedList = PathIndex; // Put StartSquare on closed list

            return(AStarSearch());                // search for the path.
        }
Пример #5
0
 /// <summary>
 /// Finds a path to the destination square and set the A* object to move along that path.
 /// </summary>
 private void FindAndMoveAlongPath(int x1, int y1, int x2, int y2)
 {
     aStar.MyPath = aStar.FindPath(x1, y1, x2, y2); // find a path
     if (aStar.MyPath != null)                      // path exists
     {
         TargetSquare      = MyMap[x2, y2];         // (x,y) is unseen
         aStar.MyPathIndex = 0;
         aStar.MoveAlongMyPath();
         return;
     }
 }
Пример #6
0
 /// <summary>
 /// Is square S on the open list of squares will be investigated soon?
 /// </summary>
 private bool IsOnOpenList(PathSquare S)
 {
     if (S.OnOpenList == PathIndex)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Пример #7
0
        /// <summary>
        /// Saves the current path to ArrayList Path.
        /// </summary>
        /// <param name="S"></param>
        private List <PathSquare> SavePath(PathSquare goal)
        {
            List <PathSquare> path = new List <PathSquare>();
            PathSquare        p    = goal;

            while (p.Parent.G > 0)
            {
                path.Insert(0, p);
                p = p.Parent;
            }

            path.Insert(0, p);

            return(path);
        }
Пример #8
0
        /// <summary>
        /// Add a PathSquare to the correct sorted position on the open list, and update the PathSquare's data.
        /// P and parent are guaranteed to be adjacent.
        /// </summary>
        public void AddToOpenList(PathSquare P, PathSquare parent)
        {
            P.G            = parent.G + 1;
            P.H            = GetEstimatedDistanceToGoal(P);
            P.OnClosedList = -1;
            P.OnOpenList   = PathIndex;
            P.Parent       = parent;

            int i;

            for (i = 0; i < OpenList.Count; i++)
            {
                PathSquare ps = (PathSquare)OpenList[i];
                if (ps.F >= P.F)
                {
                    break;
                }
            }

            OpenList.Insert(i, P); // insert in sorted position
        }
Пример #9
0
        /// <summary>
        /// Finds a new unseen square. Gets all the unseen squares and choose one randomly.
        /// </summary>
        private void FindUnseenSquare()
        {
            List <PathSquare> SquaresNotSeen = new List <PathSquare>();

            foreach (var square in MyMap)
            {
                if (MyMap[square.X, square.Y].HasBeenSeen == false)
                {
                    SquaresNotSeen.Add(square);
                }
            }

            if (SquaresNotSeen.Count > 0)
            {
                PathSquare Location = SquaresNotSeen[new Random().Next(SquaresNotSeen.Count)];
                FindAndMoveAlongPath(MyWorldState.MyGridSquare.X, MyWorldState.MyGridSquare.Y, Location.X, Location.Y);
            }
            else
            {
                FindAndMoveAlongPath(MyWorldState.MyGridSquare.X, MyWorldState.MyGridSquare.Y, MyWorldState.MyGridSquare.X, MyWorldState.MyGridSquare.Y);
            }
        }
Пример #10
0
 /// <summary>
 /// Get an optimistic estimate of the distance from P to TargetSquare.
 /// The estimate assumes that there is no terrain blocking the path.
 /// </summary>
 public int GetEstimatedDistanceToGoal(PathSquare P)
 {
     return(Math.Abs(TargetSquare.X - P.X) + Math.Abs(TargetSquare.Y - P.Y)); // x distance + y distance
 }