void GrowingTree(Func <List <Pt>, Pt> selector) { AllWalls(); // Choose a cell to be in the maze and add it to list List <Pt> list = new List <Pt>(); { Pt pt = RandomOf(Select(Locs, Out)); SetCell(pt, In); list.Add(pt); } while (list.Count > 0) { // Join from a cell in the list to a random neighbour, and add that to list Pt pt = selector(list); Pt[] ns = Select(Neighbours(pt), Out); Debug.Assert(ns.Length > 0); Pt next = RandomOf(ns); SetWall(pt, next, false); SetCell(next, In); list.Add(next); // Remove cells with no available neighbours List <Pt> check = new List <Pt>(); check.AddRange(Neighbours(pt)); check.AddRange(Neighbours(next)); foreach (Pt pt2 in check) { if (Select(Neighbours(pt2), Out).Length == 0) { list.Remove(pt2); } } } }
public int GetCell(Pt pt) { int ret = 0; _cells.TryGetValue(pt, out ret); return(ret); }
int GetWall(Pt pt) { int ret = 0; _walls.TryGetValue(pt, out ret); return(ret); }
public void FillCell(PaintContext pc, Pt pt, Pen pe, Brush br) { Pt[] vs = Vertices(pt); Point[] pts = pc.Points(vs); pc.Graphics.DrawPolygon(Pens.Green, pts); pc.Graphics.FillPolygon(br, pts); }
public void Wilsons() { AllWalls(); // Set a cell to be in SetCell(RandomOf(Select(Locs, Out)), In); while (true) { Pt[] pts = Select(Locs, Out); if (pts.Length == 0) { return; } Pt start = RandomOf(pts); Dictionary <Pt, int> dirns = new Dictionary <Pt, int>(); Pt loop = start; while (GetCell(loop) != In) { Pt[] n = Neighbours(loop); Pt next = RandomOf(SelectNot(n, 0)); int i = IndexOf(n, next); dirns[loop] = i; loop = next; } loop = start; while (dirns.ContainsKey(loop)) { Pt next = Neighbours(loop)[dirns[loop]]; SetCell(loop, In); SetWall(loop, next, false); loop = next; } } }
public void RecursiveBacktrack() { AllWalls(); Stack <Pt> stack = new Stack <Pt>(); { Pt pt = RandomOf(Select(Locs, Out)); SetCell(pt, In); stack.Push(pt); } while (stack.Count > 0) { Pt pt = stack.Peek(); Pt[] ns = Select(Neighbours(pt), Out); if (ns.Length == 0) { stack.Pop(); } else { Pt next = RandomOf(ns); SetWall(pt, next, false); SetCell(next, In); stack.Push(next); } } }
public int CompareTo(Pt p) { if (X != p.X) { return(X - p.X); } return(Y - p.Y); }
public void Solve(Pt start, Pt finish) { Dictionary <Pt, Pt> search = new Dictionary <Pt, Pt>(); List <Pt> from = new List <Pt>(); from.Add(start); while (from.Count > 0) { List <Pt> to = new List <Pt>(); foreach (Pt p in from) { Pt[] ns = Neighbours(p); foreach (Pt n in ns) { if (!GetWall(p, n)) { if (!search.ContainsKey(n)) { to.Add(n); search[n] = p; } } } } from = to; } Pt loop = finish; List <Pt> pts = new List <Pt>(); if (!PlotsMidway) { pts.Add(loop); } while (!loop.Equals(start)) { Pt next; if (!search.TryGetValue(loop, out next)) { // No solution _soln = null; return; } if (PlotsMidway) { pts.Add(Pt.Midway(loop, next)); } else { pts.Add(next); } loop = next; } if (pts.Count > 1) { _soln = pts.ToArray(); } }
public override void Init(Pt sz) { for (int y = 2; y < sz.Y - 1; y += 2) { for (int x = 2; x < sz.X; x += 2) { SetCell(new Pt(x, y), Out); } } }
void SetInWithFrontier(Pt c) { SetCell(c, In); foreach (Pt n in Neighbours(c)) { if (GetCell(n) == Out) { SetCell(n, Frontier); } } }
public void Generate(Pt sz) { Clear(); Init(sz); origin = Locs.First(); MethodInfo m = GetMethod(Algorithm); if (m != null) { m.Invoke(this, new object[0]); } }
public void SetWall(Pt pt0, Pt pt1, bool b) { int i0 = IndexOf(Neighbours(pt0), pt1); int i1 = IndexOf(Neighbours(pt1), pt0); if (i0 == -1 || i1 == -1) { return; } SetWall(pt0, SetBit(GetWall(pt0), i0, b)); SetWall(pt1, SetBit(GetWall(pt1), i1, b)); }
public override void Init(Pt sz) { for (int y = 0; y < sz.Y - 6; y += 6) { for (int x = 0; x < sz.X - 4; x += 4) { SetCell(new Pt(x, y + 2), Out); SetCell(new Pt(x + 2, y + 1), Out); SetCell(new Pt(x + 2, y + 5), Out); SetCell(new Pt(x, y + 4), Out); } } }
public override bool Equals(object obj) { if (obj == null) { return(false); } if (!(obj is Pt)) { return(false); } Pt pt = (Pt)obj; return(pt.X == X && pt.Y == Y); }
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); } } }
public void SetWall(Pt pt0, Pt pt1, bool b) { Pt[] n = Neighbours(pt0); int i = IndexOf(n, pt1); if (i == -1) { return; } if (pt0.CompareTo(pt1) < 0) { SetWall(pt1, pt0, b); return; } SetWall(pt0, SetBit(GetWall(pt0), i, b)); }
private void GridControl_MouseMove(object sender, MouseEventArgs e) { if (grid != null) { PickContext pc = new PickContext(grid); Pt loc = pc.Pt(e.Location); if (grid.GetCell(loc) == Grid.In) { cursor = loc; Invalidate(); } else if (cursor.HasValue) { cursor = null; Invalidate(); } } }
public bool GetWall(Pt pt0, Pt pt1) { Pt[] n = Neighbours(pt0); int i = IndexOf(n, pt1); if (i == -1) { return(false); } #if WALL_SINGLE //if (i * 2 >= n.Length) if (pt0.CompareTo(pt1) < 0) { return(GetWall(pt1, pt0)); } #endif return(GetBit(GetWall(pt0), i)); }
public void DrawWalls(PaintContext pc, Pen pe) { foreach (KeyValuePair <Pt, int> kvp in _walls) { Pt pt0 = kvp.Key; int w = kvp.Value; Pt[] vs = Vertices(pt0); Pt[] ns = Neighbours(pt0); for (int i = 0; i < vs.Length; ++i) { Pt pt1 = ns[i]; //if (pt0.CompareTo(pt1) >= 0) if (GetBit(w, i)) { Pt v0 = vs[i]; Pt v1 = vs[(i + 1) % vs.Length]; pc.Graphics.DrawLine(pe, pc.Point(v0), pc.Point(v1)); } } } }
void RecursiveDivision(List <Pt> pts) { if (pts.Count < 2) { return; } int y0, y1; int axis = ChooseAxis(out y0, out y1, pts); int pivot = RoundDistance(axis, (y0 + y1) / 2); List <Pt> l0 = new List <Pt>(); List <Pt> l1 = new List <Pt>(); Func <Pt, int> f = Axes[axis]; foreach (Pt p in pts) { if (f(p) < pivot) { l0.Add(p); } else { l1.Add(p); } } RecursiveDivision(l0); RecursiveDivision(l1); while (true) { Pt p = RandomOfList(l0); foreach (Pt n in Neighbours(p)) { if (l1.Contains(n)) { SetWall(p, n, false); return; } } l0.Remove(p); } }
public Pt Pt(Point p) { Pt loop = Grid.DefPt(p); bool changed = true; while (changed) { changed = false; int d = Distance2(Grid.DefPoint(loop), p); foreach (Pt n in Grid.Neighbours(loop)) { int d1 = Distance2(Grid.DefPoint(n), p); if (d1 < d) { changed = true; d = d1; loop = n; } } } return(loop); }
public void Prims() { // All cells are out to begin with AllWalls(); // Pick a cell to be in SetInWithFrontier(RandomOf(Select(Locs, Out))); while (true) { // Choose a frontier cell Pt[] pts = Select(Locs, Frontier); if (pts.Length == 0) { return; } Pt pt0 = RandomOf(pts); // Choose a neighbour that is in Pt pt1 = RandomOf(Select(Neighbours(pt0), In)); // Break down the wall between them SetWall(pt0, pt1, false); // The frontier cell becomes in SetInWithFrontier(pt0); } }
public override Pt[] Vertices(Pt pt) { return(pt.Vertices4); }
public static Pt Midway(Pt pt0, Pt pt1) { return(new Pt((pt0.X + pt1.X) / 2, (pt0.Y + pt1.Y) / 2)); }
public Point Point(Pt p) { return(Grid.DefPoint(p)); }
public abstract void Init(Pt sz);
public abstract Pt[] Vertices(Pt pt);
public override Pt[] Neighbours(Pt pt) { return(pt.Neighbours4); }
public abstract Point DefPoint(Pt p);
public override Point DefPoint(Pt p) { return(new Point(p.X * 5, p.Y * 5)); }