Пример #1
0
        private void ConstructPortals()
        {
            PortalCells = new Dictionary <GridPoint, string>();
            Portals     = new Dictionary <string, IList <GridPoint> >();
            var emptyCells = MazeCells
                             .Where(kvp => DonutMazeCellType.Empty.Equals(kvp.Value.Type));

            foreach (var emptyCell in emptyCells)
            {
                var point = emptyCell.Key;
                var movementDirections = new List <MovementDirection>()
                {
                    MovementDirection.Down,
                    MovementDirection.Left,
                    MovementDirection.Right,
                    MovementDirection.Up
                };
                foreach (var direction in movementDirections)
                {
                    // Assumption: One point can only be associated with at
                    // most one portal.
                    var neighbor1 = point.Move(direction, 1);
                    if (!MazeCells.ContainsKey(neighbor1) ||
                        !DonutMazeCellType.Portal.Equals(MazeCells[neighbor1].Type))
                    {
                        continue;
                    }
                    var neighbor2 = point.Move(direction, 2);
                    if (!MazeCells.ContainsKey(neighbor2) ||
                        !DonutMazeCellType.Portal.Equals(MazeCells[neighbor2].Type))
                    {
                        throw new Exception("Only one neighboring portal cell found");
                    }
                    var portalId = string.Empty;
                    if (MovementDirection.Right.Equals(direction) ||
                        MovementDirection.Up.Equals(direction))
                    {
                        portalId = MazeCells[neighbor1].PortalLetter + MazeCells[neighbor2].PortalLetter;
                    }
                    else
                    {
                        portalId = MazeCells[neighbor2].PortalLetter + MazeCells[neighbor1].PortalLetter;
                    }

                    PortalCells.Add(point, portalId);
                    if (!Portals.ContainsKey(portalId))
                    {
                        Portals.Add(portalId, new List <GridPoint>());
                    }
                    Portals[portalId].Add(point);
                }
            }
            EntrancePoint = new GridPoint3D(Portals[EntrancePortalId][0], 0);
            ExitPoint     = new GridPoint3D(Portals[ExitPortalId][0], 0);
        }
Пример #2
0
 public bool GetIsOnSide(GridPoint3D point, MovementDirection side)
 {
     // Note - because "up" increases Y, whereas the top is at 0 and
     // increasing y goes down,
     // we need to invert the meaning of Up and Down here
     return(side switch
     {
         MovementDirection.Left => point.X == 0,
         MovementDirection.Right => point.X == Width - 1,
         MovementDirection.Down => point.Y == 0,
         MovementDirection.Up => point.Y == Height - 1,
         _ => throw new Exception($"Invalid side {side}"),
     });
Пример #3
0
 public string GetCellString(GridPoint3D point)
 {
     if (BugCells.Contains(point))
     {
         return("#");
     }
     if (GetIsPointOffMap(point))
     {
         return(" ");
     }
     if (IsRecursive && CenterPointXY.Equals(point.XYPoint))
     {
         return("?");
     }
     return(".");
 }
Пример #4
0
        public BigInteger GetBiodiversityRating(int layer)
        {
            BigInteger result         = 0;
            BigInteger cellPointValue = 1;

            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    var point = new GridPoint3D(x, y, layer);
                    if (BugCells.Contains(point))
                    {
                        result += cellPointValue;
                    }
                    cellPointValue *= 2;
                }
            }
            return(result);
        }
Пример #5
0
 public bool GetIsOnOuterWall(GridPoint3D point)
 {
     if (point.X >= OuterWallLeft &&
         point.X <= OuterWallRight &&
         (
             point.Y == OuterWallTop ||
             point.Y == OuterWallBottom))
     {
         return(true);
     }
     if (point.Y >= OuterWallTop &&
         point.Y <= OuterWallBottom &&
         (
             point.X == OuterWallLeft ||
             point.X == OuterWallRight))
     {
         return(true);
     }
     return(false);
 }
Пример #6
0
        public static ErisMapState CreateMap(
            IList <string> mapDefinition,
            bool isRecursive)
        {
            int height   = mapDefinition.Count;
            int width    = mapDefinition.Max(row => row.Length);
            var bugCells = new HashSet <GridPoint3D>();

            for (int y = 0; y < mapDefinition.Count; y++)
            {
                var rowDefinition = mapDefinition[y];
                for (int x = 0; x < rowDefinition.Length; x++)
                {
                    var      cellDefinition = rowDefinition[x];
                    var      point          = new GridPoint3D(x, y, 0);
                    CellType cellType       = cellDefinition switch
                    {
                        '.' => CellType.Empty,
                        '#' => CellType.Bug,
                        _ => CellType.Empty,
                    };
                    if (CellType.Bug.Equals(cellType))
                    {
                        bugCells.Add(point);
                    }
                }
            }
            var result = new ErisMapState(
                bugCells: bugCells,
                width: width,
                height: height,
                minZ: 0,
                maxZ: 0,
                isRecursive: isRecursive);

            return(result);
        }
Пример #7
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);
        }
Пример #8
0
 public void UpdateVelocity(Tuple <int, int, int> acceleration)
 {
     Velocity = Velocity.Move(acceleration);
 }
Пример #9
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));
 }
Пример #10
0
 public Moon(int x, int y, int z, int vX, int vY, int vZ)
 {
     Position = new GridPoint3D(x, y, z);
     Velocity = new GridPoint3D(vX, vY, vZ);
 }
Пример #11
0
        public void Set(TCell cell, GridPoint3D point)
        {
            GridCoord3D coord = new GridCoord3D(Size, point.X, point.Y, point.Z);

            Set(cell, coord);
        }
Пример #12
0
 public Moon(int x, int y, int z)
 {
     Position = new GridPoint3D(x, y, z);
     Velocity = new GridPoint3D();
 }
Пример #13
0
 public Moon()
 {
     Position = new GridPoint3D();
     Velocity = new GridPoint3D();
 }
Пример #14
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);
        }
Пример #15
0
 private void AssertPoint(GridPoint3D point, int x, int y, int z)
 {
     Assert.AreEqual(x, point.X);
     Assert.AreEqual(y, point.Y);
     Assert.AreEqual(z, point.Z);
 }
Пример #16
0
 public Moon(GridPoint3D position)
 {
     Position = position.Move(new Tuple <int, int, int>(0, 0, 0));
     Velocity = new GridPoint3D();
 }
Пример #17
0
        public TCell Get(GridPoint3D point)
        {
            GridCoord3D coord = new GridCoord3D(Size, point);

            return(Get(coord));
        }