示例#1
0
        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);
        }
示例#2
0
 public Moon(GridPoint3D position)
 {
     Position = position.Move(new Tuple <int, int, int>(0, 0, 0));
     Velocity = new GridPoint3D();
 }
示例#3
0
 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));
 }
示例#4
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);
        }