public void Ellers() { AllWalls(); ChangeCells(Out, In); int x0, x1, y0, y1; GetBounds(out x0, out x1, out y0, out y1, In); int rowLen = 1 + (x1 - x0) / 2; ArrayOfSets cur = new ArrayOfSets(rowLen); for (int y = y0; y <= y1 - 2; y += 2) { // Join some adjacent cells in the row at random for (int i = 1; i < rowLen; ++i) { int x = x0 + i * 2; if (cur[i - 1] != cur[i] && Rnd(2) != 0) { SetWall(new Pt(x, y), new Pt(x - 2, y), false); cur.JoinAt(i, i - 1); } } // Make vertical connections ArrayOfSets next = new ArrayOfSets(rowLen); int[] sets = cur.SetIDs.ToArray(); for (int i = 0; i < sets.Length; ++i) { int[] posns = cur.PositionsOf(sets[i]); int conn = Math.Max(1, posns.Length / 2); while (conn > 0) { int r = RandomOf(posns); int x2 = x0 + 2 * r; if (GetWall(new Pt(x2, y), new Pt(x2, y + 2))) { SetWall(new Pt(x2, y), new Pt(x2, y + 2), false); next[r] = cur[r]; --conn; } } } cur = next; } // Join sets on final row for (int i = 1; i < rowLen; ++i) { if (cur[i - 1] != cur[i]) { int x = x0 + 2 * i; SetWall(new Pt(x - 2, y1), new Pt(x, y1), false); cur.JoinAt(i, i - 1); } } }
public void Kruskals() { AllWalls(); ChangeCells(Out, In); // Build a list of walls List <Pt> wallsFrom = new List <Pt>(); List <Pt> wallsTo = new List <Pt>(); foreach (Pt from in Locs) { foreach (Pt to in Select(Neighbours(from), In)) { if (from.CompareTo(to) < 0) { wallsFrom.Add(from); wallsTo.Add(to); } } } // Map points to entries in an array of sets Dictionary <Pt, int> dict = new Dictionary <Pt, int>(); int ind = 0; foreach (Pt pt in Locs) { dict[pt] = ind++; } ArrayOfSets arr = new ArrayOfSets(ind); // For each wall, in random order while (wallsFrom.Count > 0) { int i = Rnd(wallsFrom.Count); Pt from = wallsFrom[i]; Pt to = wallsTo[i]; wallsFrom.RemoveAt(i); wallsTo.RemoveAt(i); // Break down wall if places on either side are in different sets, // and join the sets int iFrom = dict[from]; int iTo = dict[to]; if (arr[iFrom] != arr[iTo]) { arr.JoinAt(iFrom, iTo); SetWall(from, to, false); } } }