Beispiel #1
0
        /// <summary>
        /// Given a set of world coordinates, returns an array of cells. Evolves and adds chunks as necessary.
        /// </summary>
        private int[,] GetView(ViewPort viewPort)
        {
            // Determine which chunks are (partially or completely) within the bounding box of the view
            var lower = ConvertCellWorldCoordinateToChunkCoordinate(viewPort.XMin, viewPort.YMin);
            var upper = ConvertCellWorldCoordinateToChunkCoordinate(viewPort.XMax, viewPort.YMax);

            // If chunks overlapped by view are not 'inside', they are going to get evolved
            var evolveList = new List <Chunk>();

            for (var posX = lower.X; posX <= upper.X; posX++)
            {
                for (var posY = lower.Y; posY <= upper.Y; posY++)
                {
                    // Get chunk, if it does not exist: create it
                    var   key = GetChunkKey(posX, posY);
                    Chunk chunk;
                    if (!Chunks.TryGetValue(key, out chunk))
                    {
                        chunk       = new Chunk(this, ChunkSizeX, ChunkSizeY, Generations, Threshold, posX, posY, RockPercentage);
                        Chunks[key] = chunk;
                    }

                    if (chunk.Type == Chunk.ChunkType.Edge)
                    {
                        chunk.Type = Chunk.ChunkType.Inside;
                        evolveList.Add(chunk);
                        // Get the neighboring chunks
                        var added = AddAdjacentChunks(posX, posY);
                        evolveList.AddRange(added);
                    }
                }
            }

            // Clean up list (remove duplicates)
            evolveList = evolveList.Distinct().ToList();

            if (evolveList.Count > 0)
            {
                Trace.WriteLine($"EvolveList.Count: {evolveList.Count}");
            }

            RunEvolution(evolveList);

            // Mark 'inside' chunks as final
            foreach (var chunk in Chunks.Values)
            {
                if (chunk.Type == Chunk.ChunkType.Inside && !chunk.IsFinal)
                {
                    chunk.MarkAsFinal();
                }
            }

            // Determine size of view, create array
            var viewSizeX = viewPort.XMax - viewPort.XMin + 1;
            var viewSizeY = viewPort.YMax - viewPort.YMin + 1;
            var view      = new int[viewSizeX, viewSizeY];

            // Copy cells from chunks into array
            for (var x = viewPort.XMin; x <= viewPort.XMax; x++)
            {
                for (var y = viewPort.YMin; y <= viewPort.YMax; y++)
                {
                    view[x - viewPort.XMin, y - viewPort.YMin] = GetFinalCell(x, y);
                }
            }

            return(view);
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            ConsoleKeyInfo key;

            var location = new Point(0, 0);
            var world    = new World();
            var drawGrid = false;

            do
            {
                Console.Clear();
                int xMin = location.X - 0,
                    xMax = location.X + world.ChunkSizeX - 1,
                    yMin = location.Y - 0,
                    yMax = location.Y + world.ChunkSizeY - 1;

                var viewPort = new ViewPort(xMin, yMin, xMax, yMax);

                var view = world.GetView(viewPort);
                for (var x = 0; x < (1 + xMax - xMin); x++)
                {
                    for (var y = 0; y < (1 + yMax - yMin); y++)
                    {
                        var cell  = view[y, x];
                        var color = Console.ForegroundColor;
                        Console.ForegroundColor = cell == 1
                            ? ConsoleColor.DarkBlue
                            : ConsoleColor.White;
                        Console.Write("█");
                        Console.ForegroundColor = color;
                    }
                    Console.WriteLine();
                }

                world.DrawImage(viewPort, drawGrid);

                Console.WriteLine("Number of chunks: " + world.Chunks.Keys.Count);
                Console.WriteLine($"Location: ({location.X}, {location.Y})");
                Console.WriteLine("R: reset\tG: grid on/off\tQ: quit");
                key = Console.ReadKey();
                if (key.Key == ConsoleKey.LeftArrow)
                {
                    location.X = location.X - world.MovementFactor;
                }
                if (key.Key == ConsoleKey.RightArrow)
                {
                    location.X = location.X + world.MovementFactor;
                }
                if (key.Key == ConsoleKey.UpArrow)
                {
                    location.Y = location.Y - world.MovementFactor;
                }
                if (key.Key == ConsoleKey.DownArrow)
                {
                    location.Y = location.Y + world.MovementFactor;
                }
                if (key.Key == ConsoleKey.R)
                {
                    world = new World();
                }
                if (key.Key == ConsoleKey.G)
                {
                    drawGrid = !drawGrid;
                }
            } while (key.Key != ConsoleKey.Q);
        }
Beispiel #3
0
        /// <summary>
        /// Given a viewport, creates an image of the world and saves it to disc.
        /// </summary>
        public Image DrawImage(ViewPort viewPort,
                               bool drawEdges            = true,
                               bool drawGrid             = false,
                               bool drawView             = true,
                               bool drawEdgesAsNoise     = false,
                               bool drawFinalAsNoise     = false,
                               bool colorizeInsideChunks = true)
        {
            var chunks = Chunks.Values.ToList();

            if (!drawEdges)
            {
                chunks = chunks.Where(x => x.Type != Chunk.ChunkType.Edge).ToList();
            }

            // Determine image size.
            var xMin = chunks.Min(x => x.PosX);
            var xMax = chunks.Max(x => x.PosX);
            var xDim = (1 + xMax - xMin) * ChunkSizeX * CellSize;
            var yMin = chunks.Min(x => x.PosY);
            var yMax = chunks.Max(x => x.PosY);
            var yDim = (1 + yMax - yMin) * ChunkSizeX * CellSize;

            var image = new Bitmap(xDim, yDim);

            using (var g = Graphics.FromImage(image))
            {
                foreach (var chunk in chunks)
                {
                    var chunkXRelative = chunk.PosX - xMin;
                    var xTopLeft       = chunkXRelative * ChunkSizeX * CellSize;

                    var chunkYRelative = chunk.PosY - yMin;
                    var yTopLeft       = chunkYRelative * ChunkSizeY * CellSize;

                    var solidColor = Brushes.DarkGray;
                    var openColor  = Brushes.DimGray;

                    for (var x = 0; x < chunk.SizeX; x++)
                    {
                        for (var y = 0; y < chunk.SizeY; y++)
                        {
                            Brush brush;
                            int   block;
                            if (chunk.IsFinal)
                            {
                                block = drawFinalAsNoise
                                    ? chunk.Noise[x, y]
                                    : chunk.Final[x, y];
                                brush = block == 1
                                    ? (colorizeInsideChunks ? Brushes.ForestGreen : solidColor)
                                    : (colorizeInsideChunks ? Brushes.SaddleBrown : openColor);
                            }
                            else
                            {
                                block = drawEdgesAsNoise
                                    ? chunk.Noise[x, y]
                                    : chunk.Cells[x, y];
                                brush = block == 1
                                    ? solidColor
                                    : openColor;
                            }

                            g.FillRectangle(brush, xTopLeft + x * CellSize, yTopLeft + y * CellSize, CellSize, CellSize);
                        }
                    }
                }

                if (drawGrid)
                {
                    foreach (var chunk in chunks.OrderBy(x => x.Type))
                    {
                        var chunkXRelative = chunk.PosX - xMin;
                        var xTopLeft       = chunkXRelative * ChunkSizeX * CellSize;

                        var chunkYRelative = chunk.PosY - yMin;
                        var yTopLeft       = chunkYRelative * ChunkSizeY * CellSize;

                        var color = chunk.Type == Chunk.ChunkType.Edge
                            ? Color.Red
                            : Color.Yellow;

                        var pen = new Pen(color, 1.5f);

                        g.DrawRectangle(pen, xTopLeft, yTopLeft, ChunkSizeX * CellSize - 1, ChunkSizeY * CellSize - 1);
                    }
                }


                // Draw viewport.
                if (drawView)
                {
                    // Calculate viewport
                    // Determine which chunks are (partially or completely) within the bounding box of the view
                    var xTranslation = Math.Abs(Math.Min(0, xMin) * ChunkSizeX * CellSize);
                    var yTranslation = Math.Abs(Math.Min(0, yMin) * ChunkSizeY * CellSize);
                    Console.WriteLine($"viewport: {viewPort}");
                    viewPort.Grow(CellSize, CellSize);
                    Console.WriteLine($"viewport-grown: {viewPort}");
                    viewPort.Translate(xTranslation, yTranslation);
                    Console.WriteLine($"viewport-translated: {viewPort}");

                    var rect = viewPort.GetRectangle();
                    g.DrawRectangle(new Pen(Color.Fuchsia, 2 * CellSize), rect);
                }
            }

            return(image);
        }