计算机软件技术实习项目三——迷宫游戏(代码实现)

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;
    }}}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值