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); }
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])); }
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); } }
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)); }
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); }
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)); }
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); }
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); }
// 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); }
// 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); }
// 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); }
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); }
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); } }
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; }
// 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)); }