/// <summary> /// Destination for a movement. Ignores all robots on the map but does take into account walls, conveyor belts and gears. Returns /// every step of the move. /// </summary> /// <param name="map">The game map.</param> /// <param name="startLocation">Where the unit starts.</param> /// <param name="cards">The cards to apply.</param> /// <returns>Every step of the move.</returns> public static List<MovePoint> CardPath(GameMap map, BoardLocation startLocation, IEnumerable<Card> cards) { // if we can't move, we end up where we started List<MovePoint> points = new List<MovePoint> {new MovePoint(startLocation)}; foreach (Card cardOn in cards) { // move robot MovePoint endLocation = Move(map, startLocation, cardOn.Move); if (endLocation.Dead) { points.Add(endLocation); return points; } if (! endLocation.Location.Equals(startLocation)) { startLocation = endLocation.Location; points.Add(new MovePoint(startLocation)); } // conveyor belt - may cause a 1/4 turn. MapSquare sq = map.GetSquare(startLocation.MapPosition); for (int speed=1; (sq.Conveyor != null) && (speed <= sq.Conveyor.Speed); speed++) { endLocation = Move(map, startLocation.MapPosition, sq.Conveyor.Direction); BoardLocation locMove = new BoardLocation(endLocation.Location.MapPosition, startLocation.Direction); sq = map.GetSquare(endLocation.Location.MapPosition); if (sq.Conveyor != null) { MapSquare.DIRECTION dirEnter = MoveDirection(startLocation.MapPosition, endLocation.Location.MapPosition); locMove = locMove.Rotate((int)sq.Conveyor.Direction - (int)dirEnter); } startLocation = locMove; points.Add(new MovePoint(startLocation)); } // gears if (sq.Type == MapSquare.TYPE.ROTATE_CLOCKWISE) { startLocation = startLocation.Rotate(1); points.Add(new MovePoint(startLocation)); } if (sq.Type == MapSquare.TYPE.ROTATE_COUNTERCLOCKWISE) { startLocation = startLocation.Rotate(-1); points.Add(new MovePoint(startLocation)); } // damage int damage = CalcLaserDamage(map, startLocation); if (damage != 0) points[points.Count - 1].Damage = damage; } return points; }
/// <summary> /// Move a unit one square in the requested direction. Ignores all robots on the map but does take into account walls, conveyor belts and gears. /// </summary> /// <param name="map">The game map.</param> /// <param name="position">The map square to start the move from.</param> /// <param name="direction">The direction to move.</param> /// <returns>The final location of the move.</returns> public static MovePoint Move(GameMap map, Point position, MapSquare.DIRECTION direction) { // watch for wall in this direction MapSquare.SIDE sideExit = sideMoveOut[(int) direction]; MapSquare.SIDE sideEnter = sideMoveIn[(int) direction]; BoardLocation location = new BoardLocation(position, direction); // can we exit this square? MapSquare sq = map.GetSquare(position); if ((sq.Walls & sideExit) != 0) return new MovePoint(location); BoardLocation moveTo = location.Move(1); // did we go off the board? if ((moveTo.MapPosition.X < 0) || (map.Width <= moveTo.MapPosition.X) || (moveTo.MapPosition.Y < 0) || (map.Height <= moveTo.MapPosition.Y)) return new MovePoint(location, true); // did we go into a pit? if (map.GetSquare(moveTo.MapPosition).Type == MapSquare.TYPE.PIT) return new MovePoint(moveTo, true); // can we enter the new square? sq = map.GetSquare(moveTo.MapPosition); if ((sq.Walls & sideEnter) != 0) return new MovePoint(location); return new MovePoint(moveTo); }