public void Iterate()
        {
            int start = -state.GetLength(0) / 2;
            root = root.NextGeneration(state, start, start).Expand();

            generation += PowerTwos.Get(root.Level - 2);
        }
        public static Node Lookup(Node node)
        {
            int index = node.HashValue % TABLE_SIZE;
            if (index < 0)
            {
                index = -index;
            }

            Node current = nodeTable[index];
            if (current == null)
            {
                return null;
            }

            while (true)
            {
                // If the node is in the table, return the node.
                if (current.DeepEqualTo(node))
                {
                    return current;
                }

                if (current.Next == null)
                {
                    return null;
                }

                current = current.Next;
            }
        }
        private void CreateEmptyGrid()
        {
            state = new bool[16, 16];
            int top = 6;
            int left = 6;

            state[top, left] = true;
            state[top + 1, left] = true;
            state[top, left + 1] = true;
            state[top + 1, left + 1] = false;

            root = CreateNode(state);
            generation = 0;
        }
Example #4
0
        // Level 0 constructor.
        public Node(bool childValue)
        {
            this.level = 0;
            this.childValue = childValue;

            this.topLeft = null;
            this.topRight = null;
            this.bottomLeft = null;
            this.bottomRight = null;

            this.population = childValue ? 1 : 0;

            this.hashValue = GetHashCode();
        }
Example #5
0
        public Node(Node topLeft, Node topRight, Node bottomLeft, Node bottomRight, int level)
        {
            Debug.Assert(level > 0, "Cannot create a child node with children.");

            this.level = level;

            this.topLeft = NodeTable.Find(topLeft);
            this.topRight = NodeTable.Find(topRight);
            this.bottomLeft = NodeTable.Find(bottomLeft);
            this.bottomRight = NodeTable.Find(bottomRight);

            this.population = topLeft.population + topRight.population
                + bottomLeft.population + bottomRight.population;

            this.hashValue = GetHashCode();
        }
        // Returns a pointer to an equivalent node in the hashtable. The node is
        // stored and returned if it is not stored in the hashtable.
        public static Node Find(Node node)
        {
            int index = node.HashValue % TABLE_SIZE;
            if (index < 0)
            {
                index = -index;
            }

            Node current = nodeTable[index];

            if (current == null)
            {
                nodeTable[index] = node;

                return node;
            }

            while (true)
            {
                // If the node is in the table, return the node.
                if (current.DeepEqualTo(node))
                {
                    return current;
                }

                // If the table does not contain the node, add it to the table
                // and return it.
                if (current.Next == null)
                {
                    current.LinkTo(node);

                    return node;
                }

                current = current.Next;
            }
        }
        private void CreateGlider()
        {
            int l = 7;
            int size = PowerTwos.Get(l);

            state = new bool[size, size];

            int top = 1;
            int left = 16;
            state[top + 0, left + 1] = true;
            state[top + 1, left + 2] = true;
            state[top + 2, left + 0] = true;
            state[top + 2, left + 1] = true;
            state[top + 2, left + 2] = true;

            top = 1;
            left = 1;
            state[top + 0, left + 1] = true;
            state[top + 1, left + 2] = true;
            state[top + 2, left + 0] = true;
            state[top + 2, left + 1] = true;
            state[top + 2, left + 2] = true;

            top = 1;
            left = 10;
            state[top + 0, left + 1] = true;
            state[top + 1, left + 2] = true;
            state[top + 2, left + 0] = true;
            state[top + 2, left + 1] = true;
            state[top + 2, left + 2] = true;

            root = CreateNode(state);
            generation = 0;
        }
        private void CreateSwitchEngine()
        {
            state = new bool[256, 256];

            int top = 130;
            int left = 130;
            state[top + 5, left] = true;
            state[top + 5, left + 2] = true;
            state[top + 4, left + 2] = true;
            state[top + 1, left + 4] = true;
            state[top + 2, left + 4] = true;
            state[top + 3, left + 4] = true;
            state[top, left + 6] = true;
            state[top + 1, left + 6] = true;
            state[top + 2, left + 6] = true;
            state[top + 1, left + 7] = true;

            root = CreateNode(state);
            generation = 0;
        }
        private void CreateGosperGliderGun()
        {
            state = new bool[128, 128];

            int top = 30;
            int left = 30;

            state[top + 4, left + 0] = true;
            state[top + 4, left + 1] = true;
            state[top + 5, left + 0] = true;
            state[top + 5, left + 1] = true;

            state[top + 2, left + 12] = true;
            state[top + 2, left + 13] = true;
            state[top + 3, left + 11] = true;
            state[top + 4, left + 10] = true;
            state[top + 5, left + 10] = true;
            state[top + 6, left + 10] = true;
            state[top + 7, left + 11] = true;
            state[top + 8, left + 12] = true;
            state[top + 8, left + 13] = true;

            state[top + 5, left + 14] = true;
            state[top + 3, left + 15] = true;
            state[top + 4, left + 16] = true;
            state[top + 5, left + 16] = true;
            state[top + 5, left + 17] = true;
            state[top + 6, left + 16] = true;
            state[top + 7, left + 15] = true;

            state[top + 0, left + 24] = true;
            state[top + 1, left + 24] = true;
            state[top + 1, left + 22] = true;
            state[top + 2, left + 20] = true;
            state[top + 2, left + 21] = true;
            state[top + 3, left + 20] = true;
            state[top + 3, left + 21] = true;
            state[top + 4, left + 20] = true;
            state[top + 4, left + 21] = true;
            state[top + 5, left + 22] = true;
            state[top + 5, left + 24] = true;
            state[top + 6, left + 24] = true;

            state[top + 2, left + 34] = true;
            state[top + 2, left + 35] = true;
            state[top + 3, left + 34] = true;
            state[top + 3, left + 35] = true;

            root = CreateNode(state);
            generation = 0;
        }
Example #10
0
        public bool DeepEqualTo(Node a)
        {
            if (level != a.level)
            {
                return false;
            }

            if (level == 0)
            {
                return childValue == a.childValue;
            }

            return topLeft == a.topLeft && topRight == a.topRight
                && bottomLeft == a.bottomLeft && bottomRight == a.bottomRight;
        }
Example #11
0
        private Node CenteredVerticalSubNodeForward(Node top, Node bottom, bool[,] state, int x, int y)
        {
            Debug.Assert(top.level == bottom.level, "Must have equal levels.");
            Debug.Assert(top.level > 1, "Level must be greater than 1.");

            return new Node(top.bottomLeft, top.bottomRight,
                bottom.topLeft, bottom.topRight, top.level).NextGeneration(state, x, y);
        }
Example #12
0
        private Node CenteredHorizontalSubNodeForward(Node left, Node right, bool[,] state, int x, int y)
        {
            Debug.Assert(left.level == right.level, "Must have equal levels.");
            Debug.Assert(left.level > 1, "level must be greater than 1.");

            return new Node(left.topRight, right.topLeft,
                left.bottomRight, right.bottomLeft, left.level).NextGeneration(state, x, y);
        }
Example #13
0
        // Return a new node 1 level down, centered at this node
        // and 2^(k - 2) generations forward if super speed is enabled.
        // x and y are the coordinates of state grid of this node.
        public Node NextGeneration(bool[,] state, int x, int y)
        {
            Debug.Assert(level >= 2, "Can only be called on a node at level 2 or above.");

            if (result == null)
            {
                // Check if the result is stored in the hash table.
                Node hashed = NodeTable.Lookup(this);
                if (hashed != null && hashed.result != null)
                {
                    result = hashed.result;
                }
            }

            if (result != null)
            {
                // Recurse into the children to set the state.
                if (state != null)
                {
                    int offset = PowerTwos.Get(level - 2);
                    result.Flatten(state, x + offset, y + offset);
                }

                return result;
            }

            if (level == 2)
            {
                bool n00 = topLeft.topLeft.childValue;
                bool n01 = topLeft.topRight.childValue;
                bool n02 = topLeft.bottomLeft.childValue;
                bool n03 = topLeft.bottomRight.childValue;

                bool n10 = topRight.topLeft.childValue;
                bool n11 = topRight.topRight.childValue;
                bool n12 = topRight.bottomLeft.childValue;
                bool n13 = topRight.bottomRight.childValue;

                bool n20 = bottomLeft.topLeft.childValue;
                bool n21 = bottomLeft.topRight.childValue;
                bool n22 = bottomLeft.bottomLeft.childValue;
                bool n23 = bottomLeft.bottomRight.childValue;

                bool n30 = bottomRight.topLeft.childValue;
                bool n31 = bottomRight.topRight.childValue;
                bool n32 = bottomRight.bottomLeft.childValue;
                bool n33 = bottomRight.bottomRight.childValue;

                // Create four nodes at level 0, 1 generation forward.
                Node resultTopLeft = new Node(IsAlive(n03,
                    new bool[] { n00, n01, n02, n10, n12, n20, n21, n30 }));

                Node resultTopRight = new Node(IsAlive(n12,
                    new bool[] { n01, n03, n10, n11, n13, n21, n30, n31 }));

                Node resultBottomLeft = new Node(IsAlive(n21,
                    new bool[] { n02, n03, n12, n20, n22, n23, n30, n32 }));

                Node resultBottomRight = new Node(IsAlive(n30,
                    new bool[] { n03, n12, n13, n21, n23, n31, n32, n33 }));

                // Return a new node at level 1 which is the center 2 by 2 of this level 2 node
                // 1 generation forward.
                result = new Node(resultTopLeft, resultTopRight,
                    resultBottomLeft, resultBottomRight, 1);

                // Set state.
                if (state != null)
                {
                    state[y + 1, x + 1] = result.topLeft.childValue;
                    state[y + 1, x + 2] = result.topRight.childValue;

                    state[y + 2, x + 1] = result.bottomLeft.childValue;
                    state[y + 2, x + 2] = result.bottomRight.childValue;
                }

                return result;
            }

            int k3 = PowerTwos.Get(level - 3);
            int k23 = (k3 << 1) + k3;

            // Create the nine sub nodes.
            Node t00 = topLeft.NextGeneration(null, 0, 0);
            Node t01 = CenteredHorizontalSubNodeForward(topLeft, topRight, null, 0, 0);
            Node t02 = topRight.NextGeneration(null, 0, 0);

            Node t10 = CenteredVerticalSubNodeForward(topLeft, bottomLeft, null, 0, 0);
            Node t11 = CentredSubNodeForward(null, 0, 0);
            Node t12 = CenteredVerticalSubNodeForward(topRight, bottomRight, null, 0, 0);

            Node t20 = bottomLeft.NextGeneration(null, 0, 0);
            Node t21 = CenteredHorizontalSubNodeForward(bottomLeft, bottomRight, null, 0, 0);
            Node t22 = bottomRight.NextGeneration(null, 0, 0);

            // Return a centered sub node 1 level down, 2^(level - 2) generations forward.
            result = new Node(
                new Node(t00, t01, t10, t11, level - 1).NextGeneration(state, x + k3, y + k3),
                new Node(t01, t02, t11, t12, level - 1).NextGeneration(state, x + k23, y + k3),
                new Node(t10, t11, t20, t21, level - 1).NextGeneration(state, x + k3, y + k23),
                new Node(t11, t12, t21, t22, level - 1).NextGeneration(state, x + k23, y + k23),
                level - 1);

            return result;
        }
Example #14
0
        public void LinkTo(Node next)
        {
            Debug.Assert(this.next == null, "This node item is already linked.");

            this.next = next;
        }