Example #1
0
        static (int, int) SimulateWithAdjecency(Matrix2D <char> matrix, Func <int, int, Matrix2D <char>, int[]> adjacencyFunc = null, int crowdedThreshold = 4, bool output = false)
        {
            if (adjacencyFunc == null)
            {
                adjacencyFunc = FindImmediateNeighbours;
            }
            int[]   indices        = new int[128 * 128];   //max 128*128
            int[][] adjacencyLists = new int[128 * 128][]; //max 128*128

            for (int y = 0; y < matrix.Height; y++)
            {
                for (int x = 0; x < matrix.Width; x++)
                {
                    int index = (y << 7) + x;
                    var ptr   = matrix.GetIndex(x, y);
                    indices[index]        = ptr;
                    adjacencyLists[index] = adjacencyFunc(x, y, matrix);
                }
            }

            var current    = matrix;
            var next       = matrix.Clone();
            int numFlipped = 1;
            int iterations = 0;

            while (numFlipped > 0)
            {
                numFlipped = 0;
                for (int y = 0; y < matrix.Height; y++)
                {
                    for (int x = 0; x < matrix.Width; x++)
                    {
                        int index     = (y << 7) + x;
                        var adjacency = adjacencyLists[index];
                        if (adjacency == null)
                        {
                            continue;                    //null or floor
                        }
                        var ptr = indices[index];
                        var c   = current.Array[ptr];
                        if (c == 'L' && IsClear(adjacency, current))
                        {
                            next.Array[ptr] = '#';
                            numFlipped++;
                        }
                        else if (c == '#' && IsCrowded(adjacency, current, crowdedThreshold))
                        {
                            next.Array[ptr] = 'L';
                            numFlipped++;
                        }
                        else
                        {
                            next.Array[ptr] = current.Array[ptr];
                        }
                    }
                }
                if (output)
                {
                    Console.CursorLeft = 0;
                    Console.CursorTop  = 0;
                    next.Dump();
                    Thread.Sleep(50);
                }
                //bufferswap
                var tmp = current;
                current = next;
                next    = tmp;
                iterations++;
            }

            return(current.Array.Count(c => c == '#'), iterations);
        }