/// <summary> /// Main search algorithm. Attempts to locate /// a route to the destination location. /// </summary> /// <param name="start">The start location.</param> /// <returns></returns> bool TryFindPath(Location start) { Queue<Location> queue = new Queue<Location>(); queue.Enqueue(start); Dictionary<Location, Location> previousSteps = new Dictionary<Location, Location>(); Location location; while (queue.Count > 0) { location = queue.Dequeue(); if (location.Equals(destination)) { Location parentLocation; Location childLocation = location; List<Move> moves = new List<Move>(); while (previousSteps.TryGetValue(childLocation, out parentLocation)) { /* Create the move and add to route.*/ Direction dir = parentLocation.GetDirection(childLocation); moves.Add(new Move(dir)); childLocation = parentLocation; } moves.Reverse(); /* The moves are back to front. */ route = moves.ToArray(); return true; } else { for (int i = 0; i < 4; i++) { Direction direction = GetDirection(i); Location neighbour = location.GetAdjacentLocation(direction); if (level[neighbour].CanEnter && !previousSteps.ContainsKey(neighbour)) { previousSteps.Add(neighbour, location); queue.Enqueue(neighbour); } } } } return false; }
/// <summary> /// Tests whether the specified location is within /// the Level grid. /// </summary> /// <param name="location">The location to test /// whether it is within the level grid.</param> /// <returns><code>true</code> if the location /// is within the <see cref="Level"/>; /// <code>false</code> otherwise.</returns> public bool InBounds(Location location) { return Level.InBounds(location); }
List<Cell> BuildCells(string rowText, int rowNumber) { List<Cell> row = new List<Cell>(rowText.Length); int columnNumber = 0; foreach (char c in rowText) { Location location = new Location(rowNumber, columnNumber++); switch (c) { case '#': /* Wall. */ row.Add(new WallCell(location, this)); break; case ' ': /* Empty. */ row.Add(new FloorCell(location, this)); break; case '$': /* Treasure in a square. */ row.Add(new FloorCell(location, this, new Treasure(location, this))); break; case '*': /* Treasure in a Goal. */ GoalCell goalCellWithTreasure = new GoalCell(location, this, new Treasure(location, this)); goalCellWithTreasure.CompletedGoalChanged += new EventHandler(GoalCell_CompletedGoalChanged); goals.Add(goalCellWithTreasure); row.Add(goalCellWithTreasure); break; case '.': /* Goal. */ GoalCell goalCell = new GoalCell(location, this); goalCell.CompletedGoalChanged += new EventHandler(GoalCell_CompletedGoalChanged); goals.Add(goalCell); row.Add(goalCell); break; case '@': /* Actor in a floor cell. */ Actor actor = new Actor(location, this); row.Add(new FloorCell(location, this, actor)); Actor = actor; break; case '!': /* Space. */ row.Add(new SpaceCell(location, this)); break; default: throw new FormatException("Invalid Level symbol found: " + c); } } return row; }
/// <summary> /// Initializes a new instance of the <see cref="SearchPathFinder"/> class. /// </summary> /// <param name="start">The start cell. Presumably where /// the <see cref="Actor"/> is located.</param> /// <param name="destination">Where we would like to get.</param> public SearchPathFinder(Cell start, Location destination) { this.destination = destination; startCell = start; level = start.Level; }
/// <summary> /// Tests whether the specified location is within /// the Level grid. /// </summary> /// <param name="location">The location to test /// whether it is within the level grid.</param> /// <returns><code>true</code> if the location /// is within the <see cref="Level"/>; /// <code>false</code> otherwise.</returns> public bool InBounds(Location location) { return (location.RowNumber >= 0 && location.RowNumber < RowCount && location.ColumnNumber >= 0 && location.ColumnNumber < ColumnCount); }
/// <summary> /// Gets the <see cref="Orpius.Sokoban.Cell"/> with the specified location. /// </summary> /// <value>The cell at the specified location.</value> public Cell this[Location location] { get { if (InBounds(location)) { return this[location.RowNumber, location.ColumnNumber]; } return null; } }
/// <summary> /// Initializes a new instance of the <see cref="GoalCell"/> class. /// </summary> /// <param name="location">The location of the goal /// on the level grid.</param> /// <param name="level">The level grid where this cell /// is located.</param> /// <param name="contents">The contents of this goal cell.</param> public GoalCell(Location location, Level level, CellContents contents) : base(cellName, location, level, contents) { }
/// <summary> /// Initializes a new instance of the <see cref="GoalCell"/> class. /// </summary> /// <param name="location">The location of the goal /// on the level grid.</param> /// <param name="level">The level grid where this cell /// is located.</param> public GoalCell(Location location, Level level) : base(cellName, location, level) { }
/// <summary> /// Initializes a new instance of the <see cref="Actor"/> class. /// </summary> /// <param name="location">The location.</param> /// <param name="level">The level.</param> public Actor(Location location, Level level) : base("Actor", location, level) { }