Advertisement
Guest User

FloodFill

a guest
Oct 11th, 2012
447
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.66 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3.  
  4. namespace FloodFill
  5. {
  6.     internal class Program
  7.     {
  8.         private const int MAP_SIZE = 1024; // only powers of two are supported
  9.  
  10.         private static void Main()
  11.         {
  12.             var map = new byte[MAP_SIZE * MAP_SIZE];
  13.  
  14.             var stopwatch = Stopwatch.StartNew();
  15.             {
  16.                 FloodFill(map, startX: 123, startY: 123, fromValue: 0, toValue: 1);
  17.             }
  18.             stopwatch.Stop();
  19.  
  20.             Console.WriteLine(stopwatch.ElapsedMilliseconds);
  21.             Console.ReadLine();
  22.         }
  23.  
  24.         private static void FloodFill(byte[] map, int startX, int startY, byte fromValue, byte toValue)
  25.         {
  26.             int shift = (int) Math.Round(Math.Log(map.Length, 4)); // if the array's length is (2^x * 2^x), then shift = x
  27.             int startIndex = startX + (startY << shift);
  28.  
  29.             if (map[startIndex] != fromValue)
  30.             {
  31.                 return;
  32.             }
  33.  
  34.             int size = 1 << shift;
  35.             int sizeMinusOne = size - 1;
  36.             int xMask = size - 1;
  37.             int minIndexForVerticalCheck = size;
  38.             int maxIndexForVerticalCheck = map.Length - size - 1;
  39.  
  40.             map[startIndex] = toValue;
  41.  
  42.             var queue = new FastQueue<int>();
  43.             queue.Enqueue(startIndex);
  44.  
  45.             while (queue.Count > 0)
  46.             {
  47.                 int index = queue.Dequeue();
  48.                 int x = index & xMask;
  49.  
  50.                 if (x > 0)
  51.                 {
  52.                     if (map[index - 1] == fromValue)
  53.                     {
  54.                         map[index - 1] = toValue;
  55.                         queue.Enqueue(index - 1);
  56.                     }
  57.                 }
  58.                 if (x < sizeMinusOne)
  59.                 {
  60.                     if (map[index + 1] == fromValue)
  61.                     {
  62.                         map[index + 1] = toValue;
  63.                         queue.Enqueue(index + 1);
  64.                     }
  65.                 }
  66.                 if (index >= minIndexForVerticalCheck)
  67.                 {
  68.                     if (map[index - size] == fromValue)
  69.                     {
  70.                         map[index - size] = toValue;
  71.                         queue.Enqueue(index - size);
  72.                     }
  73.                 }
  74.                 if (index <= maxIndexForVerticalCheck)
  75.                 {
  76.                     if (map[index + size] == fromValue)
  77.                     {
  78.                         map[index + size] = toValue;
  79.                         queue.Enqueue(index + size);
  80.                     }
  81.                 }
  82.             }
  83.         }
  84.     }
  85.  
  86.     internal class FastQueue<T> where T : struct
  87.     {
  88.         private const int INITIAL_CAPACITY = 16;
  89.  
  90.         private T[] items;
  91.         private int size;
  92.         private int mask;
  93.         private int head, tail;
  94.  
  95.         public FastQueue()
  96.         {
  97.             items = new T[INITIAL_CAPACITY];
  98.             mask = INITIAL_CAPACITY - 1;
  99.             head = tail = 0;
  100.             size = 0;
  101.         }
  102.  
  103.         public int Count
  104.         {
  105.             get { return size; }
  106.         }
  107.  
  108.         public void Enqueue(T item)
  109.         {
  110.             if (size == items.Length)
  111.             {
  112.                 IncreaseCapacity(items.Length << 1);
  113.             }
  114.  
  115.             items[head & mask] = item;
  116.             head++;
  117.             size++;
  118.         }
  119.  
  120.         public T Dequeue()
  121.         {
  122.             var item = items[tail & mask];
  123.             tail++;
  124.             size--;
  125.             return item;
  126.         }
  127.  
  128.         private void IncreaseCapacity(int capacity)
  129.         {
  130.             Array.Resize(ref items, capacity);
  131.             mask = capacity - 1;
  132.         }
  133.     }
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement