Ejemplo n.º 1
0
        public override LifeNodeBase Next()
        {
            if (this.population == 0)
            {
                return(this.nw);
            }
            nextCalls++;
            if (this.next == null)
            {
                nextCacheMiss++;
                // If the children are leaves, we can directly calculate
                // the new state of the center of this node.
                if (this.nw.IsLeaf)
                {
                    this.next = this.calcNewLeaf();
                }
                else
                {
                    // We put together 4 new nodes each half the size of this one
                    // and designed to calculate the center half of this node.  In other words,
                    // we want to calculate the new value of this.nw.se, this.ne.sw, etc., so we
                    // put together artificial subnodes that "wrap" nw.se, ne.sw, etc., calc their
                    // next generation and then stick those four results together into the new child node
                    // X  X  X  X  |  X  X  X  X
                    // X  nw nw nc | nc ne ne  X
                    // X  nw nw nc | nc ne ne  X
                    // X  cw cw cc | cc ce ce  X
                    // X  cw cw cc | cc ce ce  X
                    // X  sw sw sc | sc se se  X
                    // X  sw sw sc | sc se se  X
                    // X  X  X  X  |  X  X  X  X
                    LifeNodeBase nw = ((LifeNode)this.nw).TemporaryCenterNode();
                    LifeNodeBase nc = LifeNode.TemporaryCenterXNode(this.nw, this.ne);
                    LifeNodeBase ne = ((LifeNode)this.ne).TemporaryCenterNode();
                    LifeNodeBase cw = LifeNode.TemporaryCenterYNode(this.nw, this.sw);
                    LifeNodeBase cc = this.TemporaryCenterCenterNode();
                    LifeNodeBase ce = LifeNode.TemporaryCenterYNode(this.ne, this.se);
                    LifeNodeBase se = ((LifeNode)this.se).TemporaryCenterNode();
                    LifeNodeBase sc = LifeNode.TemporaryCenterXNode(this.sw, this.se);
                    LifeNodeBase sw = ((LifeNode)this.sw).TemporaryCenterNode();

                    // From those 9 temporary nodes, we construct four larger nodes and
                    // then calculate their next generation

                    LifeNodeBase tnw = LifeNode.CreateNode(nw, nc, cw, cc);
                    LifeNodeBase tne = LifeNode.CreateNode(nc, ne, cc, ce);
                    LifeNodeBase tsw = LifeNode.CreateNode(cw, cc, sw, sc);
                    LifeNodeBase tse = LifeNode.CreateNode(cc, ce, sc, se);
                    tnw = tnw.Next();
                    tne = tne.Next();
                    tsw = tsw.Next();
                    tse = tse.Next();

                    // Put those next gens together and we get the next gen of this node
                    // cache it of course
                    this.next = LifeNode.CreateNode(tnw, tne, tsw, tse);
                }
            }
            return(this.next);
        }
Ejemplo n.º 2
0
        public override LifeNode ExpandUniverse()
        {
            LeafLifeNode emptySpace = LeafLifeNode.CreateNode(0);

            // Subnodes for nw, ne, sw, se
            LeafLifeNode[] subNodes = new LeafLifeNode[] { emptySpace, emptySpace, emptySpace, emptySpace };

            // New nw will have old nw value in its se corner
            if ((this.bits & 0x01) == 0x01)
            {
                subNodes[0] = LeafLifeNode.CreateNode(0x08);
            }
            // New ne will have old ne in its sw corner
            if ((this.bits & 0x02) == 0x02)
            {
                subNodes[1] = LeafLifeNode.CreateNode(0x04);
            }
            if ((this.bits & 0x04) == 0x04)
            {
                subNodes[2] = LeafLifeNode.CreateNode(0x02);
            }
            if ((this.bits & 0x08) == 0x08)
            {
                subNodes[3] = LeafLifeNode.CreateNode(0x01);
            }
            return(LifeNode.CreateNode(subNodes[0], subNodes[1], subNodes[2], subNodes[3]));
        }
Ejemplo n.º 3
0
 public static void GarbageCollect(LifeNode universe)
 {
     cache = new Dictionary <LifeNode, LifeNode>();
     foreach (KeyValuePair <LifeNode, LifeNode> pair in cache)
     {
         LifeNode node = pair.Key;
         CreateNode(node.nw, node.ne, node.sw, node.se);
     }
 }
Ejemplo n.º 4
0
        public static LifeNodeBase EmptySpace(int dimension)
        {
            Debug.Assert(dimension > 1);
            Debug.Assert(Utils.IsPowerOfTwo(dimension));
            if (dimension == 2)
            {
                return(LeafLifeNode.CreateNode(0));
            }
            LifeNodeBase next = EmptySpace(dimension / 2);

            return(LifeNode.CreateNode(next, next, next, next));
        }
Ejemplo n.º 5
0
        public override LifeNode ExpandUniverse()
        {
            LifeNodeBase emptySpace = LifeNode.EmptySpace(this.dimension / 2);
            LifeNode     newNW      = LifeNode.CreateNode(emptySpace, emptySpace, emptySpace, this.nw);

            Debug.Assert(newNW.Dimension == this.dimension);
            LifeNode newNE  = LifeNode.CreateNode(emptySpace, emptySpace, this.ne, emptySpace);
            LifeNode newSW  = LifeNode.CreateNode(emptySpace, this.sw, emptySpace, emptySpace);
            LifeNode newSE  = LifeNode.CreateNode(this.se, emptySpace, emptySpace, emptySpace);
            LifeNode retval = LifeNode.CreateNode(newNW, newNE, newSW, newSE);

            Debug.Assert(retval.Dimension == dimension * 2);
            Debug.Assert(retval.Population == this.Population);
            return(retval);
        }
Ejemplo n.º 6
0
        public static LifeNodeBase InitSpace(int dimension, InitLeaf initFunc)
        {
            if (!Utils.IsPowerOfTwo(dimension))
            {
                throw new InvalidOperationException("dimension must be a power of 2");
            }
            if (dimension == 2)
            {
                return(initFunc());
            }
            LifeNodeBase subNode1 = LifeNode.InitSpace(dimension / 2, initFunc);
            LifeNodeBase subNode2 = LifeNode.InitSpace(dimension / 2, initFunc);
            LifeNodeBase subNode3 = LifeNode.InitSpace(dimension / 2, initFunc);
            LifeNodeBase subNode4 = LifeNode.InitSpace(dimension / 2, initFunc);

            return(LifeNode.CreateNode(subNode1, subNode2, subNode3, subNode4));
        }
Ejemplo n.º 7
0
        public static LifeNode CreateNode(LifeNodeBase nw, LifeNodeBase ne, LifeNodeBase sw, LifeNodeBase se)
        {
            LifeNode newNode = new LifeNode(nw, ne, sw, se);
            LifeNode cached;

            if (!cache.TryGetValue(newNode, out cached))
            {
                cache.Add(newNode, newNode);
                misses++;
            }
            else
            {
                newNode = cached;
                hits++;
            }
            return(newNode);
        }
Ejemplo n.º 8
0
        public LifeNodeBase TemporaryCenterCenterNode()
        {
            LifeNodeBase retval = null;

            if (this.NW.IsOneStepLargerThanLeaf)
            {
                bool nwbit = this.nw.SE.IsAlive(1, 1);
                bool nebit = this.ne.SW.IsAlive(0, 1);
                bool swbit = this.sw.NE.IsAlive(1, 0);
                bool sebit = this.se.NW.IsAlive(0, 0);
                retval = LeafLifeNode.CreateNode(nwbit, nebit, swbit, sebit);
            }
            else
            {
                retval = LifeNode.CreateNode(this.nw.SE.SE, this.ne.SW.SW, this.sw.NE.NE, this.se.NW.NW);
            }
            return(retval);
        }
Ejemplo n.º 9
0
        // Create new LifeNode from central bits of nw, ne, sw, se
        public static LifeNodeBase CreateCenterNode(LifeNodeBase nw, LifeNodeBase ne, LifeNodeBase sw, LifeNodeBase se)
        {
            LifeNodeBase retval = null;

            if (nw.IsLeaf)
            {
                bool nwsebit = nw.IsAlive(1, 1);
                bool neswbit = ne.IsAlive(0, 1);
                bool swnebit = sw.IsAlive(1, 0);
                bool senwbit = se.IsAlive(0, 0);
                retval = LeafLifeNode.CreateNode(nwsebit, neswbit, swnebit, senwbit);
            }
            else
            {
                retval = LifeNode.CreateNode(nw.SE, ne.SW, sw.NE, se.NW);
            }
            return(retval);
        }
Ejemplo n.º 10
0
        // Given two nodes, n and s, pull out these bits
        // XX|XX|XX|XX
        // XX|XX|XX|XX
        // XX|XX|XX|XX
        // XX|NW|NE|XX
        //-------------
        // XX|SW|SE|XX
        // XX|XX|XX|XX
        // XX|XX|XX|XX
        // XX|XX|XX|XX
        public static LifeNodeBase TemporaryCenterYNode(LifeNodeBase n, LifeNodeBase s)
        {
            Debug.Assert(n.Dimension == s.Dimension);
            LifeNodeBase retval = null;

            if (n.IsOneStepLargerThanLeaf)
            {
                bool nwbit = n.SW.IsAlive(1, 1);
                bool nebit = n.SE.IsAlive(0, 1);
                bool swbit = s.NW.IsAlive(1, 0);
                bool sebit = s.NE.IsAlive(0, 0);
                retval = LeafLifeNode.CreateNode(nwbit, nebit, swbit, sebit);
            }
            else
            {
                retval = LifeNode.CreateNode(n.SW.SE, n.SE.SW, s.NW.NE, s.NE.NW);
            }
            return(retval);
        }
Ejemplo n.º 11
0
        // Given two nodes, w and e, pull out these bits
        // XX|XX|XX|XX||XX|XX|XX|XX
        // XX|XX|XX|NW||NE|XX|XX|XX
        // XX|XX|XX|SW||SE|XX|XX|XX
        // XX|XX|XX|XX||XX|XX|XX|XX
        public static LifeNodeBase TemporaryCenterXNode(LifeNodeBase w, LifeNodeBase e)
        {
            Debug.Assert(w.Dimension == e.Dimension);
            LifeNodeBase retval = null;

            if (w.IsOneStepLargerThanLeaf)
            {
                bool nwbit = w.NE.IsAlive(1, 1);
                bool nebit = e.NW.IsAlive(0, 1);
                bool swbit = w.SE.IsAlive(1, 0);
                bool sebit = e.SW.IsAlive(0, 0);
                retval = LeafLifeNode.CreateNode(nwbit, nebit, swbit, sebit);
            }
            else
            {
                retval = LifeNode.CreateNode(w.NE.SE, e.NW.SW, w.SE.NE, e.SW.NW);
            }
            return(retval);
        }
Ejemplo n.º 12
0
        public override bool Equals(object obj)
        {
            LifeNode other = obj as LifeNode;

            if (other != null)
            {
                if (this.dimension != other.dimension)
                {
                    return(false);
                }
                // Because the leaves are cached already we can
                // do pointer equality on them

                return((this.nw == other.nw) &&
                       (this.ne == other.ne) &&
                       (this.se == other.se) &&
                       (this.sw == other.sw));
            }
            return(false);
        }
Ejemplo n.º 13
0
 public static void GarbageCollect(LifeNode universe)
 {
     cache = new Dictionary<LifeNode, LifeNode>();
     foreach (KeyValuePair<LifeNode,LifeNode> pair in cache)
     {
         LifeNode node = pair.Key;
         CreateNode(node.nw, node.ne, node.sw, node.se);
     }
 }
Ejemplo n.º 14
0
 public static LifeNode CreateNode(LifeNodeBase nw, LifeNodeBase ne, LifeNodeBase sw, LifeNodeBase se)
 {
     LifeNode newNode = new LifeNode(nw, ne, sw, se);
     LifeNode cached;
     if (!cache.TryGetValue(newNode, out cached))
     {
         cache.Add(newNode, newNode);
         misses++;
     }
     else
     {
         newNode = cached;
         hits++;
     }
     return newNode;
 }
Ejemplo n.º 15
0
 // Next cell is created using "helper" temporary cells that surround
 // the center.
 //
 // XX|XX|XX|XX
 // XX|NW|NE|XX
 // XX|SW|SE|XX
 // XX|XX|XX|XX
 public LifeNodeBase TemporaryCenterNode()
 {
     Debug.Assert(this.IsLeaf == false);
     return(LifeNode.CreateCenterNode(this.nw, this.ne, this.sw, this.se));
 }