迷宫游戏源码

2023-10-30

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "MAZE.h"
#include <QMainWindow>
#include <QWidget>
#include <iostream>
#include <QTime>
#include <QLineEdit>
#include <QPushButton>
#include <QPainter>
#include <QLabel>
#include <QMessageBox>
#include <QDebug>
#include <QKeyEvent>
#include <QPixmap>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void paintEvent(QPaintEvent *);//键盘监听
    void keyPressEvent(QKeyEvent *e);//绘图重写
private:
    MAZE *m;              ///<迷宫地图
    ///< 当前人物在迷宫的位置(X,Y)
    int X = 1;
    int Y = 0;
    bool bfs_fg = false; ///< 最短路径绘制标志
private slots:
    void on_queding_clicked();//创建迷宫
    void on_zhaolu_clicked();//寻找路径

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

 maze.h


#ifndef MAZE_H
#define MAZE_H

static const int N = 650;

class MAZE
{
public:
    ///< 值为0:绘制迷宫过道
    ///< 值为1:绘制迷宫围墙
    ///< 值为2:绘制你当前的位置
    ///< 值为3:绘制迷宫终点
    ///< 值为4:绘制你当前的位置
    ///< 值为6:绘制最短路径提示
    int maze[N][N];
    struct point//定义结构体point
    {
        int x, y, pre;
    }q[N*N], path[N*N];//结构体数组
    MAZE();
    void set_n(int tn);
    int get_n();
    //int get_len_path(){return len_path;}
    //void set_len_path(int tn){len_path = tn;}
    void printPath()//打印通路
    {
        bfs();
        for(int i = len_path-1; i >= 0; i--)
            if(maze[path[i].x][path[i].y]==0)
                maze[path[i].x][path[i].y] = 6;
    }
    void recoverPath()
    {
        for(int i = len_path-1; i >= 0; i--)
            if(maze[path[i].x][path[i].y]==6)
                maze[path[i].x][path[i].y] = 0;
    }
    void mazeInit();//迷宫信息
    int searchPath(int x, int y);//搜索路径
    void print();
    ~MAZE();
private:
    int n, len_path, nn;
    void bfs();
    void getPath(int pos);
};

#endif // MAZE_H

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

maze.cpp

#include "MAZE.h"
#include <iostream>
#include <windows.h>
#include <cstdio>
#include <cmath>
#include <time.h>
#include <cstring>
using namespace std;
int fa[N*N];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

MAZE::MAZE(){}


void MAZE::set_n(int tn)
{
    n = tn;
    nn = n/2;
}

int MAZE::get_n()
{
    return n;
}

void MAZE::print()
{
    bfs();
}
void MAZE::mazeInit()
{
    //迷宫围墙,nn*2+2是规划的迷宫地图大小
    for(int i=0; i<=nn*2+2; ++i)
        for(int j=0; j<=nn*2+2; ++j)
            maze[i][j] = 1;

    //在迷宫之外的的轮廓默认为过道
    for(int i=0, j=2*nn+2; i<=2*nn+2; ++i)
    {
        maze[i][0] = 0;
        maze[i][j] = 0;
    }
    for(int i=0, j=2*nn+2; i<=2*nn+2; ++i)
    {
        maze[0][i] = 0;
        maze[j][i] = 0;
    }

    //默认迷宫坐标第三行第一例为起点
    maze[2][1] = 2;
    //默认2*nn 行 和 2*nn+1列为终点
    maze[2*nn][2*nn+1] = 3;

    //生成无符号随机数
    srand((unsigned)time(NULL));
    //生成的随机数在 [0, nn+1]之间,生成路径
    searchPath(rand()%nn+1, rand()%nn+1);

    //将地图整体向左上方平移一个单位
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            maze[i][j] = maze[i+1][j+1];
        }
    }

    len_path = 0;
}

int MAZE::searchPath(int x, int y)
{
    //往四个方向
    static int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
    int zx = x*2;
    int zy = y*2;
    int next, turn, i;
    maze[zx][zy] = 0;
    //设置turn为[0, 4]之间的任意一个奇数
    turn = rand()%2 ? 1 : 3;
    //next=rand()%4 取值范围[0, 4),
    //next=(next+turn)%4 每个循环在奇数和偶数之间切换,[0, 4)遍历一遍
    //在迷宫地图里,随机选一个地方,开始挖路,4次循环,往4个方向挖
    for(i=0, next=rand()%4; i<4; ++i, next=(next+turn)%4)
        //搜索当前位置的第二步,如果是围墙,这将当前位置的沿着指定方向的下一步设置为路
        if(maze[zx+2*dir[next][0]][zy+2*dir[next][1]] == 1)
        {
            maze[zx+dir[next][0]][zy+dir[next][1]] = 0;
            searchPath(x+dir[next][0], y+dir[next][1]);//等于searthPath(zx+2*dir[next][0]][zy+2*dir[next][1])当前位置的下一步为节点开始搜索
        }
    return 0;
}

void MAZE::getPath(int pos)
{
    while(pos != -1)
    {
        path[len_path].x = q[pos].x;
        path[len_path].y = q[pos].y;
        len_path++;
        pos = q[pos].pre;
    }
}

void MAZE::bfs()//寻路
{
    int front, tail, sx, sy;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            if(maze[i][j] == 2)
            {
                sx = i; sy = j;
            }
    front = tail = 0;
    q[tail].x = sx;
    q[tail].y = sy;
    q[tail].pre = -1;
    tail++;
    int x, y, nx, ny;
    bool fg = false;
    while(front < tail)
    {
        x = q[front].x;
        y = q[front].y;
        for(int i = 0; i < 4; i++)
        {
            nx = x+dx[i];
            ny = y+dy[i];
            if(nx>=0&&nx<n&&ny>=0&&ny<n&&maze[nx][ny]==0)//确保头结点在路上
            {
                maze[nx][ny] = 5;//把此节点设为通路
                q[tail].x = nx;
                q[tail].y = ny;
                q[tail].pre = front;//加入到数组q中
                tail++;
            }
            if(maze[nx][ny] == 3){//起点和终点重合
                q[tail].x = nx;
                q[tail].y = ny;
                q[tail].pre = front;
                tail++;
                fg = true;//结束标志
                len_path = 0;
                path[len_path].x = nx;
                path[len_path].y = ny;
                len_path++;
                getPath(front);
            }
        }
        if(fg)break;//如果找到终点结束循环
        front++;//否则头结点到上一个节点
    }
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            if(maze[i][j] == 5)
                maze[i][j] = 0;
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "MAZE.h"
#include <iostream>
//绘制迷宫最小单元的(矩形)的长和宽20,即正方形
#define size 20
using namespace std;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //调整窗口中其它控件的大小
    int n = 31;
    /*新建迷宫*/
    m = new MAZE();
    m->set_n(n);
    //迷宫初始化
    m->mazeInit();
    //迷宫绘制
    m->print();
    //设置窗口标题
    this->setWindowTitle("迷宫");
    //设置窗口固定大小
    this->setFixedSize(620,650);

}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    int n = m->get_n();
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            //绘制迷宫围墙
            if(m->maze[i][j] ==1){
                painter.setPen(Qt::black);
                painter.setBrush(QBrush(Qt::black,Qt::SolidPattern));
                painter.drawRect(QRect(j*size,i*size,size,size));
            }
            //绘制你当前的位置
            else if(m->maze[i][j] == 2){
                painter.setPen(Qt::yellow);
                painter.setBrush(Qt::yellow);
                painter.drawRect(j*20,i*20,20,20);
            }
            //绘制迷宫终点
            else if(m->maze[i][j] == 3){
                painter.setPen(Qt::red);
                painter.setBrush(Qt::red);
                painter.drawRect(j*20,i*20,20,20);
            }
            //绘制迷宫过道
            else if(m->maze[i][j] == 0){
                painter.setPen(Qt::white);
                painter.setBrush(QBrush(Qt::white,Qt::SolidPattern));
                painter.drawRect(QRect(j*size,i*size,size,size));
            }
            //绘制最短路径提示
            else if(m->maze[i][j] == 6){
                painter.setPen(Qt::white);
                painter.setBrush(Qt::blue);
                painter.drawRect(j*20+5,i*20+5,10,10);
            }
        }
    }
}

void MainWindow::keyPressEvent(QKeyEvent *e)//键盘监听
{
    if(bfs_fg){
        m->recoverPath();
        bfs_fg = false;
        update();
    }
    int tx = X, ty = Y;
    int n = m->get_n();
    if(e->key()==Qt::Key_W)//上
    {
        if(X>0 && m->maze[X-1][Y] != 1)
        {
            X=X-1;
        }
    }
    else if(e->key()==Qt::Key_S)//下
    {
        if(X<n-1 && m->maze[X+1][Y] != 1)
        {
            X=X+1;
        }
    }
    else if(e->key()==Qt::Key_A)//左
    {
        if(Y>0 && m->maze[X][Y-1] != 1)
        {
            Y=Y-1;
        }
    }
    else if(e->key()==Qt::Key_D)//右
    {

        if(Y<n-1 && m->maze[X][Y+1] != 1)
        {
            Y=Y+1;
        }
    }
    int tmp = m->maze[X][Y];
    if(tmp == 3){
        QMessageBox::information(this,"提示","到达终点",QMessageBox::Yes);
    }else{
        m->maze[X][Y] = m->maze[tx][ty];
        m->maze[tx][ty] = tmp;
    }
    update();
}



void MainWindow::on_queding_clicked()//重建迷宫
{
    m->mazeInit();
    //初始化人物当前位置
    X = 1, Y = 0;
    //重绘地图,会调用void MainWindow::paintEvent(QPaintEvent *)
    update();
}

void MainWindow::on_zhaolu_clicked()//自动寻路
{
    m->printPath();
    bfs_fg = true;
    update();
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

迷宫游戏源码 的相关文章

随机推荐

  • 零拷贝( Zero-copy )

    一 背景 零拷贝 描述了计算机操作 其中CPU 不执行将数据从 一个存储区 复制到 另一个存储区 的任务 通过网络传输文件时 通常用于节省CPU周期和内存带宽 在传统的 Linux 操作系统的标准 I O 接口是基于数据拷贝操作的 即 I
  • C++基本语句(一)

    学习C 的第二天 一 C 的基本语句 1 1声明语句和变量 P21 P22 声明语句和变量 各自的作用是什么 为什么变量必须要声明 以及下面这段代码提供了哪两项信息 定义一个整型变量 int carrots 定义一个整型变量 int car
  • 尤里的复仇Ⅰ 小芳!

    尤里的复仇 小芳 作者 admin 时间 2021 06 15 分类 封神台 第一章 为了女神小芳 找到get参数id 使用 1 1 or 1 1 1 or 1 2 测试 发现存在sql注入 最终payload为 id 1 and 1 2
  • XMind中的 “甘特图”视图

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 甘特图 视图 当所有任务信息添加完成后 点击 任务信息 视图底部的 显示甘特图 按钮 XMind将弹出 甘特图 视图 所有任务信息将不同属性的线条展现 如果此时切换画布或者
  • math模块

    math 模块是Python中的标准模块 并且始终可用 要在此模块下使用数学函数 您必须使用导入模块import math 它提供对基础C库函数的访问 导入数学函数库 import math 查看 math 查看包中的内容 print di
  • C99与C89主要区别

    http www cnblogs com xiaoyoucai p 6146784 html
  • P4162 [SCOI2009]最长距离

    题目链接 这道题数据范围比较小 所以方法还是比较暴力的 思路 先按每个格子的状态 让所有格子与他周围的格子连一条权值为它连向那个格子的值 0或1 然后我们n方枚举所有格子跑最短路 最短路即为从起点到终点的最小障碍数 然后我们枚举所有最短路
  • Spring的两种定时器

    1 spring学习系列 定时器一TimerTask spring定时器一般有两种 TimerTask Quartz 本节只讲TimerTask 需要的包 aopalliance 1 0 jar commons logging 1 1 1
  • 使用html2Canvas跟jspdf将一部分页面生成PDF

    刚好碰到这么一个需求 前端需要将后端返回的json对象数据生成表单样式的pdf文件 首次接触所以简单记录一下 经过反复查找大致流程为 现在页面画一个表单 gt 拿到数据将数据放表单中 gt 给表单最外层加个ref利用html2Canvas生
  • Linux:NTP服务离线安装及配置

    0 常用命令 rpm qa grep ntp 查询已安装的ntp版本信息等 service ntpd status 查询ntp服务状态 service ntpd start 启动 service ntpd stop 停止 service n
  • hack the box - tier0

    Tier0 Meow Recommended Academy Modules INTRO TO ACADEMY STARTING POINT Tier 0 Machines Tags Enumeration Telnet External
  • 嵌入式linux解决方法

    一 问题描述 u boot version 2016 03 ubuntu version 18 04 ubuntu中环境配置正确 通过其他客户端能够挂载上 但是使用uboot得nfs下载命令会报错 gt nfs 80800000 192 1
  • CSS中表格以及表单的属性以及运用

    一 表格 按照一定的顺序摆放数据 表格是由一些单元格组成 1属性 border边框 cellspacing 单元格与单元格之间的距离 cell padding 单元格 边框和内容之间的距离 align 表格水平的位置 tr行 align 调
  • 并发编程NO.2

    并发编程 共享模型之管程 4 1共享资源问题 临界区 一个程序运行多个线程本身是没问题的 问题出在多个线程访问共享资源 多个线程读共享资源没有问题 但是多线程对共享资源进行读写操作 就会有问题 一段代码内如果存在对共享资源的多线程读写操作
  • leetcode 2. 两数相加

    2023 9 14 这道题还是有点难度 需要维护一个进位值 构造一个虚拟头节点dummy 用于结果的返回 还要构造一个当前节点cur 用于遍历修改新链表 整体思路就是长度短的链表需要补0 然后两链表从头开始遍历相加 要考虑进位 需要注意的点
  • [PHP] CURL获取cookie,模拟登录获取数据

    需求 通过CURL先登录 然后获取登录后的cookie 在请求数据接口的时候带上这个cookie即可 直接贴代码 1
  • 决策树分箱-特征工程之数据离散化处理-基于python实现

    一 简介 离散化是通过创建一组跨越变量值范围的连续区间将连续变量转换为离散变量的过程 1 1 离散化有助于处理异常值和高度偏斜的变量 离散化通过将这些值 与分布的剩余内点值一起放入较低或较高的区间来帮助处理异常值 因此 这些异常值观察不再与
  • rosbag与csv等格式转换

    1 rosbag 转换成csv 参看 https blog csdn net cliukai article details 94554350 具体就是 rostopic echo b
  • Cocos Creator 用JS脚本实现游戏背景的无限滚动

    首先是实现的一个原理 使用2张相同的图片 让它们在脚本中不停的移动 用y值的减少来实现 当有图片离开场景时 给此图片的y重新赋值 相当于位置的重置 在update中无限调用背景移动的函数 我的canvas 位于上方的图片结点名称为BG 下方
  • 迷宫游戏源码

    mainwindow h ifndef MAINWINDOW H define MAINWINDOW H include MAZE h include