Beispiel #1
0
        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);
                    }
                }
            }
        }
Beispiel #2
0
        public int GetCell(Pt pt)
        {
            int ret = 0;

            _cells.TryGetValue(pt, out ret);
            return(ret);
        }
Beispiel #3
0
        int GetWall(Pt pt)
        {
            int ret = 0;

            _walls.TryGetValue(pt, out ret);
            return(ret);
        }
Beispiel #4
0
 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);
 }
Beispiel #5
0
 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;
         }
     }
 }
Beispiel #6
0
        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);
                }
            }
        }
Beispiel #7
0
 public int CompareTo(Pt p)
 {
     if (X != p.X)
     {
         return(X - p.X);
     }
     return(Y - p.Y);
 }
Beispiel #8
0
        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();
            }
        }
Beispiel #9
0
 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);
         }
     }
 }
Beispiel #10
0
 void SetInWithFrontier(Pt c)
 {
     SetCell(c, In);
     foreach (Pt n in Neighbours(c))
     {
         if (GetCell(n) == Out)
         {
             SetCell(n, Frontier);
         }
     }
 }
Beispiel #11
0
        public void Generate(Pt sz)
        {
            Clear();
            Init(sz);
            origin = Locs.First();
            MethodInfo m = GetMethod(Algorithm);

            if (m != null)
            {
                m.Invoke(this, new object[0]);
            }
        }
Beispiel #12
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));
        }
Beispiel #13
0
 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);
         }
     }
 }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
                }
            }
        }
Beispiel #16
0
        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));
        }
Beispiel #17
0
 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();
         }
     }
 }
Beispiel #18
0
        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));
        }
Beispiel #19
0
 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));
             }
         }
     }
 }
Beispiel #20
0
        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);
            }
        }
Beispiel #21
0
        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);
        }
Beispiel #22
0
 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);
     }
 }
Beispiel #23
0
 public override Pt[] Vertices(Pt pt)
 {
     return(pt.Vertices4);
 }
Beispiel #24
0
 public static Pt Midway(Pt pt0, Pt pt1)
 {
     return(new Pt((pt0.X + pt1.X) / 2, (pt0.Y + pt1.Y) / 2));
 }
Beispiel #25
0
 public Point Point(Pt p)
 {
     return(Grid.DefPoint(p));
 }
Beispiel #26
0
 public abstract void Init(Pt sz);
Beispiel #27
0
 public abstract Pt[] Vertices(Pt pt);
Beispiel #28
0
 public override Pt[] Neighbours(Pt pt)
 {
     return(pt.Neighbours4);
 }
Beispiel #29
0
 public abstract Point DefPoint(Pt p);
Beispiel #30
0
 public override Point DefPoint(Pt p)
 {
     return(new Point(p.X * 5, p.Y * 5));
 }