widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include"maze.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void paintEvent(QPaintEvent *event);
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::Widget *ui;
maze m;
};
#endif // WIDGET_H
maze.h
#ifndef MAZE_H
#define MAZE_H
#include <QWidget>
#include<QPainter>
#include <QKeyEvent>
#include <QEvent>
#include <QTime>
#include <QDebug>
#include <QStack>
#include <QMessagebox>
#include <QProcess>
#include<QPushButton>
struct Point {
int row;
int col;
};
//方块大小
#define xs 20
#define ys 20
//行列
#define H 29
#define L 29
class maze : public QWidget
{
Q_OBJECT
public:
explicit maze(QWidget *parent = nullptr);
void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *event);
QPushButton *bt2;
QPushButton *bt3;
QPushButton *bt4;
signals:
public slots:
void start();
void findpath();
void minpath();
private:
int x=xs*2,y=ys*2; //起点位置
int row=1,col=1; //当前位置
int g=0;
public:
QPainter painter;
QPen pen;
QStack<Point> stack;
void formaze();
bool ghyou(int i,int j);
bool ghzuo(int i,int j);
bool ghsha(int i,int j);
bool ghxia(int i,int j);
};
#endif // MAZE_H
widget.cpp
#include "widget.h"
#include "./ui_widget.h"
#include <QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->resize(800,600);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
this->hide();
m.show();
}
void Widget::on_pushButton_2_clicked()
{
this->close();
}
void Widget::paintEvent(QPaintEvent *event){
QPainter painter(this);
QPixmap p;
p.load("D:/VC++/qt document/NOWD$U{[Q`U)}]%9B35QKJJ(1).jpg");
painter.drawPixmap(0,0,800,600,p);
}
maze.cpp
#include "maze.h"
#include<iostream>
#include<QList>
#include <stack>
using namespace std;
//1代表墙,0代表类似树的节点
int MAP[H][L];
int isFind[H+2][L+2];
int ar[H][L];
QStack<Point> aopen;
QStack<Point> op;
maze::maze(QWidget *parent)
: QWidget{parent}
{
this->resize(800,600);
bt2=new QPushButton(this);
bt2->setText("生成迷宫");
bt2->resize(100,50);
bt2->move(650,150);
connect(bt2,SIGNAL(clicked()),this,SLOT(start()));
bt3=new QPushButton(this);
bt3->setText("生成路径");
bt3->resize(100,50);
bt3->move(650,350);
connect(bt3,SIGNAL(clicked()),this,SLOT(findpath()));
bt4=new QPushButton(this);
bt4->setText("退出游戏");
bt4->resize(100,50);
bt4->move(650,250);
connect(bt4,SIGNAL(clicked()),this,SLOT(close()));
start();
}
void maze::start()
{
row=1;
col=1;
//初始化
for (int i=0;i<H;i++)
{
for(int j=0;j<L;j++)
{
if(i%2==1&&j%2==1)
{
MAP[i][j]=0;
continue;
}
MAP[i][j]=1;
}
}
//初始化辅助数组
for (int i=0;i<H+2;i++)
{
for(int j=0;j<L+2;j++)
{
isFind[i][j]=1;
}
}
for (int i=0;i<H;i++)
{
for(int j=0;j<L;j++)
{
isFind[i+1][j+1]=MAP[i][j];
}
}
formaze();
update();
}
void maze::findpath()
{
minpath();
update();
}
void maze::paintEvent(QPaintEvent *event){
painter.begin(this);
//设置间距
pen.setWidth(xs);
for(int i=0;i<H;i++)
{
for(int j=0;j<L;j++)
{
if(MAP[i][j]==1)
{
pen.setColor(Qt::black);
painter.setPen(pen);
painter.drawPoint((j+1)*xs,(i+1)*ys);
}
//类似节点
if(MAP[i][j]==0)
{
pen.setColor(Qt::white);
painter.setPen(pen);
painter.drawPoint((j+1)*xs,(i+1)*ys);
}
}
}
//画自动走的路径
while(!op.empty())
{
Point temp = op.top();
pen.setColor(Qt::green);
painter.setPen(pen);
painter.drawPoint((temp.col+1)*xs,(temp.row+1)*ys);
op.pop();
}
while(!aopen.empty())
{
Point temp = aopen.top();
pen.setColor(Qt::gray);
painter.setPen(pen);
painter.drawPoint((temp.col+1)*xs,(temp.row+1)*ys);
aopen.pop();
}
pen.setColor(Qt::red);
painter.setPen(pen);
painter.drawPoint((col+1)*xs,(row+1)*ys);
pen.setColor(Qt::yellow);
painter.setPen(pen);
painter.drawPoint((H-1)*xs,(L-1)*ys);
painter.end();
}
void maze::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_W:
if(row*ys>0&&MAP[row-1][col]==0)
{
row--;
}
break;
case Qt::Key_S:
if((row+2)*ys<=ys*H&&MAP[row+1][col]==0)
{
row++;
}
break;
case Qt::Key_A:
if(col*xs>0&&MAP[row][col-1]==0)
{
col--;
}
break;
case Qt::Key_D://x=(col+1)*xsize
if((col+2)*xs<=ys*L&&MAP[row][col+1]==0)
{
col++;
}
break;
default:
break;
}
update();
//走到终点
if(row==H-2&&col==L-2)
{
//创建 QMessageBox 类对象
QMessageBox MyBox(QMessageBox::Question,"提示","你已走出迷宫",QMessageBox::Yes|QMessageBox::No);
//使 MyBox 对话框显示
int rec=MyBox.exec();
if (rec==QMessageBox::Yes) {
this->close();
}
else if (rec==QMessageBox::No) {
this->close();
}
}
}
void maze::formaze()
{
Point curP = { 2,2 };//辅组地图上的起始点
QStack<Point> m;
m.push(curP);
int direction = 0;
while (1) {
//结束循环条件:遍历完了
int n = 0; //n表示有多少个路
for (int i = 0; i < H+2; i++) {
for (int j = 0; j < L+2; j++) {
if (isFind[i][j] == 0)n++; //未被遍历的
}
}
if (n == 0)break;
direction = rand()%4;
if (isFind[curP.row - 2][curP.col] == 1 && isFind[curP.row][curP.col - 2] == 1 &&
isFind[curP.row + 2][curP.col] == 1 && isFind[curP.row][curP.col + 2] == 1)
{
if(!m.empty())m.pop();
if(m.empty()){
qDebug()<<"生成失败";
}
curP = m.top(); //回溯
}
if (direction == 0 && isFind[curP.row - 2][curP.col] == 0) { //左边
MAP[curP.row - 1 - 1][curP.col - 1] = 0;
isFind[curP.row - 2][curP.col] = 1;//记录走过
curP.row -= 2;
m.push(curP);
}
else if (direction == 1 && isFind[curP.row][curP.col - 2] == 0) {//shang
MAP[curP.row - 1][curP.col - 1 - 1] = 0;
isFind[curP.row][curP.col - 2] = 1;
curP.col -= 2;
m.push(curP);
}
else if (direction == 2 && isFind[curP.row + 2][curP.col] == 0) {//you
MAP[curP.row + 1 - 1][curP.col - 1] = 0;
isFind[curP.row + 2][curP.col] = 1;
curP.row += 2;
m.push(curP);
}
else if (direction == 3 && isFind[curP.row][curP.col + 2] == 0) {//xia
MAP[curP.row - 1][curP.col + 1 - 1] = 0;
isFind[curP.row][curP.col + 2] = 1;
curP.col += 2;
m.push(curP);
}
}
}
void maze::minpath()
{
for (int i=0;i<H;i++)
{
for(int j=0;j<L;j++)
{
ar[i][j]=0;
}
}
Point beginPoint = { 1,1};//起点
Point endPoint = { H-2,L-2 };//终点
aopen.push(beginPoint); //栈顶为当前位置
Point currentPoint = beginPoint;//当前走到的位置
ar[currentPoint.row][currentPoint.col] = 1;
while(1){
if (MAP[currentPoint.row + 1][currentPoint.col] == 0 &&
ar[currentPoint.row + 1][currentPoint.col] == 0&&
ghyou(currentPoint.row,currentPoint.col))
{
ar[currentPoint.row + 1][currentPoint.col] = 1;//走过标注1
currentPoint.row = currentPoint.row + 1;//当前位置改变
aopen.push(currentPoint);
qDebug()<<"0";
}
if (MAP[currentPoint.row][currentPoint.col+1] == 0 &&
ar[currentPoint.row][currentPoint.col+1] == 0&&
ghxia(currentPoint.row,currentPoint.col))//可以向右走的条件
{
ar[currentPoint.row][currentPoint.col + 1] = 1;
currentPoint.col = currentPoint.col + 1;
aopen.push(currentPoint);
}
//上
if (MAP[currentPoint.row - 1][currentPoint.col] == 0 &&
ar[currentPoint.row - 1][currentPoint.col] == 0&&
ghzuo(currentPoint.row,currentPoint.col))//可以向上走的条件
{
ar[currentPoint.row - 1][currentPoint.col] = 1;
currentPoint.row = currentPoint.row - 1;
aopen.push(currentPoint);
}
//左
if (MAP[currentPoint.row][currentPoint.col-1] == 0 &&
ar[currentPoint.row][currentPoint.col-1] == 0&&
ghsha(currentPoint.row,currentPoint.col))//可以向左走的条件
{
ar[currentPoint.row][currentPoint.col - 1] = 1;
currentPoint.col = currentPoint.col - 1;
aopen.push(currentPoint);
}
else//即上下左右都无法走
{
aopen.pop();
currentPoint = aopen.top();
}
if (currentPoint.row == endPoint.row && currentPoint.col == endPoint.col)
{
qDebug() << "找到终点!路径回退:" ;
break;
}
if (aopen.empty())
{
qDebug() << "找不到路!" ;
break;
}
}
}
bool maze::ghyou(int i,int j){
int ghcompare[4]={0,0,0,0};
if(MAP[i+1][j]==0 && ar[i+1][j]==0)//右
ghcompare[0]= H-2-(i+1)+L-2 -j+g;
qDebug()<<ghcompare[0];
if(MAP[i-1][j]==0 && ar[i-1][j]==0)//左
ghcompare[1]= H-2-(i-1)+L-2 -j+g;
qDebug()<<ghcompare[1];
if(MAP[i][j+1]==0 && ar[i][j+1]==0)//下
ghcompare[2]= H-2-i+L-2 -(j+1)+g;
qDebug()<<ghcompare[2];
if(MAP[i][j-1]==0 && ar[i][j-1]==0)//上
ghcompare[3]= H-2-i+L-2 -(j-1)+g;
qDebug()<<ghcompare[3];
int cout=0;
if(ghcompare[0]==0)return false;
else{
for(int a=1;a<4;a++){
if(ghcompare[a]!=0){
if(ghcompare[a]<=ghcompare[0]){
cout++;
}
}
}
if(cout==0) return true;
else return false;
}}
bool maze::ghzuo(int i,int j){
int ghcompare[4]={0,0,0,0};
if(MAP[i+1][j]==0 && ar[i+1][j]==0)//右
ghcompare[1]= H-2-(i+1)+L-2 -j+g;
if(MAP[i-1][j]==0 && ar[i-1][j]==0)//左
ghcompare[0]= H-2-(i-1)+L-2 -j+g;
if(MAP[i][j+1]==0 && ar[i][j+1]==0)//下
ghcompare[2]= H-2-i+L-2 -(j+1)+g;
if(MAP[i][j-1]==0 && ar[i][j-1]==0)//上
ghcompare[3]= H-2-i+L-2 -(j-1)+g;
int cout=0;
if(ghcompare[1]==0&&ghcompare[2]==0&&ghcompare[3]==0)return true;
else{
if(ghcompare[0]==0)return false;
else{
for(int a=1;a<4;a++){
if(ghcompare[a]!=0){
if(ghcompare[a]<=ghcompare[0]){
cout++;
}
}
}
if(cout==0) return true;
else return false;
}}}
bool maze::ghxia(int i,int j){
int ghcompare[4]={0,0,0,0};
if(MAP[i+1][j]==0 && ar[i+1][j]==0)//右
ghcompare[2]= H-2-(i+1)+L-2 -j+g;
if(MAP[i-1][j]==0 && ar[i-1][j]==0)//左
ghcompare[1]= H-2-(i-1)+L-2 -j+g;
if(MAP[i][j+1]==0 && ar[i][j+1]==0)//下
ghcompare[0]= H-2-i+L-2 -(j+1)+g;
if(MAP[i][j-1]==0 && ar[i][j-1]==0)//上
ghcompare[3]= H-2-i+L-2 -(j-1)+g;
int cout=0;
if(ghcompare[1]==0&&ghcompare[2]==0&&ghcompare[3]==0)return true;
else{
if(ghcompare[0]==0)return false;
else{
for(int a=1;a<4;a++){
if(ghcompare[a]!=0){
if(ghcompare[a]<ghcompare[0]){
cout++;
}
}
}
if(cout==0) return true;
else return false;
}}}
bool maze::ghsha(int i,int j){
int ghcompare[4]={0,0,0,0};
if(MAP[i+1][j]==0 && ar[i+1][j]==0)//右
ghcompare[3]= H-2-(i+1)+L-2 -j+g;
if(MAP[i-1][j]==0 && ar[i-1][j]==0)//左
ghcompare[1]= H-2-(i-1)+L-2 -j+g;
if(MAP[i][j+1]==0 && ar[i][j+1]==0)//下
ghcompare[2]= H-2-i+L-2 -(j+1)+g;
if(MAP[i][j-1]==0 && ar[i][j-1]==0)//上
ghcompare[0]= H-2-i+L-2 -(j-1)+g;
int cout=0;
if(ghcompare[1]==0&&ghcompare[2]==0&&ghcompare[3]==0)return true;
else{
if(ghcompare[0]==0)return false;
else{
for(int a=1;a<4;a++){
if(ghcompare[a]!=0){
if(ghcompare[a]<ghcompare[0]){
cout++;
}
}
}
if(cout==0) return true;
else return false;
}}}