Exemple #1
0
 public string GetCellString(GridPoint point)
 {
     if (!MazeCells.ContainsKey(point))
     {
         return(" ");
     }
     return(DonutMazeCell.GetCellString(MazeCells[point]));
 }
Exemple #2
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);
        }
Exemple #3
0
        public bool GetCanEnterCell(
            GridPoint point,
            SortedDictionary <string, string> keysCollected,
            bool ignoreDoors = false)
        {
            if (!MazeCells.ContainsKey(point))
            {
                return(false);
            }
            var cell = MazeCells[point];

            if (MazeCellType.Wall.Equals(cell.Type))
            {
                return(false);
            }
            if (!ignoreDoors &&
                CellsWithDoors.ContainsKey(point) &&
                !keysCollected.ContainsKey(CellsWithDoors[point].ToLower()))
            {
                return(false);
            }
            return(true);
        }
Exemple #4
0
        public IList <GridPoint> GetPointNeighbors(
            GridPoint point,
            SortedDictionary <string, string> keysCollected,
            GridPoint specificNeighborToAllow = null,
            bool ignoreDoors = false)
        {
            var neighbors  = new List <GridPoint>();
            var candidates = new List <GridPoint>()
            {
                point.MoveLeft(1),
                point.MoveRight(1),
                point.MoveUp(1),
                point.MoveDown(1)
            };

            foreach (var candidate in candidates)
            {
                if (!MazeCells.ContainsKey(candidate))
                {
                    continue;
                }
                var  candidateCell        = MazeCells[candidate];
                bool checkIfCanCenterCell = !(
                    specificNeighborToAllow != null &&
                    specificNeighborToAllow.Equals(candidate));
                if (checkIfCanCenterCell)
                {
                    if (!GetCanEnterCell(candidate, keysCollected, ignoreDoors))
                    {
                        continue;
                    }
                }
                neighbors.Add(candidate);
            }
            return(neighbors);
        }
Exemple #5
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);
        }