数据结构_不相交集合_绘制迷宫

本文介绍了如何使用C#编程语言实现迷宫的绘制及基于并集查找算法的迷宫破解程序,包括迷宫的房间格数设定、房间大小、起点位置等参数,并通过并集查找算法生成不相交路径,最终展示迷宫图像并保存为.bmp文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//绘制迷宫
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Maze
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Size form_size=new Size(700,700);
            this.Size = form_size;
            this.MinimumSize = form_size;
            this.MaximumSize = form_size;
        }

        //迷宫房间格数
        //
        int m = 20, n = 20;
        //迷宫房间大小
        //
        int size = 10;
        //迷宫起点距离窗口左上角距离d*size
        //
        int d = 10;
        //窗口尺寸
        //
        int width = 700;
        int height = 700;

        private void Form1_Load(object sender, EventArgs e)
        {
            Paint_Maze();
        }

        public void Paint_Maze()
        {
            Bitmap image=new Bitmap(width,height);
            Graphics g = Graphics.FromImage(image);
            
            //渲染背景
            //
            g.FillRectangle(new SolidBrush(Color.White), 0, 0, width, height);
            
            //绘制迷宫房间
            //
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    g.DrawRectangle(new Pen(new SolidBrush(Color.Black),1), new Rectangle((i + d) * size, (j + d) * size, size, size));
                }
            }

            //绘制入口、出口
            //
            g.DrawLine(new Pen(new SolidBrush(Color.White), 1), new Point(d * size, d * size), new Point((d + 1) * size-1, d * size));    //入口横墙
            g.DrawLine(new Pen(new SolidBrush(Color.White), 1), new Point(d * size, d * size), new Point(d * size, (d + 1) * size-1));    //入口竖墙
            g.DrawLine(new Pen(new SolidBrush(Color.White), 1), new Point(((int)((m * n - 1) % n) + d) * size+1, ((int)((m * n - 1) / n) + 1 + d) * size), new Point(((int)((m * n - 1) % n) + 1 + d) * size, ((int)((m * n - 1) / n) + 1 + d) * size));    //出口横墙
            g.DrawLine(new Pen(new SolidBrush(Color.White), 1), new Point(((int)((m * n - 1) % n) + 1 + d) * size, ((int)((m * n - 1) / n) + d) * size+1), new Point(((int)((m * n - 1) % n) + 1 + d) * size, ((int)((m * n - 1) / n) + 1 + d) * size));    //出口竖墙

            //不相交集
            //
            ADT adt = new ADT();
            adt.InitSet(m * n);
            Random random = new Random();
            while (adt.Find(0) != adt.Find(m * n - 1))
            {
                //随机产生一个房间号
                //
                int room_a = random.Next(m * n);
                List<int> list=new List<int>();
                //检查房间a相邻四间房子a-n(上)、a+n(下)、a-1(左)、a+1(右)是否存在
                //
                if (room_a - n >= 0)
                {
                    list.Add(room_a - n);
                }
                if (room_a + n < m * n)
                {
                    list.Add(room_a + n);
                }
                if (room_a - 1 >= ((int)(room_a / n)) * n)
                {
                    list.Add(room_a - 1);
                }
                if (room_a + 1 < ((int)(room_a / n) + 1) * n)
                {
                    list.Add(room_a + 1);
                }
                //随机产生一个相邻的房间
                //
                int index = random.Next(list.Count);
                int room_b = list[index];
                //检查房间是否连通
                //
                if (adt.Find(room_a) == adt.Find(room_b))
                    continue;
                else
                {
                    int root_a = adt.Find(room_a);
                    int root_b = adt.Find(room_b);
                    //记录哪个房间序号小,靠近入口
                    //
                    int room_min = Math.Min(room_a, room_b);
                    //定义即将拆掉的墙的坐标
                    //
                    int x1, x2, y1, y2;
                    //相差1,拆竖墙;否则拆横墙
                    //
                    if (Math.Abs(room_a - room_b) == 1)
                    {
                        //拆竖墙
                        if (room_a == room_min)     //room_a在room_b前面
                        {
                            x1 = ((int)(room_a % n) + 1+d) * size;
                            y1 = ((int)(room_a / n) + d) * size + 1;
                            x2 = x1;
                            y2 = ((int)(room_a / n) + 1 + d) * size - 1;
                        }
                        else
                        {
                            x1 = ((int)(room_b % n) + 1+d) * size;
                            y1 = ((int)(room_b / n) + d) * size + 1;
                            x2 = x1;
                            y2 = ((int)(room_b / n) + 1 + d) * size - 1;
                        }
                    }
                    else    //拆横墙
                    {
                        if (room_a == room_min)     //room_a在room_b上面
                        {
                            x1 = ((int)(room_a % n) + d) * size + 1;
                            y1 = ((int)(room_a / n)+1+d) * size;
                            x2 = ((int)(room_a % n) + 1 + d) * size - 1;
                            y2 = y1;
                        }
                        else
                        {
                            x1 = ((int)(room_b % n)+d) * size+1;
                            y1 = ((int)(room_b / n) + 1+d) * size;
                            x2 = ((int)(room_b % n) +1+ d) * size - 1;
                            y2 = y1;
                        }
                    }

                    //将room_a和room_b连通
                    //
                    adt.Union(root_a, root_b);
                    g.DrawLine(new Pen(new SolidBrush(Color.White), 1), new Point(x1, y1), new Point(x2, y2));
                }

            }

            //显示图像
            //
            pictureBox1.Image = image;
            image.Save("maze.bmp");
        }
    }
}
//不相交集合类,合并按秩合并
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Maze
{
    class ADT
    {
        //parent list
        //
        private static int[] parent;
        private static int[] rank;


        //Initialize
        //
        public void InitSet(int numElements)
        {
            parent = new int[numElements];
            rank = new int[numElements];
            for (int i = 0; i < numElements; i++)
            {
                parent[i] = -1;
                rank[i] = 1;
            }
        }
        
        //Find
        //
        public int Find(int num)
        {
            int temp;
            temp = num;
            while (parent[temp] != -1)
            {
                temp = parent[temp];
            }
            return temp;
        }


        //Union
        //
        public void Union(int root1, int root2)
        {
            if (rank[root1] < rank[root2])
            {
                parent[root1] = root2;
            }
            else
            {
                if (rank[root1] == rank[root1])
                {
                    rank[root1]++;
                }
                parent[root2] = root1;
            }
        }
    }
}

写完绘制迷宫程序,该填写破解迷宫程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值