Advertisement
Guest User

FloodFill

a guest
Oct 12th, 2012
1,078
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.13 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 = 1024; // only powers of two are supported
  10.  
  11.         private static void Main()
  12.         {
  13.             var map = new byte[MAP_SIZE * MAP_SIZE];
  14.  
  15.             var stopwatch = Stopwatch.StartNew();
  16.             {
  17.                 FloodFill(map, startX: 123, startY: 123, fromValue: 0, toValue: 1);
  18.             }
  19.             stopwatch.Stop();
  20.  
  21.             Console.WriteLine(stopwatch.ElapsedMilliseconds);
  22.  
  23.             // Test results
  24.             if (map.Any(item => item == 0))
  25.             {
  26.                 Console.WriteLine("Error");
  27.             }
  28.             else
  29.             {
  30.                 Console.WriteLine("Ok");
  31.             }
  32.  
  33.             Console.ReadLine();
  34.         }
  35.  
  36.         private static void FloodFill(byte[] map, int startX, int startY, byte fromValue, byte toValue)
  37.         {
  38.             int shift = (int) Math.Round(Math.Log(map.Length, 4)); // if the array's length is (2^x * 2^x), then shift = x
  39.             int startIndex = startX + (startY << shift);
  40.  
  41.             if (map[startIndex] != fromValue)
  42.             {
  43.                 return;
  44.             }
  45.  
  46.             // initialize flood fill
  47.             int size = 1 << shift;
  48.             int sizeMinusOne = size - 1;
  49.             int xMask = size - 1;
  50.             int minIndexForVerticalCheck = size;
  51.             int maxIndexForVerticalCheck = map.Length - size - 1;
  52.  
  53.             // initialize queue
  54.             int capacity = size * 2;
  55.             int mask = capacity - 1;
  56.             uint tail = 0;
  57.             uint head = 0;
  58.             var queue = new int[capacity];
  59.  
  60.             map[startIndex] = toValue;
  61.             queue[tail++ & mask] = startIndex;
  62.  
  63.             while (tail - head > 0)
  64.             {
  65.                 int index = queue[head++ & mask];
  66.                 int x = index & xMask;
  67.  
  68.                 if (x > 0 && map[index - 1] == fromValue)
  69.                 {
  70.                     map[index - 1] = toValue;
  71.                     queue[tail++ & mask] = index - 1;
  72.                 }
  73.                 if (x < sizeMinusOne && map[index + 1] == fromValue)
  74.                 {
  75.                     map[index + 1] = toValue;
  76.                     queue[tail++ & mask] = index + 1;
  77.                 }
  78.                 if (index >= minIndexForVerticalCheck && map[index - size] == fromValue)
  79.                 {
  80.                     map[index - size] = toValue;
  81.                     queue[tail++ & mask] = index - size;
  82.                 }
  83.                 if (index <= maxIndexForVerticalCheck && map[index + size] == fromValue)
  84.                 {
  85.                     map[index + size] = toValue;
  86.                     queue[tail++ & mask] = index + size;
  87.                 }
  88.             }
  89.         }
  90.     }
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement