public static FerryState ApplyFerryMovementInstruction( FerryState currentState, FerryMovementInstruction ferryMovementInstruction) { var nextPosition = currentState.Position; var nextHeading = currentState.Heading; if (FerryMovementDirection.East.Equals(ferryMovementInstruction.MovementDirection)) { nextPosition = nextPosition.MoveRight(ferryMovementInstruction.Value); } else if (FerryMovementDirection.North.Equals(ferryMovementInstruction.MovementDirection)) { nextPosition = nextPosition.MoveUp(ferryMovementInstruction.Value); } else if (FerryMovementDirection.West.Equals(ferryMovementInstruction.MovementDirection)) { nextPosition = nextPosition.MoveLeft(ferryMovementInstruction.Value); } else if (FerryMovementDirection.South.Equals(ferryMovementInstruction.MovementDirection)) { nextPosition = nextPosition.MoveDown(ferryMovementInstruction.Value); } else if (FerryMovementDirection.Left.Equals(ferryMovementInstruction.MovementDirection)) { var direction = GetMovementDirectionFromHeading(nextHeading); var nextDirection = MovementDirectionHelper.Rotate(direction, ferryMovementInstruction.Value, true); nextHeading = GetHeadingFromMovementDirection(nextDirection); } else if (FerryMovementDirection.Right.Equals(ferryMovementInstruction.MovementDirection)) { var direction = GetMovementDirectionFromHeading(nextHeading); var nextDirection = MovementDirectionHelper.Rotate(direction, ferryMovementInstruction.Value, false); nextHeading = GetHeadingFromMovementDirection(nextDirection); } else if (FerryMovementDirection.Forward.Equals(ferryMovementInstruction.MovementDirection)) { var direction = GetMovementDirectionFromHeading(nextHeading); nextPosition = nextPosition.Move(direction, ferryMovementInstruction.Value); } else { throw new Exception($"Unknown direction: {ferryMovementInstruction.MovementDirection}"); } var nextState = new FerryState(nextPosition, nextHeading); return(nextState); }
public IList <GridPoint3D> GetNeighbors(GridPoint3D point) { var result = new List <GridPoint3D>(); var directions = new List <MovementDirection>() { MovementDirection.Left, MovementDirection.Right, MovementDirection.Up, MovementDirection.Down }; foreach (var direction in directions) { var neighbor = point.Move(direction, 1); if (!IsRecursive) { result.Add(neighbor); } else // Recursive map { // Check if the neighbor is the middle point if (neighbor.XYPoint.Equals(CenterPointXY)) { // Get the outer cells adjacent to this one in the // inner layer // Handle y is inverted (up actually decreases y), // the inner layer side is actually the same as the // vertical movement direction var innerLayerSide = direction; if (MovementDirection.Left.Equals(direction) || MovementDirection.Right.Equals(direction)) { innerLayerSide = MovementDirectionHelper.GetOppositeDirection(direction); } int[] edgeValues; var coordinateOrder = string.Empty; switch (innerLayerSide) { case MovementDirection.Left: edgeValues = new int[4] { 0, point.Z + 1, 0, Height - 1 }; coordinateOrder = "XZY"; break; case MovementDirection.Right: edgeValues = new int[4] { Width - 1, point.Z + 1, 0, Height - 1 }; coordinateOrder = "XZY"; break; case MovementDirection.Up: edgeValues = new int[4] { 0, point.Z + 1, 0, Width - 1 }; coordinateOrder = "YZX"; break; case MovementDirection.Down: edgeValues = new int[4] { Height - 1, point.Z + 1, 0, Width - 1 }; coordinateOrder = "YZX"; break; default: throw new Exception($"Invalid side {direction}"); } var neighborsOnInnerLayer = GridHelper3D.GetPointsAlongEdge( edgeValues: edgeValues, coordinateOrder: coordinateOrder); result.AddRange(neighborsOnInnerLayer); } // Check if the neighbor is off the map else if (GetIsPointOffMap(neighbor)) { // Get the adjacent cell to the center in the outer layer var outerLayerCenterCell = new GridPoint3D(CenterPointXY, point.Z - 1); neighbor = outerLayerCenterCell.Move(direction, 1); result.Add(neighbor); } else { result.Add(neighbor); } } } return(result); }