Example #1
0
        /// <summary>
        /// The main method of the FloodFill AI.
        /// </summary>
        /// <param name="p"> Point to start/continue the flooding from. </param>
        private void Flood(Point p, int keyIndex, int slidingIndex)
        {
            // If the exit has already been found or we have already visited this tile, stop the flooding.
            if (exitFound || visited[p.X, p.Y, keyIndex, slidingIndex])
            {
                return;
            }

            // GuardTile is subclass of HoleTile so this will return for both.
            // Can't use the same for walls because DoorTile is a subclass of WallTile.
            // Can't use doors for which you don't have the key.
            if (tileField.GetTile(p) is HoleTile ||
                tileField.GetType(p) == TileType.Wall ||
                (tileField.GetType(p) == TileType.Door && (keyIndex & keys[(tileField.GetTile(p) as DoorTile).DoorColor]) == 0))
            {
                return;
            }

            // The current tile has been visited.
            visited[p.X, p.Y, keyIndex, slidingIndex] = true;

            // Add the current tile to the route.
            route.Push(p);

            // If this is the exit, the algorithm is done.
            // Make sure this is after pushing p to route, otherwise you will stand still before the exit.
            if (tileField.GetType(p) == TileType.End)
            {
                exitFound = true;
                return;
            }

            // Check if the current tile is a keytile,
            // and whether we have already picked up a key of this color.
            if (tileField.GetType(p) == TileType.Key)
            {
                // Add the key to the keyIndex
                keyIndex |= keys[(tileField.GetTile(p) as KeyTile).KeyColor];
            }

            // If we're on an ice tile, we need the sliding direction to see if we can change direction.
            if (tileField.GetType(p) == TileType.Ice)
            {
                // Retrieve the current and previous point in the route.
                Point current  = route.Pop();
                Point previous = route.Pop();

                // Calculate the direction you're moving at.
                slidingDirection = current - previous;

                // Return the current and previous point to the route.
                route.Push(previous);
                route.Push(current);
            }

            //If you can move onto the tile behind the ice tile, you can't change direction
            if (tileField.GetType(p) == TileType.Ice &&
                !(tileField.GetTile(p.X + slidingDirection.X, p.Y + slidingDirection.Y) is WallTile))
            {
                //Only keep going in this direction
                Flood(p + slidingDirection, keyIndex, slides[GetDirectionFromPoint(slidingDirection)]);
            }
            // Otherwise we can move in all directions.
            else
            {
                PlayerAction[] action = getActionsInRandomOrder();

                for (int i = 0; i < 5; i++)
                {
                    if (action[i] == PlayerAction.SPECIAL && tileField.GetType(p) == TileType.Portal)
                    {
                        Flood((tileField.GetTile(p) as PortalTile).Destination, keyIndex, 0);
                    }
                    else if (action[i].IsDirection())
                    {
                        // Obstacles are checked earlier in Flood() so we only need to check whether the new point is in the tilefield.
                        if (!tileField.OutOfTileField(p + action[i].ToDirection().ToPoint()))
                        {
                            Flood(p + action[i].ToDirection().ToPoint(), keyIndex, 0);
                        }
                    }
                }
            }

            // All directions are done, return to the previous point.
            // If the exit has been found, keep the route intact.
            if (!exitFound && route.Count > 0)
            {
                route.Pop();
            }
        }