Exemplo n.º 1
0
        private static Neighbors GetNeighbors(RectangularMaze maze, Cell cell)
        {
            var position          = maze.GetPositionOfCell(cell);
            var neighborPositions = cell.CellWalls
                                    .Select(x => new { wall = x, position = maze.GetPositionOfCell(x.GetOtherCell(cell)) })
                                    .ToArray();

            var north = neighborPositions.Where(x => x.position.row == position.row - 1).Select(x => x.wall).FirstOrDefault();
            var east  = neighborPositions.Where(x => x.position.column == position.column + 1).Select(x => x.wall).FirstOrDefault();

            return(new Neighbors(north, east));
        }
        public void InitMazeTest()
        {
            IMaze maze = new RectangularMaze(4, 5);

            System.Console.WriteLine(maze.ToString());
            Assert.AreEqual("  _ _ _ _ _\n" +
                            " |_|_|_|_|_|\n" +
                            " |_|_|_|_|_|\n" +
                            " |_|_|_|_|_|\n" +
                            " |_|_|_|_|_|\n",
                            maze.ToString());
        }
        public void NeighborKnowsItHasANeighborTooTest()
        {
            IMaze maze = new RectangularMaze(10, 15);

            System.Console.WriteLine(maze.ToString());
            bool   pass = true;
            string str  = "";

            //Top line
            str += " ";
            for (int col = 0; col < maze.Width; col++)
            {
                str += " _";
            }
            str += "\n";
            for (int row = 0; row < maze.Height; row++)
            {
                str += " |";
                for (int col = 0; col < maze.Width; col++)
                {
                    var s = maze.Cells[row, col].Neighbors[Direction.S] == null ? "_" : " ";
                    if (maze.Cells[row, col].Neighbors[Direction.S] != null)
                    {
                        if (maze.Cells[row, col].Neighbors[Direction.S].Neighbors[Direction.N] != maze.Cells[row, col])
                        {
                            s    = "e";
                            pass = false;
                        }
                    }
                    str += s;


                    s = maze.Cells[row, col].Neighbors[Direction.E] == null ? "|" : " ";

                    if (maze.Cells[row, col].Neighbors[Direction.E] != null)
                    {
                        if (maze.Cells[row, col].Neighbors[Direction.E].Neighbors[Direction.W] != maze.Cells[row, col])
                        {
                            s    = "e";
                            pass = false;
                        }
                    }
                    str += s;
                }
                str += "\n";
            }
            System.Console.WriteLine(str);
            Assert.IsTrue(pass);
        }
        private static PassableDirections GetPassableDirections(RectangularMaze maze, Cell cell)
        {
            var position          = maze.GetPositionOfCell(cell);
            var neighborPositions = cell.CellWalls
                                    .Where(x => x.IsPassable)
                                    .Select(x => maze.GetPositionOfCell(x.GetOtherCell(cell)))
                                    .ToArray();

            var northPassable = neighborPositions.Any(x => x.row == position.row - 1);
            var southPassable = neighborPositions.Any(x => x.row == position.row + 1);
            var eastPassable  = neighborPositions.Any(x => x.column == position.column + 1);
            var westPassable  = neighborPositions.Any(x => x.column == position.column - 1);

            return(new PassableDirections(northPassable, southPassable, eastPassable, westPassable));
        }
        public void GenMazeTest()
        {
            IMaze maze = new RectangularMaze(4, 5);

            maze.Generate(0, 0, new System.Random());
            System.Console.WriteLine(maze.ToString());

            IMaze maze2 = new RectangularMaze(8, 10);

            maze2.Generate(9, 7, new System.Random());
            System.Console.WriteLine(maze2.ToString());

            IMaze maze3 = new RectangularMaze(10, 15);

            maze3.Generate(0, 0, new System.Random());
            System.Console.WriteLine(maze3.ToString());
        }
        public static SKImage RenderWithSkia(this RectangularMaze maze,
                                             RenderOptions renderOptions,
                                             DistanceInfo distanceInfo,
                                             ShortestPathInfo shortestPathInfo)
        {
            if (maze == null)
            {
                throw new ArgumentNullException(nameof(maze));
            }

            renderOptions = renderOptions ?? new RenderOptions();

            var imageWidth  = (CellSize * maze.ColumnCount) + (Margin * 2);
            var imageHeight = (CellSize * maze.RowCount) + (Margin * 2);

            var imageInfo = new SKImageInfo(imageWidth, imageHeight, SKColorType.Rgba8888, SKAlphaType.Premul);

            using (var surface = SKSurface.Create(imageInfo))
            {
                surface.Canvas.Clear(SKColors.Black);

                var whitePaint = new SKPaint {
                    Color = SKColors.White, StrokeWidth = CellLineWidth
                };
                var startPaint = new SKPaint {
                    Color = SKColors.Green, StrokeWidth = CellLineWidth
                };
                var finishPaint = new SKPaint {
                    Color = SKColors.Red, StrokeWidth = CellLineWidth
                };
                var pathPaint = new SKPaint {
                    Color = SKColors.Yellow, StrokeWidth = CellLineWidth
                };

                foreach (var cell in maze.AllCells)
                {
                    var(row, column) = maze.GetPositionOfCell(cell);
                    var leftX   = (column * CellSize) + Margin;
                    var rightX  = leftX + CellSize;
                    var topY    = (row * CellSize) + Margin;
                    var bottomY = topY + CellSize;

                    var isNorthFacingExit = (maze.FinishingCell == cell || maze.StartingCell == cell) && row == 0 && column > 1;
                    var isSouthFacingExit = (maze.FinishingCell == cell || maze.StartingCell == cell) && row == maze.RowCount - 1 && column > 1;
                    var isEastFacingExit  = (maze.FinishingCell == cell || maze.StartingCell == cell) && column == maze.ColumnCount - 1;
                    var isWestFacingExit  = (maze.FinishingCell == cell || maze.StartingCell == cell) && column == 0;

                    var passableDirections = GetPassableDirections(maze, cell);
                    if (!passableDirections.North && !isNorthFacingExit)
                    {
                        surface.Canvas.DrawLine(leftX, topY, rightX, topY, whitePaint);
                    }

                    if (!passableDirections.South && !isSouthFacingExit)
                    {
                        surface.Canvas.DrawLine(leftX, bottomY, rightX, bottomY, whitePaint);
                    }

                    if (!passableDirections.East && !isEastFacingExit)
                    {
                        surface.Canvas.DrawLine(rightX, topY, rightX, bottomY, whitePaint);
                    }

                    if (!passableDirections.West && !isWestFacingExit)
                    {
                        surface.Canvas.DrawLine(leftX, topY, leftX, bottomY, whitePaint);
                    }

                    if (renderOptions.ShowGradientOfDistanceFromStart)
                    {
                        const int shadingMargin = 2;

                        var finishingCellDistance = distanceInfo.DistanceFromStartMap[distanceInfo.FarthestCell];
                        var currentCellDistance   = distanceInfo.DistanceFromStartMap[cell];
                        var intensity             = (byte)(255 * (currentCellDistance / (decimal)finishingCellDistance));
                        var color = new SKColor(0, 0, intensity);
                        var paint = new SKPaint {
                            Color = color
                        };
                        var shadeWidth  = rightX - leftX - (shadingMargin * 2);
                        var shadeHeight = bottomY - topY - (shadingMargin * 2);

                        surface.Canvas.DrawRect(leftX + shadingMargin, topY + shadingMargin, shadeWidth, shadeHeight, paint);
                    }

                    if (renderOptions.HighlightShortestPath && shortestPathInfo.IsCellInPath(cell))
                    {
                        var paint = cell == maze.StartingCell ? startPaint
                            : cell == maze.FinishingCell ? finishPaint
                            : pathPaint;

                        var distance = distanceInfo.DistanceFromStartMap[cell];
                        surface.Canvas.DrawText(distance.ToString(), leftX + LabelMarginX, topY + LabelMarginY, paint);
                    }
                    else if (renderOptions.ShowAllDistances && distanceInfo.DistanceFromStartMap.ContainsKey(cell))
                    {
                        var distance = distanceInfo.DistanceFromStartMap[cell];
                        surface.Canvas.DrawText(distance.ToString(), leftX + LabelMarginX, topY + LabelMarginY, whitePaint);
                    }
                    else if (cell == maze.StartingCell)
                    {
                        surface.Canvas.DrawText("S", leftX + LabelMarginX, topY + LabelMarginY, startPaint);
                    }
                    else if (cell == maze.FinishingCell)
                    {
                        surface.Canvas.DrawText("E", leftX + LabelMarginX, topY + LabelMarginY, finishPaint);
                    }
                }

                return(surface.Snapshot());
            }
        }