IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 迷宫自动生成和路径求解 -> 正文阅读

[人工智能]迷宫自动生成和路径求解

宁波大学数据结构project3迷宫maze

基于MFC、opencv、VS2017的实现迷宫自动生成和路径求解,写的比较烂。

问题分析:

1.如何生成迷宫:随机生成、prim算法生成

2.如何求解迷宫:dfs、bfs等遍历方法

3.图形化界面联动:opencv图片刷新、时间控制、MFC等

必要的资源:VS2017,opencv-3.4.1

第一步、看一下文件的布置:

创建好工程后记得在下图目录下新建image这个文件夹

然后将这几张图片放入image下

如下图所示:

第二步、由于本人直接在project3Dlg.cpp里面写了全部,其他文件没有动过,可能需要将里面的图片路径改掉,所以直接上代码:

?

// project3Dlg.cpp: 实现文件
//

#include "stdafx.h"
#include "project3.h"
#include "project3Dlg.h"
#include "afxdialogex.h"
#include "resource.h"

#include <iostream>
#include<cstdlib>
#include<fstream>
#include<ctime>
#include<stdlib.h>
#include<stack>

#include<opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;
#ifdef _DEBUG
#define new DEBUG_NEW
#define m 50 ?//row
#define n 50
#define down1 1
#define right1 2
#define left1 4
#define up1 8
#define WALL1 -1
#define NOTHING1 2
#endif

void MatToCImage(Mat &mat, CImage &cImage);
int maze_size = m + 2;
int maze[52][52]; ?// size = m + 2
int src = 5;
int dst = 6;
int border = 0;
int h0;
int w0;
int h1;
int w1;
int working_count = 0;
stack<int> StackIntx;
stack<int> StackInty;

// Mat border;
Mat background;
Mat border_img;
Mat mmc;
Mat xg;

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

struct block {
?? ?int row, column, direction;
?? ?block(int _row, int _column, int _direction) {
?? ??? ?row = _row;
?? ??? ?column = _column;
?? ??? ?direction = _direction;
?? ?}
};
struct point {
?? ?int x;
?? ?int y;
}start, end;

vector<block> myblock;
int x_num = 1, y_num = 1;//矿工位置
int G[100][100];

void init() {
?? ?//将地图全部置为墙
?? ?memset(G, WALL1, sizeof(G));
?? ?//定义起始点
?? ?G[1][1] = NOTHING1;
?? ?start.x = start.y = 1;
}
void FindBlock() {
?? ?//找出与当前位置相邻的墙
?? ?if (x_num + 1 <= m && G[x_num + 1][y_num] == WALL1) {//down
?? ??? ?myblock.push_back(block(x_num + 1, y_num, down1));
?? ?}
?? ?if (y_num + 1 <= n && G[x_num][y_num + 1] == WALL1) {//right
?? ??? ?myblock.push_back(block(x_num, y_num + 1, right1));
?? ?}
?? ?if (x_num - 1 >= 1 && G[x_num - 1][y_num] == WALL1) {//up
?? ??? ?myblock.push_back(block(x_num - 1, y_num, up1));
?? ?}
?? ?if (y_num - 1 >= 1 && G[x_num][y_num - 1] == WALL1) {//left
?? ??? ?myblock.push_back(block(x_num, y_num - 1, left1));
?? ?}
}


class CAboutDlg : public CDialogEx
{
public:
?? ?CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
?? ?enum { IDD = IDD_ABOUTBOX };
#endif

?? ?protected:
?? ?virtual void DoDataExchange(CDataExchange* pDX); ? ?// DDX/DDV 支持

// 实现
protected:
?? ?DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
?? ?CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// Cproject3Dlg 对话框

Cproject3Dlg::Cproject3Dlg(CWnd* pParent /*=nullptr*/)
?? ?: CDialogEx(IDD_PROJECT3_DIALOG, pParent)
{
?? ?m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void Cproject3Dlg::DoDataExchange(CDataExchange* pDX)
{
?? ?CDialogEx::DoDataExchange(pDX);
?? ?DDX_Control(pDX, IDC_PICTURE_STATIC, m_Picture);
}

BEGIN_MESSAGE_MAP(Cproject3Dlg, CDialogEx)
?? ?ON_WM_SYSCOMMAND()
?? ?ON_WM_PAINT()
?? ?ON_WM_QUERYDRAGICON()
?? ?ON_BN_CLICKED(IDC_BUTTON2, &Cproject3Dlg::OnBnClickedButton2)
?? ?ON_BN_CLICKED(IDC_BUTTON1, &Cproject3Dlg::OnBnClickedButton1)
?? ?ON_BN_CLICKED(IDC_BUTTON3, &Cproject3Dlg::OnBnClickedButton3)
END_MESSAGE_MAP()


// Cproject3Dlg 消息处理程序

BOOL Cproject3Dlg::OnInitDialog()
{
?? ?CDialogEx::OnInitDialog();

?? ?// 将“关于...”菜单项添加到系统菜单中。

?? ?// IDM_ABOUTBOX 必须在系统命令范围内。
?? ?ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
?? ?ASSERT(IDM_ABOUTBOX < 0xF000);

?? ?CMenu* pSysMenu = GetSystemMenu(FALSE);
?? ?if (pSysMenu != nullptr)
?? ?{
?? ??? ?BOOL bNameValid;
?? ??? ?CString strAboutMenu;
?? ??? ?bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
?? ??? ?ASSERT(bNameValid);
?? ??? ?if (!strAboutMenu.IsEmpty())
?? ??? ?{
?? ??? ??? ?pSysMenu->AppendMenu(MF_SEPARATOR);
?? ??? ??? ?pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
?? ??? ?}
?? ?}

?? ?// 设置此对话框的图标。 ?当应用程序主窗口不是对话框时,框架将自动
?? ?// ?执行此操作
?? ?SetIcon(m_hIcon, TRUE);?? ??? ??? ?// 设置大图标
?? ?SetIcon(m_hIcon, FALSE);?? ??? ?// 设置小图标

?? ?// TODO: 在此添加额外的初始化代码

?? ?// string border_path = "../images/border.png";
?? ?string background_path = "../images/background.png";
?? ?background = imread(background_path);
?? ?SetDlgItemText(IDC_EDIT1, _T(""));

?? ?//显示图像
?? ?CImage src2;
?? ?CRect rect1, pic_rectl;
?? ?int height1, width1;
?? ?int cxl, cyl;

?? ?GetDlgItem(IDC_PICTURE_STATIC)->GetClientRect(&pic_rectl);
?? ?width1 = pic_rectl.right;
?? ?height1 = pic_rectl.bottom;
?? ?resize(background, background, Size(height1, width1));
?? ?MatToCImage(background, src2);//OpenCV中Mat对象转MFC的CImage类的函数(见我另一篇博文)
?? ?//获取图片的宽 高度
?? ?cxl = src2.GetWidth();
?? ?cyl = src2.GetHeight();
?? ?//获取Picture Control控件的大小
?? ?GetDlgItem(IDC_PICTURE_STATIC)->GetWindowRect(&rect1);
?? ?//将客户区选中到控件表示的矩形区域内 ?
?? ?ScreenToClient(&rect1);
?? ?//窗口移动到控件表示的区域 ?
?? ?GetDlgItem(IDC_PICTURE_STATIC)->MoveWindow(rect1.left, rect1.top, cxl, cyl, TRUE);
?? ?CWnd *pWnd = NULL;
?? ?pWnd = GetDlgItem(IDC_PICTURE_STATIC);//获取控件句柄 ?
?? ?pWnd->GetClientRect(&rect1);//获取句柄指向控件区域的大小 ?
?? ?CDC *pDc = NULL;
?? ?pDc = pWnd->GetDC();//获取picture的DC ?
?? ?src2.Draw(pDc->m_hDC, rect1);//将图片绘制到picture表示的区域内 ?
?? ?ReleaseDC(pDc);

?? ?return TRUE; ?// 除非将焦点设置到控件,否则返回 TRUE
}

void Cproject3Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
?? ?if ((nID & 0xFFF0) == IDM_ABOUTBOX)
?? ?{
?? ??? ?CAboutDlg dlgAbout;
?? ??? ?dlgAbout.DoModal();
?? ?}
?? ?else
?? ?{
?? ??? ?CDialogEx::OnSysCommand(nID, lParam);
?? ?}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
// ?来绘制该图标。 ?对于使用文档/视图模型的 MFC 应用程序,
// ?这将由框架自动完成。

void Cproject3Dlg::OnPaint()
{
?? ?if (IsIconic())
?? ?{
?? ??? ?CPaintDC dc(this); // 用于绘制的设备上下文

?? ??? ?SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

?? ??? ?// 使图标在工作区矩形中居中
?? ??? ?int cxIcon = GetSystemMetrics(SM_CXICON);
?? ??? ?int cyIcon = GetSystemMetrics(SM_CYICON);
?? ??? ?CRect rect;
?? ??? ?GetClientRect(&rect);
?? ??? ?int x = (rect.Width() - cxIcon + 1) / 2;
?? ??? ?int y = (rect.Height() - cyIcon + 1) / 2;

?? ??? ?// 绘制图标
?? ??? ?dc.DrawIcon(x, y, m_hIcon);
?? ?}
?? ?else
?? ?{
?? ??? ?CDialogEx::OnPaint();
?? ?}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR Cproject3Dlg::OnQueryDragIcon()
{
?? ?return static_cast<HCURSOR>(m_hIcon);
}


// Mat -> CImage
void MatToCImage(Mat &mat, CImage &cImage)
{
?? ?//create new CImage ?
?? ?int width = mat.cols;
?? ?int height = mat.rows;
?? ?int channels = mat.channels();

?? ?cImage.Destroy(); //clear ?
?? ?cImage.Create(width, height, 8 * channels); //默认图像像素单通道占用1个字节 ?

?? ?//copy values ?
?? ?uchar* ps;
?? ?uchar* pimg = (uchar*)cImage.GetBits(); //A pointer to the bitmap buffer ?
?? ?int step = cImage.GetPitch();

?? ?for (int i = 0; i < height; ++i)
?? ?{
?? ??? ?ps = (mat.ptr<uchar>(i));
?? ??? ?for (int j = 0; j < width; ++j)
?? ??? ?{
?? ??? ??? ?if (channels == 1) //gray ?
?? ??? ??? ?{
?? ??? ??? ??? ?*(pimg + i * step + j) = ps[j];
?? ??? ??? ?}
?? ??? ??? ?else if (channels == 3) //color ?
?? ??? ??? ?{
?? ??? ??? ??? ?for (int k = 0; k < 3; ++k)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?*(pimg + i * step + j * 3 + k) = ps[j * 3 + k];
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}
}

void Cproject3Dlg::OnBnClickedButton2()
{
?? ?// TODO: 在此添加控件通知处理程序代码
?? ?UINT i;
?? ?i = MessageBox(TEXT("请确认是否要退出程序"), TEXT("温馨提示"), MB_YESNO | MB_ICONQUESTION);
?? ?if (i == IDNO)
?? ?{
?? ??? ?return;
?? ?}
?? ?CDialogEx::OnOK();
}


void Cproject3Dlg::OnBnClickedButton1()
{
?? ?// TODO: 在此添加控件通知处理程序代码
?? ?// 运行并输出结果
?? ?bool tmp_flag = true;
?? ?working_count = 0;
?? ?int Ip[2];
?? ?int time1 = 0;
?? ?int Size_height = background.rows;
?? ?int Size_width = background.cols;

?? ?CImage src2;
?? ?CRect rect1;
?? ?// int height1, width1;
?? ?int cxl, cyl;
?? ?Ip[0] = h0;
?? ?Ip[1] = w0;
?? ?StackIntx.push(Ip[0]);
?? ?StackInty.push(Ip[1]);
?? ?while (true)
?? ?{
?? ??? ?int tmp_Ip[2];
?? ??? ?tmp_Ip[0] = Ip[0];
?? ??? ?tmp_Ip[1] = Ip[1];
?? ??? ?if (time1 % 10000 != 1)
?? ??? ?{
?? ??? ??? ?time1++;
?? ??? ??? ?CString C_time;
?? ??? ??? ?C_time.Format(_T("dead maze after :%d coount"), time1);
?? ??? ??? ?SetDlgItemText(IDC_EDIT1, C_time);
?? ??? ??? ?continue;
?? ??? ?}
?? ??? ?if (working_count > 100000)
?? ??? ?{
?? ??? ??? ?tmp_flag = false;
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?cout << working_count << " " << Ip[0] << ", " << Ip[1] << endl;
?? ??? ?if (maze[Ip[0]][Ip[1]] == dst)
?? ??? ?{
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?if (maze[Ip[0] + 1][Ip[1]] == dst)
?? ??? ?{
?? ??? ??? ?Ip[0] = Ip[0] + 1;
?? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("成功找到"));
?? ??? ??? ?Point Pt1, Pt2;
?? ??? ??? ?Pt1 = Point(tmp_Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), tmp_Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Pt2 = Point(Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Scalar color1 = Scalar(60, 80, 255);
?? ??? ??? ?line(background, Pt1, Pt2, color1, 2);
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?else if (maze[Ip[0]][Ip[1] + 1] == dst)
?? ??? ?{
?? ??? ??? ?Ip[1] = Ip[1] + 1;
?? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("成功找到"));
?? ??? ??? ?Point Pt1, Pt2;
?? ??? ??? ?Pt1 = Point(tmp_Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), tmp_Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Pt2 = Point(Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Scalar color1 = Scalar(60, 80, 255);
?? ??? ??? ?line(background, Pt1, Pt2, color1, 2);
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?else if (maze[Ip[0]][Ip[1] - 1] == dst)
?? ??? ?{
?? ??? ??? ?Ip[1] = Ip[1] - 1;
?? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("成功找到"));
?? ??? ??? ?Point Pt1, Pt2;
?? ??? ??? ?Pt1 = Point(tmp_Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), tmp_Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Pt2 = Point(Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Scalar color1 = Scalar(60, 80, 255);
?? ??? ??? ?line(background, Pt1, Pt2, color1, 2);
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?else if (maze[Ip[0] - 1][Ip[1]] == dst)
?? ??? ?{
?? ??? ??? ?Ip[0] = Ip[0] - 1;
?? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("成功找到"));
?? ??? ??? ?Point Pt1, Pt2;
?? ??? ??? ?Pt1 = Point(tmp_Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), tmp_Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Pt2 = Point(Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Scalar color1 = Scalar(60, 80, 255);
?? ??? ??? ?line(background, Pt1, Pt2, color1, 2);
?? ??? ??? ?break;
?? ??? ?}

?? ??? ?if ((maze[Ip[0] - 1][Ip[1]] != border) && (maze[Ip[0] - 1][Ip[1]] != src))
?? ??? ?{
?? ??? ??? ?Ip[0] = Ip[0] - 1;
?? ??? ??? ?if (maze[Ip[0]][Ip[1]] == dst)
?? ??? ??? ?{
?? ??? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("成功找到"));
?? ??? ??? ??? ?break;
?? ??? ??? ?}

?? ??? ??? ?maze[Ip[0]][Ip[1]] = src;
?? ??? ??? ?working_count++;
?? ??? ?}
?? ??? ?else if ((maze[Ip[0]][Ip[1] + 1] != border) && (maze[Ip[0]][Ip[1] + 1] != src))
?? ??? ?{
?? ??? ??? ?Ip[1] = Ip[1] + 1;
?? ??? ??? ?if (maze[Ip[0]][Ip[1]] == dst)
?? ??? ??? ?{
?? ??? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("成功找到"));
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ??? ?maze[Ip[0]][Ip[1]] = src;
?? ??? ??? ?working_count++;
?? ??? ?}
?? ??? ?else if ((maze[Ip[0] + 1][Ip[1]] != border) && (maze[Ip[0] + 1][Ip[1]] != src))
?? ??? ?{
?? ??? ??? ?Ip[0] = Ip[0] + 1;
?? ??? ??? ?if (maze[Ip[0]][Ip[1]] == dst)
?? ??? ??? ?{
?? ??? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("成功找到"));
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ??? ?maze[Ip[0]][Ip[1]] = src;
?? ??? ??? ?working_count++;
?? ??? ?}
?? ??? ?else if ((maze[Ip[0]][Ip[1] - 1] != border) && (maze[Ip[0]][Ip[1] - 1] != src))
?? ??? ?{
?? ??? ??? ?Ip[1] = Ip[1] - 1;
?? ??? ??? ?if (maze[Ip[0]][Ip[1]] == dst)
?? ??? ??? ?{
?? ??? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("成功找到"));
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ??? ?maze[Ip[0]][Ip[1]] = src;
?? ??? ??? ?working_count++;
?? ??? ?}
?? ??? ?else if (!StackIntx.empty())
?? ??? ?{
?? ??? ??? ?cout << StackIntx.top() << "," << StackInty.top() << endl;
?? ??? ??? ?int tmp_Ip2[2];
?? ??? ??? ?tmp_Ip2[0] = StackIntx.top();
?? ??? ??? ?tmp_Ip2[1] = StackInty.top();
?? ??? ??? ?StackIntx.pop();
?? ??? ??? ?StackInty.pop();
?? ??? ??? ?if (StackIntx.empty())
?? ??? ??? ?{
?? ??? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("找不到!"));
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ??? ?Ip[0] = StackIntx.top();
?? ??? ??? ?Ip[1] = StackInty.top();
?? ??? ??? ?Scalar color2 = Scalar(255, 255, 0);
?? ??? ??? ?Point Pt1, Pt2;
?? ??? ??? ?Pt1 = Point(tmp_Ip2[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), tmp_Ip2[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?Pt2 = Point(Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ??? ?line(background, Pt1, Pt2, color2, 2);
?? ??? ??? ?
?? ??? ??? ?working_count++;
?? ??? ??? ?MatToCImage(background, src2);//OpenCV中Mat对象转MFC的CImage类的函数
?? ??? ??? ?//获取图片的宽 高度
?? ??? ??? ?cxl = src2.GetWidth();
?? ??? ??? ?cyl = src2.GetHeight();
?? ??? ??? ?//获取Picture Control控件的大小
?? ??? ??? ?GetDlgItem(IDC_PICTURE_STATIC)->GetWindowRect(&rect1);
?? ??? ??? ?//将客户区选中到控件表示的矩形区域内
?? ??? ??? ?ScreenToClient(&rect1);
?? ??? ??? ?//窗口移动到控件表示的区域
?? ??? ??? ?GetDlgItem(IDC_PICTURE_STATIC)->MoveWindow(rect1.left, rect1.top, cxl, cyl, TRUE);
?? ??? ??? ?CWnd *pWnd = NULL;
?? ??? ??? ?pWnd = GetDlgItem(IDC_PICTURE_STATIC);//获取控件句柄
?? ??? ??? ?pWnd->GetClientRect(&rect1);//获取句柄指向控件区域的大小
?? ??? ??? ?CDC *pDc = NULL;
?? ??? ??? ?pDc = pWnd->GetDC();//获取picture的DC
?? ??? ??? ?src2.Draw(pDc->m_hDC, rect1);//将图片绘制到picture表示的区域内
?? ??? ??? ?ReleaseDC(pDc);
?? ??? ??? ?continue;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?SetDlgItemText(IDC_EDIT2, _T("找不到!"));
?? ??? ??? ?tmp_flag = false;
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?StackIntx.push(Ip[0]);
?? ??? ?StackInty.push(Ip[1]);
?? ??? ?Point Pt1, Pt2;
?? ??? ?Pt1 = Point(tmp_Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), tmp_Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ?Pt2 = Point(Ip[1] * Size_width / (maze_size + 1) + Size_width / (2 * maze_size + 2), Ip[0] * Size_height / (maze_size + 1) + Size_height / (2 * maze_size + 2));
?? ??? ?Scalar color1 = Scalar(60, 80, 255);
?? ??? ?line(background, Pt1, Pt2, color1, 2);
?? ??? ?/*
?? ??? ?namedWindow("background");
?? ??? ?imshow("background", background);
?? ??? ?waitKey(0);
?? ??? ?destroyAllWindows();
?? ??? ?*/
?? ??? ?
?? ??? ?// rectangle(background, Point(Ip[1] * Size_width / 23, Ip[0] * Size_height / 23), Point((Ip[1] + 1) * Size_width / 23, (Ip[0] + 1)*Size_height / 23), Scalar(0, 0, 255), -1);
?? ??? ?MatToCImage(background, src2);//OpenCV中Mat对象转MFC的CImage类的函数
?? ??? ?//获取图片的宽 高度
?? ??? ?cxl = src2.GetWidth();
?? ??? ?cyl = src2.GetHeight();
?? ??? ?//获取Picture Control控件的大小
?? ??? ?GetDlgItem(IDC_PICTURE_STATIC)->GetWindowRect(&rect1);
?? ??? ?//将客户区选中到控件表示的矩形区域内
?? ??? ?ScreenToClient(&rect1);
?? ??? ?//窗口移动到控件表示的区域
?? ??? ?GetDlgItem(IDC_PICTURE_STATIC)->MoveWindow(rect1.left, rect1.top, cxl, cyl, TRUE);
?? ??? ?CWnd *pWnd = NULL;
?? ??? ?pWnd = GetDlgItem(IDC_PICTURE_STATIC);//获取控件句柄
?? ??? ?pWnd->GetClientRect(&rect1);//获取句柄指向控件区域的大小
?? ??? ?CDC *pDc = NULL;
?? ??? ?pDc = pWnd->GetDC();//获取picture的DC
?? ??? ?src2.Draw(pDc->m_hDC, rect1);//将图片绘制到picture表示的区域内
?? ??? ?ReleaseDC(pDc);
?? ?}
?? ?while (!StackIntx.empty())
?? ?{
?? ??? ?StackIntx.pop();
?? ??? ?StackInty.pop();
?? ?}
?? ?/*
?? ?rectangle(background, Point(w0 * Size_width / 23, h0*Size_height / 23), Point((w0 + 1) * Size_width / 23, (h0 + 1)*Size_height / 23), Scalar(255, 0, 0), -1);
?? ?rectangle(background, Point(w1 * Size_width / 23, h1*Size_height / 23), Point((w1 + 1) * Size_width / 23, (h1 + 1)*Size_height / 23), Scalar(0, 255, 0), -1);

?? ?*/
?? ?MatToCImage(background, src2);//OpenCV中Mat对象转MFC的CImage类的函数
?? ?//获取图片的宽 高度
?? ?cxl = src2.GetWidth();
?? ?cyl = src2.GetHeight();
?? ?//获取Picture Control控件的大小
?? ?GetDlgItem(IDC_PICTURE_STATIC)->GetWindowRect(&rect1);
?? ?//将客户区选中到控件表示的矩形区域内
?? ?ScreenToClient(&rect1);
?? ?//窗口移动到控件表示的区域
?? ?GetDlgItem(IDC_PICTURE_STATIC)->MoveWindow(rect1.left, rect1.top, cxl, cyl, TRUE);
?? ?CWnd *pWnd = NULL;
?? ?pWnd = GetDlgItem(IDC_PICTURE_STATIC);//获取控件句柄
?? ?pWnd->GetClientRect(&rect1);//获取句柄指向控件区域的大小
?? ?CDC *pDc = NULL;
?? ?pDc = pWnd->GetDC();//获取picture的DC
?? ?src2.Draw(pDc->m_hDC, rect1);//将图片绘制到picture表示的区域内
?? ?ReleaseDC(pDc);
?? ?CString C_working_count;
?? ?if (tmp_flag)
?? ?{
?? ??? ?C_working_count.Format(_T("over by :%d count"), working_count);
?? ??? ?SetDlgItemText(IDC_EDIT1, C_working_count);
?? ?}
?? ?else
?? ?{
?? ??? ?C_working_count.Format(_T("dead maze after :%d coount"), working_count);
?? ??? ?SetDlgItemText(IDC_EDIT1, C_working_count);
?? ?}
?? ?
}


void Cproject3Dlg::OnBnClickedButton3()
{
?? ?// TODO: 在此添加控件通知处理程序代码
?? ?// 新生成一张迷宫

?? ?// 普林算法
?? ?init();
?? ?srand((unsigned)time(NULL));//随机数种子
?? ?FindBlock();
?? ?//第一步压入两堵墙(起点右边和起点下面)进入循环
?? ?while (myblock.size()) {
?? ??? ?int BlockSize = myblock.size();
?? ??? ?//随机选择一堵墙(生成0 ~ BlockSize-1之间的随机数,同时也是vector里墙的下标)
?? ??? ?int randnum = rand() % BlockSize;
?? ??? ?block SelectBlock = myblock[randnum];
?? ??? ?x_num = SelectBlock.row;//矿工来到我们“选择的墙”这里
?? ??? ?y_num = SelectBlock.column;
?? ??? ?//根据当前选择的墙的方向进行后续操作
?? ??? ?//此时,起始点 选择的墙 目标块 三块区域在同一直线上
?? ??? ?//我们让矿工从“选择的墙”继续前进到“目标块”
?? ??? ?//矿工有穿墙能力 :)
?? ??? ?switch (SelectBlock.direction) {
?? ??? ?case down1: {
?? ??? ??? ?x_num++;
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?case right1: {
?? ??? ??? ?y_num++;
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?case left1: {
?? ??? ??? ?y_num--;
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?case up1: {
?? ??? ??? ?x_num--;
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?}
?? ??? ?//目标块如果是墙
?? ??? ?if (G[x_num][y_num] == WALL1) {
?? ??? ??? ?//打通墙和目标块
?? ??? ??? ?G[SelectBlock.row][SelectBlock.column] = G[x_num][y_num] = NOTHING1;
?? ??? ??? ?//再次找出与矿工当前位置相邻的墙
?? ??? ??? ?FindBlock();
?? ??? ?}
?? ??? ?else {//如果不是呢?说明我们的矿工挖到了一个空旷的通路上面 休息一下就好了
?? ??? ??? ?//relax
?? ??? ?}
?? ??? ?//删除这堵墙(把用不了的墙删了,对于那些已经施工过了不必再施工了,同时也是确保我们能跳出循环)
?? ??? ?myblock.erase(myblock.begin() + randnum);
?? ?}

?? ?background = imread("../images/background.png");
?? ?border_img = imread("../images/border.png");
?? ?mmc = imread("../images/mmc.png");
?? ?xg = imread("../images/xg.png");

?? ?srand((int)time(0));
?? ?h0 = 1 + rand() % (maze_size - 2);
?? ?w0 = 1 + rand() % (maze_size - 2);
?? ?h1 = 1 + rand() % (maze_size - 2);
?? ?w1 = 1 + rand() % (maze_size - 2);
?? ?if (h0 == h1 && w0 == w1) {
?? ??? ?h0 = 1 + rand() % (maze_size - 2);
?? ??? ?w0 = 1 + rand() % (maze_size - 2);
?? ??? ?h1 = 1 + rand() % (maze_size - 2);
?? ??? ?w1 = 1 + rand() % (maze_size - 2);
?? ?}
?? ?

?? ?CImage src2;
?? ?CRect rect1, pic_rectl;
?? ?int height1, width1;
?? ?int cxl, cyl;
?? ?GetDlgItem(IDC_PICTURE_STATIC)->GetClientRect(&pic_rectl);
?? ?width1 = pic_rectl.right; // 522
?? ?height1 = pic_rectl.bottom; // 490
?? ?resize(border_img, border_img, Size(width1 / (maze_size + 1), height1 / (maze_size + 1)));
?? ?resize(mmc, mmc, Size(width1 / (maze_size + 1), height1 / (maze_size + 1)));
?? ?resize(xg, xg, Size(width1 / (maze_size + 1), height1 / (maze_size + 1)));
?? ?resize(background, background, Size(width1, height1));
?? ?for (int i = 0; i < maze_size; i++)
?? ?{
?? ??? ?maze[0][i] = border;
?? ??? ?maze[i][0] = border;
?? ??? ?maze[maze_size - 1][i] = border;
?? ??? ?maze[i][maze_size - 1] = border;
?? ?}

?? ?for (int i = 1; i < m + 1; i++) {
?? ??? ?for (int j = 1; j < n + 1; j++) {
?? ??? ??? ?maze[i][j] = border;
?? ??? ??? ?if (i == start.x&&j == start.y) {
?? ??? ??? ??? ?continue;
?? ??? ??? ?}
?? ??? ??? ?else if (G[i][j] == NOTHING1) {
?? ??? ??? ??? ?maze[i][j] = 1;
?? ??? ??? ?}
?? ??? ??? ?else {
?? ??? ??? ??? ?maze[i][j] = border;
?? ??? ??? ?}
?? ??? ?}
?? ?}

?? ?/*
?? ?for (int i = 1; i < (maze_size - 1); i++)
?? ?{
?? ??? ?for (int j = 1; j < (maze_size - 1); j++)
?? ??? ?{
?? ??? ??? ?maze[i][j] = rand() % 3;
?? ??? ?}
?? ?}
?? ?*/
?? ?
?? ?
?? ?
?? ?maze[h0][w0] = src;
?? ?maze[h1][w1] = dst;
?? ?
?? ?for (int i = 0; i < maze_size; i++)
?? ?{
?? ??? ?for (int j = 0; j < maze_size; j++)
?? ??? ?{
?? ??? ??? ?if (maze[i][j] == 0)
?? ??? ??? ?{
?? ??? ??? ??? ?// rectangle(background, Point(j * width1 / (maze_size + 1), i*height1 / (maze_size + 1)), Point((j + 1) * width1 / (maze_size + 1), (i + 1)*height1 / (maze_size + 1)), Scalar(0, 0, 0), -1);
?? ??? ??? ??? ?Rect roi;
?? ??? ??? ??? ?roi.x = j * width1 / (maze_size + 1);
?? ??? ??? ??? ?roi.y = i * height1 / (maze_size + 1);
?? ??? ??? ??? ?roi.height = height1 / (maze_size + 1);
?? ??? ??? ??? ?roi.width = width1 / (maze_size + 1);
?? ??? ??? ??? ?border_img.copyTo(background(roi));
?? ??? ??? ??? ?// background(roi) = border_img.clone();
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?// rectangle(background, Point(w0 * width1 / (maze_size + 1), h0*height1 / (maze_size + 1)), Point((w0 + 1) * width1 / (maze_size + 1), (h0 + 1)*height1 / (maze_size + 1)), Scalar(255, 0, 0), -1);
?? ?rectangle(background, Point(w1 * width1 / (maze_size + 1), h1*height1 / (maze_size + 1)), Point((w1 + 1) * width1 / (maze_size + 1), (h1 + 1)*height1 / (maze_size + 1)), Scalar(0, 255, 0), -1);
?? ?Rect myroi;
?? ?myroi.x = w0 * width1 / (maze_size + 1);
?? ?myroi.y = h0 * height1 / (maze_size + 1);
?? ?myroi.height = height1 / (maze_size + 1);
?? ?myroi.width = width1 / (maze_size + 1);
?? ?mmc.copyTo(background(myroi));
?? ?myroi.x = w1 * width1 / (maze_size + 1);
?? ?myroi.y = h1 * height1 / (maze_size + 1);
?? ?xg.copyTo(background(myroi));
?? ?MatToCImage(background, src2);//OpenCV中Mat对象转MFC的CImage类的函数(见我另一篇博文)
?? ?//获取图片的宽 高度
?? ?cxl = src2.GetWidth();
?? ?cyl = src2.GetHeight();
?? ?//获取Picture Control控件的大小
?? ?GetDlgItem(IDC_PICTURE_STATIC)->GetWindowRect(&rect1);
?? ?//将客户区选中到控件表示的矩形区域内
?? ?ScreenToClient(&rect1);
?? ?//窗口移动到控件表示的区域
?? ?GetDlgItem(IDC_PICTURE_STATIC)->MoveWindow(rect1.left, rect1.top, cxl, cyl, TRUE);
?? ?CWnd *pWnd = NULL;
?? ?pWnd = GetDlgItem(IDC_PICTURE_STATIC);//获取控件句柄
?? ?pWnd->GetClientRect(&rect1);//获取句柄指向控件区域的大小
?? ?CDC *pDc = NULL;
?? ?pDc = pWnd->GetDC();//获取picture的DC
?? ?src2.Draw(pDc->m_hDC, rect1);//将图片绘制到picture表示的区域内
?? ?ReleaseDC(pDc);

}


?

第三步、展示效果图

提示:棕色是墙壁,mmc所在地是起点,xg所在地是终点,mmc没有任何先验知识,纯靠遍历。

1.随机生成的迷宫:

明显比较杂乱。。。

对迷宫进行路径求解(红色是最终路径,蓝色是多走的冗余路径):

效果也还行。。。

2.基于prim算法生成的规整的迷宫

对迷宫进行求解(红色最终路线,蓝色冗余路线):

左下角是走的总步数。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-07-07 00:00:15  更:2021-07-07 00:00:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年3日历 -2024/3/29 18:07:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码