Advertisement
Guest User

Untitled

a guest
Feb 28th, 2013
936
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.19 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4.  
  5. namespace FloodFill
  6. {
  7.     internal class Program
  8.     {
  9.         private const int MAP_SIZE = 4096; // only powers of two are supported
  10.  
  11.         private static void Main()
  12.         {
  13.             var map = new byte[MAP_SIZE * MAP_SIZE];
  14.             for (int i = 0; i < MAP_SIZE; i++)
  15.             {
  16.                 map[0 * MAP_SIZE + i] = 1;
  17.                 map[(MAP_SIZE - 1) * MAP_SIZE + i] = 1;
  18.  
  19.                 map[i * MAP_SIZE + 0] = 1;
  20.                 map[i * MAP_SIZE + MAP_SIZE - 1] = 1;
  21.             }
  22.  
  23.             var stopwatch = Stopwatch.StartNew();
  24.             {
  25.                 FloodFill(map, startX: 123, startY: 123, fromValue: 0, toValue: 1);
  26.             }
  27.             stopwatch.Stop();
  28.  
  29.             Console.WriteLine(stopwatch.ElapsedMilliseconds);
  30.  
  31.             // Test results
  32.             if (map.Any(item => item == 0))
  33.             {
  34.                 Console.WriteLine("Error");
  35.             }
  36.             else
  37.             {
  38.                 Console.WriteLine("Ok");
  39.             }
  40.  
  41.             Console.ReadLine();
  42.         }
  43.  
  44.         private static unsafe void FloodFill(byte[] map, int startX, int startY, byte fromValue, byte toValue)
  45.         {
  46.             int shift = (int)Math.Round(Math.Log(map.Length, 4)); // if the array's length is (2^x * 2^x), then shift = x
  47.             int startIndex = startX + (startY << shift);
  48.  
  49.             if (map[startIndex] != fromValue)
  50.             {
  51.                 return;
  52.             }
  53.  
  54.             // initialize flood fill
  55.             int size = 1 << shift;
  56.             int xMask = size - 1;
  57.  
  58.             // initialize queue
  59.             int capacity = size * 2;
  60.             int mask = capacity - 1;
  61.             uint tail = 0;
  62.             uint head = 0;
  63.             var queue = new int[capacity];
  64.  
  65.             fixed (byte* m = map)
  66.             fixed (int* q = queue)
  67.             {
  68.                 *(m + startIndex) = toValue;
  69.                 *(q + (tail++ & mask)) = startIndex;
  70.  
  71.                 while (tail - head > 0)
  72.                 {
  73.                     int index = q[head++ & mask];
  74.                     int x = index & xMask;
  75.                     byte* p = m + index;
  76.  
  77.                     if (*(p - 1) == fromValue)
  78.                     {
  79.                         *(p - 1) = toValue;
  80.                         *(q + (tail++ & mask)) = index - 1;
  81.                     }
  82.  
  83.                     if (*(p + 1) == fromValue)
  84.                     {
  85.                         *(p + 1) = toValue;
  86.                         *(q + (tail++ & mask)) = index + 1;
  87.                     }
  88.  
  89.                     if (*(p - size) == fromValue)
  90.                     {
  91.                         *(p - size) = toValue;
  92.                         *(q + (tail++ & mask)) = index - size;
  93.                     }
  94.  
  95.                     if (*(p + size) == fromValue)
  96.                     {
  97.                         *(p + size) = toValue;
  98.                         *(q + (tail++ & mask)) = index + size;
  99.                     }
  100.                 }
  101.             }
  102.         }
  103.     }
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement