Exemplo n.º 1
0
 /// <summary>
 /// Finds a path. Throws PathNotFoundException when no path can be found.
 /// </summary>
 /// <returns>A finished path.</returns>
 private Dictionary <HashSet <KeyColor>, Dictionary <Point, PlayerAction> > FindPath()
 {
     Level = new AStarLevel(player.TileField);
     Level.SolveLevel();
     if (Level.OptimalPath.Count == 0)
     {
         throw new PathNotFoundException();
     }
     return(Level.OptimalPath);
 }
Exemplo n.º 2
0
        public AStarLevel(AStarLevel oldField, ColoredTile newKey, long score)
        {
            OpenTiles     = new List <AStarTile>();
            PotentialKeys = new HashSet <ColoredTile>();
            ReachedKeys   = new HashSet <ColoredTile>();
            ClosedDoors   = new HashSet <ColoredTile>();
            obtainedKeys  = new HashSet <KeyColor>();
            OptimalPath   = new Dictionary <HashSet <KeyColor>, Dictionary <Point, PlayerAction> >();

            Field = new AStarTile[oldField.Field.GetLength(0), oldField.Field.GetLength(1)];
            for (int x = 0; x < Field.GetLength(0); x++)
            {
                for (int y = 0; y < Field.GetLength(1); y++)
                {
                    Field[x, y] = oldField.Field[x, y].Clone;
                }
            }

            Field[newKey.TileLocation.X, newKey.TileLocation.Y] = new AStarTile(newKey.TileLocation, AStarTileType.passable, score: score);
            Start = Field[newKey.TileLocation.X, newKey.TileLocation.Y];
            OpenTiles.Add(Field[newKey.TileLocation.X, newKey.TileLocation.Y]);

            //Copy keys exept the reached key
            foreach (ColoredTile key in oldField.PotentialKeys)
            {
                if (key.Color != newKey.Color)
                {
                    PotentialKeys.Add(key);
                }
                else
                {
                    Field[key.TileLocation.X, key.TileLocation.Y].TileType = AStarTileType.passable;
                }
            }

            //Copy doors exept the doors of the color of the new key.
            foreach (ColoredTile door in oldField.ClosedDoors)
            {
                if (door.Color != newKey.Color)
                {
                    PotentialKeys.Add(door);
                }
                else
                {
                    Field[door.TileLocation.X, door.TileLocation.Y].TileType = AStarTileType.passable;
                }
            }

            foreach (KeyColor key in oldField.obtainedKeys)
            {
                obtainedKeys.Add(key);
            }
            obtainedKeys.Add(newKey.Color);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Solves the level.
        /// </summary>
        public void SolveLevel()
        {
            while (OpenTiles.Count > 0)
            {
                OpenTiles.Sort((t1, t2) => t1.Score.CompareTo(t2.Score));
                VisitTile(OpenTiles[0]);
            }

            HashSet <AStarLevel> innerFields = new HashSet <AStarLevel>();

            AStarLevel optimalField = null;

            foreach (ColoredTile t in ReachedKeys)
            {
                AStarLevel newField = new AStarLevel(this, t, Field[t.TileLocation.X, t.TileLocation.Y].Score);
                innerFields.Add(newField);
                newField.SolveLevel();
                if (newField.Finish?.Score < (Finish?.Score ?? long.MaxValue))
                {
                    Finish       = newField.Finish;
                    optimalField = newField;
                }
            }

            if (optimalField != null)
            {
                OptimalPath.Add(obtainedKeys, CreateOptimalPath(Start, Field[(int)optimalField?.Start.Location.X, (int)optimalField?.Start.Location.Y]));
                foreach (HashSet <KeyColor> keys in optimalField.OptimalPath.Keys)
                {
                    OptimalPath.Add(keys, optimalField.OptimalPath[keys]);
                }
            }
            else if (Finish != null)
            {
                OptimalPath.Add(obtainedKeys, CreateOptimalPath(Start, Field[(int)Finish?.Location.X, (int)Finish?.Location.Y]));
            }
        }