public CommandVoidResult DoomFireAlgo( CommandEvaluationContext context, [Option("w", "width", "width in characters", true, true)] int width = 100, [Option("h", "height", "height in characters", true, true)] int height = 40, [Option("d", "decay-delta", "decay delta", true, true)] int decayDelta = 3, [Option("g", "gray", "gray mode - no colors")] bool gray = false, [Option("s", "slow", "0 max speed - pause time between images in ms", true, true)] int slow = 0, [Option("t", "no-text", "do not add text info above anim")] bool noText = false, [Option(null, "color-palette", "color palette. 36 symbols separated by " + PalettePatternSeparator, true, true)] string firePattern = DefaultFirePattern ) { // remove directives to speed up (TODO: the directives lead to stack overflow in this case) firePattern = firePattern.ToLower(); var firePallete = firePattern.Split(PalettePatternSeparator); var sb = new StringBuilder(width * height * 20); if (!gray) { // add colors var n = firePallete.Length; var stp = 256 / n; int r = 0; int g = 0; int b = 0; for (int i = 0; i < firePallete.Length; i++) { firePallete[i] = ANSI.SGR_SetForegroundColor24bits(r, g, b) + firePallete[i]; r += stp; if (r > 100) { g += stp; } } } var o = context.Out; o.Echo("pixelPalete.Length=" + firePallete.Length); var pixels = width * height; var pixelsArray = new int[pixels]; var random = new Random(); void createPixelsStructure() { for (var i = 0; i < pixels; i++) { pixelsArray[i] = 0; } }; void calculatePropagation() { for (var column = 0; column < width; column++) { for (var row = 0; row < height; row++) { var index = column + (width * row); updatePixelIntensity(index); } } }; void updatePixelIntensity(int index) { var belowIndex = index + width; if (belowIndex < width * height) { var decay = (int)Math.Floor(random.NextDouble() * decayDelta); var belowIntensity = pixelsArray[belowIndex]; var newIntensity = belowIntensity - decay; if (index - decay > 0) { pixelsArray[index - decay] = newIntensity > 0 ? newIntensity : 0; } } }; void createSource() { for (var column = 0; column < width; column++) { var overflowPixel = width * height; var index = (overflowPixel - width) + column; pixelsArray[index] = firePallete.Length - 1; } }; void render() { sb.Clear(); sb.Append(ANSI.CUP()); for (var row = 0; row < height; row++) { for (var column = 0; column < width; column++) { var index = column + (width * row); var intensity = pixelsArray[index]; sb.Append(firePallete[intensity]); } sb.AppendLine(); } o.ConsolePrint(sb.ToString()); // fast print }; void start() { o.ClearScreen(); try { o.HideCur(); } catch (Exception ex) { o.Errorln(ex.Message); } createPixelsStructure(); createSource(); } start(); var end = false; while (!end) { var sw0 = Stopwatch.StartNew(); calculatePropagation(); sw0.Stop(); var sw1 = Stopwatch.StartNew(); render(); sw1.Stop(); if (!noText) { o.Echoln($"(rdc)Doom fire algo - {Math.Round(1d / (sw0.ElapsedMilliseconds+sw1.ElapsedMilliseconds) * 1000,2)} fps"); } //end = context.CommandLineProcessor.CancellationTokenSource.IsCancellationRequested; end = context.CommandLineProcessor.IsCancellationRequested; if (slow > 0) { Thread.Sleep(slow); } } o.ShowCur(); return(CommandVoidResult.Instance); }
public CommandVoidResult Run( [Option("w", "width", "width in characters", true, true)] int width = 100, [Option("h", "height", "height in characters", true, true)] int height = 40, [Option("d", "decay-delta", "decay delta", true, true)] int decayDelta = 3, [Option("g", "gray", "gray mode - no colors")] bool gray = false, [Option("s", "slow", "0 max speed - pause time between images in ms", true, true)] int slow = 0, [Option("t", "no-text", "do not add text info above anim")] bool noText = false, [Option(null, "color-palette", "color palette. 36 symbols separated by " + PalettePatternSeparator, true, true)] string firePattern = DefaultFirePattern ) { firePattern = firePattern.ToLower(); var firePallete = firePattern.Split(PalettePatternSeparator); var sb = new StringBuilder(width * height * 20); if (!gray) { // add colors var n = firePallete.Length; var stp = 256 / n; int r = 0; int g = 0; int b = 0; for (int i = 0; i < firePallete.Length; i++) { firePallete[i] = ANSI.SGR_SetForegroundColor24bits(r, g, b) + firePallete[i]; r += stp; if (r > 100) g += stp; } } var o = new ConsoleTextWriterWrapper(System.Console.Out); var pixels = width * height; var pixelsArray = new int[pixels]; var random = new Random(); void createPixelsStructure() { for (var i = 0; i < pixels; i++) pixelsArray[i] = 0; }; void calculatePropagation() { for (var column = 0; column < width; column++) { for (var row = 0; row < height; row++) { var index = column + (width * row); updatePixelIntensity(index); } } }; void updatePixelIntensity(int index) { var belowIndex = index + width; if (belowIndex < width * height) { var decay = (int)Math.Floor(random.NextDouble() * decayDelta); var belowIntensity = pixelsArray[belowIndex]; var newIntensity = belowIntensity - decay; if (index - decay > 0) pixelsArray[index - decay] = newIntensity > 0 ? newIntensity : 0; } }; void createSource() { for (var column = 0; column < width; column++) { var overflowPixel = width * height; var index = (overflowPixel - width) + column; pixelsArray[index] = firePallete.Length - 1; } }; void render() { sb.Clear(); sb.Append(ANSI.CUP()); try { o.HideCur(); } catch (Exception) { } for (var row = 0; row < height; row++) { for (var column = 0; column < width; column++) { var index = column + (width * row); var intensity = pixelsArray[index]; sb.Append(firePallete[intensity]); } sb.AppendLine(); } o.WriteAsync(sb.ToString()); }; void start() { o.ClearScreen(); try { o.HideCur(); } catch (Exception) { } createPixelsStructure(); createSource(); } start(); var end = false; System.Console.CancelKeyPress += (o, e) => { System.Environment.Exit(0); }; while (!end) { var sw0 = Stopwatch.StartNew(); calculatePropagation(); sw0.Stop(); var sw1 = Stopwatch.StartNew(); render(); sw1.Stop(); if (!noText) o.Echoln($"(rdc)Doom fire algo - {Math.Round(1d / (sw0.ElapsedMilliseconds + sw1.ElapsedMilliseconds) * 1000, 2)} fps"); if (slow > 0) Thread.Sleep(slow); } try { o.ShowCur(); } catch (Exception) { }; return CommandVoidResult.Instance; }