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); }
public Moon(GridPoint3D position) { Position = position.Move(new Tuple <int, int, int>(0, 0, 0)); Velocity = new GridPoint3D(); }
public Moon(GridPoint3D position, GridPoint3D velocity) { Position = position.Move(new Tuple <int, int, int>(0, 0, 0)); Velocity = velocity.Move(new Tuple <int, int, int>(0, 0, 0)); }
public IList <GridPoint3D> GetEmptyNeighbors(GridPoint3D currentPosition) { var result = new List <GridPoint3D>(); var movementDirections = new List <MovementDirection>() { MovementDirection.Down, MovementDirection.Left, MovementDirection.Right, MovementDirection.Up }; foreach (var movementDirection in movementDirections) { var neighborPoint = currentPosition.Move(movementDirection, 1); if (!MazeCells.ContainsKey(neighborPoint.XYPoint)) { continue; } var type = MazeCells[neighborPoint.XYPoint].Type; if (DonutMazeCellType.Wall.Equals(type)) { continue; } if (DonutMazeCellType.Empty.Equals(type)) { result.Add(neighborPoint); } else if (DonutMazeCellType.Portal.Equals(type)) { // Assumption: One point can be associated with at most // one portal var portalId = PortalCells[currentPosition.XYPoint]; if (EntrancePortalId.Equals(portalId) || ExitPortalId.Equals(portalId)) { continue; } bool isOnOuterEdge = GetIsOnOuterWall(currentPosition); // If this is a recursive maze, then outer portals only // work for z > 1 if (IsRecursive && isOnOuterEdge && currentPosition.Z == 0) { continue; } var connectedPoint = Portals[portalId] .Where(p => !p .Equals(currentPosition.XYPoint)) .FirstOrDefault(); if (connectedPoint == null) { throw new Exception("Portal found with no connected point"); } // Handle recursive maze - if this is an inner portal, then // we are going in a level, so increment z // If this is an outer portal, then we are going out a // level, so decrease z int connectedPointZ = currentPosition.Z; if (IsRecursive) { if (isOnOuterEdge) { connectedPointZ--; } else if (GetIsOnInnerWall(currentPosition)) { connectedPointZ++; } } // The connected point is stored in the maze at z=0, so // move it to the appropriate z index result.Add(new GridPoint3D(connectedPoint, connectedPointZ)); } else { throw new Exception($"Invalid cell type {type}"); } } return(result); }