Advertisement
timeshifter

faster life

Sep 18th, 2015
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.78 KB | None | 0 0
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.Windows.Forms;
  5.  
  6. namespace colorlife {
  7.     public unsafe partial class frmDavesLife : Form {
  8.         Bitmap canvas;
  9.         Graphics g;
  10.         Rectangle bmpRect;
  11.         BitmapData bmpData;
  12.         uint* currPos;
  13.         bool fadeColors = true,
  14.             cycleColors = true;
  15.  
  16.         System.Windows.Forms.Timer tmrFrames = new System.Windows.Forms.Timer(); //mah frame counter
  17.         byte[] field; //the game state array
  18.         bool gameRunning = true, altFrame = false; //gameRunning so the Game loop terminates properly, altFrame is flipped every frame
  19.         uint w, //width
  20.              h, //height
  21.              w1, //width - 1
  22.              wp1, //width + 1
  23.              w2,
  24.              w3,
  25.              l,  //length
  26.              lw, //l - w
  27.              x, //x coord
  28.              outerL,
  29.              i, //index
  30.              FPS = 0, //fps
  31.              FPSTotal = 0, //total fps, for average calculation
  32.              frameCount = 0, //number of frames, to determine the average
  33.              timerCount = 0;
  34.         byte* t, //start address of the active half of the field array
  35.               a; //start of the inactive half
  36.         byte n;
  37.         //color cycling stuff
  38.         Color[] colorList = { Color.Purple, Color.Blue, Color.Green, Color.Yellow, Color.Orange, Color.Red };
  39.         uint cycleLength = 80, //frames between each full color
  40.             currCycleFrame = 0, currCycleItem = 0, //counters
  41.             col, //current frame's computed color
  42.             colDecVal = 1, //RGB value decrement each frame
  43.             colLimit = 31; //RGB value lower limit
  44.  
  45.         byte rVal, gVal, bVal; //current color values
  46.  
  47.         public frmDavesLife() {
  48.             Initialize();
  49.             Random R = new Random(0);
  50.             for (x = 1; x <= w; x++) {
  51.                 for (int y = 1; y <= h; y++) {
  52.                     field[(y * (w + 2)) + x] = (byte)(R.Next(100) <= 15 ? 1 : 0);
  53.                 }
  54.             }
  55.             altFrame = false;
  56.             tmrFrames.Enabled = true;
  57.             Game();
  58.         }
  59.  
  60.         public frmDavesLife(string path) {
  61.             Initialize();
  62.             for (x = 0; x < outerL * 2; x++) field[x] = 0;
  63.             altFrame = false;
  64.             string[] pattern = System.IO.File.ReadAllLines(path);
  65.             for (int x = 0; x < (pattern[0].Length <= this.ClientSize.Width ? pattern[0].Length : this.ClientSize.Width); x++) {
  66.                 for (int y = 0; y <= pattern.GetUpperBound(0); y++) {
  67.                     field[x + (y * w)] = byte.Parse(pattern[y][x].ToString());
  68.                 }
  69.             }
  70.             tmrFrames.Enabled = true;
  71.             Game();
  72.         }
  73.  
  74.         void Initialize() {
  75.             this.ClientSize = new Size(800, 600);
  76.             this.FormBorderStyle = FormBorderStyle.Fixed3D;
  77.             this.MinimizeBox = false;
  78.             this.MaximizeBox = false;
  79.             this.DoubleBuffered = true;
  80.             this.Text = "Dave's Game of Life";
  81.             this.Deactivate += new EventHandler(Form1_Deactivate);
  82.             this.Activated += new EventHandler(frmDavesLife_Activated);
  83.             this.Paint += new PaintEventHandler(Form1_Paint);
  84.             tmrFrames.Tick += new EventHandler(tmrFrames_Tick);
  85.             canvas = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
  86.             w = (uint)canvas.Width;
  87.             h = (uint)canvas.Height;
  88.             bmpRect = new Rectangle(0, 0, (int)w, (int)h);
  89.             l = w * h;
  90.             w1 = (w + 2) - 1;
  91.             wp1 = (w + 2) + 1;
  92.             //lw = l - w;
  93.             w2 = w + 2;
  94.             w3 = w + 3;
  95.             outerL = (w + 2) * (h + 2);
  96.             g = Graphics.FromImage(canvas);
  97.             g.Clear(Color.Black);
  98.             field = new byte[outerL * 2];
  99.             tmrFrames.Interval = 1000;
  100.             if (cycleColors) {
  101.                 rVal = colorList[0].R;
  102.                 gVal = colorList[0].G;
  103.                 bVal = colorList[0].B;
  104.             }
  105.             else
  106.                 col = 0xffffffff;
  107.             this.Show();
  108.             Application.DoEvents();
  109.         }
  110.  
  111.         void frmDavesLife_Activated(object sender, EventArgs e) {
  112.             if (!gameRunning) {
  113.                 gameRunning = true;
  114.                 Game();
  115.             }
  116.         }
  117.  
  118.         void tmrFrames_Tick(object sender, EventArgs e) {
  119.             timerCount++;
  120.             if (gameRunning) {
  121.                 FPSTotal += FPS;
  122.                 frameCount++;
  123.             }
  124.             this.Text = string.Format(
  125.                 "{0} ({1}) - {2}",
  126.                 FPS.ToString(),
  127.                 FPSTotal / frameCount,
  128.                 timerCount);
  129.             FPS = 0;
  130.         }
  131.  
  132.         void Form1_Paint(object sender, PaintEventArgs e) {
  133.             e.Graphics.DrawImageUnscaled(canvas, 0, 0);
  134.         }
  135.  
  136.         void Form1_Deactivate(object sender, EventArgs e) {
  137.             gameRunning = false;
  138.         }
  139.  
  140.         void Game() {
  141.             while (gameRunning) {
  142.                 FPS++;
  143.                 //if (cycleColors)
  144.                 //    CycleColors();
  145.                 ComputeFrame();
  146.                 this.Refresh();
  147.                 Application.DoEvents();
  148.                 altFrame = !altFrame;
  149.             }
  150.         }
  151.  
  152.         void CycleColors() { //this method could be optimized, but it's such a small hit on performance that it frankly doesn't matter
  153.             Color col1 = colorList[currCycleItem];
  154.             Color col2 = currCycleItem < (colorList.Length - 1) ? colorList[currCycleItem + 1] : colorList[0];
  155.             rVal = (byte)((((col2.R - col1.R) / (double)cycleLength) * currCycleFrame) + col1.R);
  156.             gVal = (byte)((((col2.G - col1.G) / (double)cycleLength) * currCycleFrame) + col1.G);
  157.             bVal = (byte)((((col2.B - col1.B) / (double)cycleLength) * currCycleFrame) + col1.B);
  158.             if (++currCycleFrame == cycleLength) {
  159.                 currCycleFrame = 0;
  160.                 currCycleItem = (currCycleItem + 1) % (uint)colorList.Length;
  161.             }
  162.             col = 0xff000000 | (uint)((rVal << 16) | (gVal << 8) | bVal);
  163.         }
  164.  
  165.         void ComputeFrame() {
  166.             i = 0;
  167.             x = 0;
  168.  
  169.             //lock the canvas, because i haven't delved into actual bitmap pointer drawing to the screen itself
  170.             bmpData = canvas.LockBits(bmpRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
  171.             currPos = (uint*)bmpData.Scan0;
  172.  
  173.             fixed (byte* f = field) { //field contains the entire grid plus swap
  174.                 t = f + w3; //starting point of the current generation
  175.                 a = t; //starting point of the next generation
  176.  
  177.                 //determine which is which
  178.                 if (altFrame) t += outerL;
  179.                 else a += outerL;
  180.  
  181.                 while (i++ < l) {
  182.                     //sum living neighbors
  183.                     n = (byte)(*(t - 1) + *(t + 1) + *(t - w2) + *(t + w2) + *(t - w1) + *(t + w1) + *(t - wp1) + *(t + wp1));
  184.  
  185.                     if (*t == 1) { //current cell is alive
  186.                         *a = (byte)((n != 2 && n != 3) ? 0 : 1);
  187.                         *currPos = 0xffffffff; // col;
  188.                     }
  189.                     else { //he's dead, jim
  190.                         *a = (byte)(n == 3 ? 1 : 0);
  191.                         //if (fadeColors) { //fancy color cycling and fading, looks cool, but is slow
  192.                         //    if ((*currPos & 0x00ff0000) > (uint)(colLimit << 16)) *currPos -= (uint)(colDecVal << 16);
  193.                         //    if ((*currPos & 0x0000ff00) > (uint)(colLimit << 8)) *currPos -= (uint)(colDecVal << 8);
  194.                         //    if ((*currPos & 0x000000ff) > (uint)(colLimit)) *currPos -= (uint)(colDecVal);
  195.                         //}
  196.                         //else
  197.                         *currPos = 0xff000000;
  198.                     }
  199.  
  200.                     ++currPos;
  201.                     if (++x == w) {
  202.                         x = 0;
  203.                         a += 3;
  204.                         t += 3;
  205.                     }
  206.                     else {
  207.                         ++a;
  208.                         ++t;
  209.                     }
  210.                 }
  211.             }
  212.             canvas.UnlockBits(bmpData);
  213.         }
  214.     }
  215.  
  216.     static class Program {
  217.         [STAThread]
  218.         static void Main(string[] arg) {
  219.             try {
  220.                 if (arg.Length > 0 && System.IO.File.Exists(arg[0]))
  221.                     Application.Run(new frmDavesLife(arg[0]));
  222.                 else
  223.                     Application.Run(new frmDavesLife());
  224.             }
  225.             catch { }
  226.         }
  227.     }
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement