实习项目一源代码:
Headers:mianwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QVector>
#include "ui_mainwindow.h"
QT_BEGIN_NAMESPACE
//mianwindow是一个ui中得类
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// void iniUI();//习惯性地定义一个这样的函数,这是关于我们自己处理UI界面时候的样子
// void MYUI();
//public slots:
// void onButttonGroupClicked(QAbstractButton* btn);//关联信号与槽的函数
QString expression;
private slots:
void on_btn_lbr_clicked();
void on_btn_rbr_clicked();
void on_btn_add_clicked();
void on_btn_sub_clicked();
void on_btn_mul_clicked();
void on_btn_div_clicked();
void on_btn_equ_clicked();
// void on_btn_ls_clicked();
// void on_btn_rs_clicked();
void on_btn_AC_clicked();
void on_btn_del_clicked();
void on_btn_0_clicked();
void on_btn_1_clicked();
void on_btn_2_clicked();
void on_btn_3_clicked();
void on_btn_4_clicked();
void on_btn_5_clicked();
void on_btn_6_clicked();
void on_btn_7_clicked();
void on_btn_8_clicked();
void on_btn_9_clicked();
void on_btn_poi_clicked();
void on_btn_cmem_clicked();
private:
Ui::MainWindow *ui;
// QString expression;
int count1=0;//计数器1,可以判断左右括号是不是正对出现
int count2=0;//
};
#endif // MAINWINDOW_H
Sources:mianwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QButtonGroup> //按钮组
#include <QDebug>
#include<QStack>
const int maxn=110;//最多只能输入440个字节,int是4字节,char是1字节
char priority[7][7]={
//i表示表达书字符,j表示栈顶元素
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'}, // 此行"("=")"表示左右括号相遇,括号内运算已完成,i=4,且j=5
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='} // "=" 表示整个表达式求值完毕
}; // "0"表示不可能出现这种情况 ( 语法错误 )
//Procede 用于判断运算符栈栈顶运算符 a1 与读入运算符 a2 之间的优先关系函数
char Procede(char a,char b){
//a表示栈顶元素,b表示表达式元素
// 建立 priority[][] 到 运算符比较间的映射关系
int i,j;
switch(a){
case'+':i=0;break;
case'-':i=1;break;
case'*':i=2;break;
case'/':i=3;break;
case'(':i=4;break;
case')':i=5;break;
case'#':i=6;break; // # 是表达式的结束符
}
switch(b){
case'+':j=0;break;
case'-':j=1;break;
case'*':j=2;break;
case'/':j=3;break;
case'(':j=4;break;
case')':j=5;break;
case'#':j=6;break;
}
return priority[i][j];
}
double Operate(double m,double n,char x){
if(x=='+')
return m+n;
if(x=='-')
return n-m;
if(x=='*')
return m*n;
if(x=='/')
return n/m;
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)//ui被实例化了
{
ui->setupUi(this);//this是当前mainwindow类的实例对象。通过setupui就把ui设置给了this指针指向的实例对象
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btn_equ_clicked()
{
QChar j= expression.right(1).at(0);
if(count1!=count2||j=="+"||j=="-"||j=="*"||j=="/")
{
ui->ted->setText("表达式错误");
return;
}
QString e;
e = expression;
e += '=';
QStack <float> OPND; // 存数字
QStack <char> OPTR; // 存操作符
char s[maxn]; //运算式数组
OPTR.push('#'); //操作符栈底部加#
char ss[2]="#"; //定义一个#,然后尾部还有\0
// char path[50];
QString str = expression;
QByteArray ba = str.toLocal8Bit();
memcpy(s,ba.data(),ba.size()+1);//加1是为了最后的终结符,否则转换回来的时候不知道什么时候截止
QString str2;
str2 = QString::fromLocal8Bit(s);
/*qt fromLocal8Bit()函数可以设置编码。
QT默认的编码是unicode,不能显示中文的 windows默认使用(GBK/GB2312/GB18030) 使用fromLocal8Bit()函数,
实现了从本地字符集GB到Unicode的转换,用于处理汉语显示乱码等问题
static inline QString fromLocal8Bit(const QByteArray &str);该函数返回的是String类型的数
*/
//通过strcat函数,对表达式进行尾部加#,然后依次判断当前输入的是数字和运算符的情况
strcat(s,ss);//strcat是一个追加字符串的函数,运算式尾部加 "#"--结束运算符
char c=s[0];//c表示运算式的最前面那个字符
int k=1;
while(c!='#'||OPTR.top()!='#')
{ //表达式未读完或者运算未完(未到底部)
float y=0;
//用c来表示当前输入的这个字符,如果是一个数字,那么压入OPND栈中
if(c>='0' && c<='9')
{
while(c>='0' && c<='9')
{ // 读入连续的数字
y=y*10+(c-'0');//y*10表示两位数及两位以上的数的处理
c=s[k++]; //c向后遍历,一直遍历到s[110]
}
if(c=='.')
{
//小数点
float a=0,b=0;
k+=1;
c=s[k];
while (c>='0' && c<='9')
{
b=b*10+(c-'0');
c=s[k++];
a++;
}
for(;a>0;a--)
{
b=b*(10^(-1));
}
y=y+b;
}
OPND.push(y); // 把读进的数字入数字栈
}
//运算符
else
{
switch(Procede(OPTR.top(),c)) //栈顶运算符和当前读取运算符,比较优先级
//OPTR.top()表示表格左边的,用OPTR.top()和c比较
{
case'<': //栈顶元素优先级低
OPTR.push(c);//表达式的字符压入栈顶
c=s[k++];//遍历
break;
case'=':
OPTR.pop(); // 脱括号,或者去掉井号
c=s[k++]; // 读入下一个字符
break;
case'>': //退栈并将运算结果入栈
char x=OPTR.top();OPTR.pop();
float m=OPND.top();OPND.pop();
float n=OPND.top();OPND.pop();
OPND.push(Operate( m, n ,x ));//将结果存入操作数栈
break;
}
}
}
ui->ted->setText(QString::number(OPND.top()));//在ted界面显示结果
//在tbr界面存储数据
e += QString::number(OPND.top());
ui->tbr->append(e);//在tbr界面展示遍历的结果
}
void MainWindow::on_btn_lbr_clicked()
{
if((expression.back()=="(")||(expression.back()==")")||(expression.back()>='0' && expression.back()<='9'))return;
expression+="(";
count1++;
ui->ted->setText(expression);
}
void MainWindow::on_btn_rbr_clicked()
{
if((expression==NULL||expression.back()==".")||(expression.back()=="(")||(expression.back()==")")||(expression.back()=="+")||(expression.back()=="-")||(expression.back()=="*")||(expression.back()=="/"))return;
if(count1>count2)
{
expression+=")";
count2++;
ui->ted->setText(expression);}
else return;
}
void MainWindow::on_btn_add_clicked()
{
if(expression==NULL||expression.back()=="+"||expression.back()=="-"||expression.back()=="*"||expression.back()=="/")return;
expression+="+";
ui->ted->setText(expression);
}
void MainWindow::on_btn_sub_clicked()
{
if(expression==NULL||expression.back()=="+"||expression.back()=="-"||expression.back()=="*"||expression.back()=="/")return;
expression+="-";
ui->ted->setText(expression);
}
void MainWindow::on_btn_mul_clicked()
{
if(expression==NULL||expression.back()=="+"||expression.back()=="-"||expression.back()=="*"||expression.back()=="/")return;
expression+="*";
ui->ted->setText(expression);
}
void MainWindow::on_btn_div_clicked()
{
if(expression==NULL||expression.back()=="+"||expression.back()=="-"||expression.back()=="*"||expression.back()=="/")return;
expression+="/";
ui->ted->setText(expression);
}
void MainWindow::on_btn_AC_clicked()
{
int n=sizeof(expression);
expression.chop(n*n);
ui->ted->setText(expression);
}
void MainWindow::on_btn_del_clicked()
{
expression.chop(1);
ui->ted->setText(expression);
}
void MainWindow::on_btn_0_clicked()
{
if(expression.back()=="0"||expression.back()=="/")return;
expression+="0";
ui->ted->setText(expression);
}
void MainWindow::on_btn_1_clicked()
{
if(expression.back()=="0")
QString clear(expression);
expression+="1";
ui->ted->setText(expression);
}
void MainWindow::on_btn_2_clicked()
{
expression+="2";
ui->ted->setText(expression);
}
void MainWindow::on_btn_3_clicked()
{
expression+="3";
ui->ted->setText(expression);
}
void MainWindow::on_btn_4_clicked()
{
expression+="4";
ui->ted->setText(expression);
}
void MainWindow::on_btn_5_clicked()
{
expression+="5";
ui->ted->setText(expression);
}
void MainWindow::on_btn_6_clicked()
{
expression+="6";
ui->ted->setText(expression);
}
void MainWindow::on_btn_7_clicked()
{
expression+="7";
ui->ted->setText(expression);
}
void MainWindow::on_btn_8_clicked()
{
expression+="8";
ui->ted->setText(expression);
}
void MainWindow::on_btn_9_clicked()
{
expression+="9";
ui->ted->setText(expression);
}
void MainWindow::on_btn_poi_clicked()
{
if(expression.back()=="."||expression.back()=="("||expression.back()==")"||expression.back()=="+"||expression.back()=="-"||expression.back()=="*"||expression.back()=="/")return;
if((expression.lastIndexOf(".")>expression.lastIndexOf("+"))||(expression.lastIndexOf(".")>expression.lastIndexOf("-"))||(expression.lastIndexOf(".")>expression.lastIndexOf("*"))||(expression.lastIndexOf(".")>expression.lastIndexOf("/")))
{
return;
}
else{
expression+=".";
ui->ted->setText(expression);
}
}
void MainWindow::on_btn_cmem_clicked()
{
ui->tbr->clear();
}
实习项目二源代码:
1.Headers:widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QKeyEvent>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
//定义一个枚举类型的变量即可
enum Direct{
DIR_UP,
DIR_DOWN,
DIR_RIGHT,
DIR_LEFT
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
protected:
//蛇的按键移动
void keyPressEvent(QKeyEvent *event);//按键处理,是从父类QWidget继承的
//每隔一个时延latency,朝一个方向加一个方块和去掉一个方块
void addTop();
void addDown();
void addLeft();
void addRight();
//绘图
void paintEvent(QPaintEvent *event);
//前进时加头节点的同时删除尾节点
void deleteLast();
//随机生成食物
void addNewReward();
//判断游戏结束的条件
bool checkContact();
private:
Ui::Widget *ui;
int moveFlag = DIR_UP;//游戏一开始的方向是朝向上的
//得分
int score = 0;
bool gamestart = false;//表示游戏开始或者暂停
QTimer *timer;//定时器
//每隔一个时延让蛇移动,相当于蛇的速度
int latency=150;
//链表来表示一条蛇
QList <QRectF> snake;//QRectf表示一块有面积的区域。可以理解成一个链表
//食物
QRectF rewardNode;
//方块的宽高
int nodeWidht = 20;
int nodeHeight = 20;
protected slots:
void counttimeout();
};
#endif // WIDGET_H
2.Sources:widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
#include<QKeyEvent>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("贪吃蛇");
timer = new QTimer(this);//使用QTimer定时器类,首先创建一个定时器类的对象
connect(timer,SIGNAL(timeout()),this,SLOT(counttimeout()));//timer 超时后会发出timeout()信号,所以在创建好定时器对象后给其建立信号与槽
resize(1524,950);
//初始化蛇身
QRectF rect(500,230,nodeWidht,nodeHeight);
snake.append(rect);
addTop();
addTop();
addNewReward();//初始化食物
}
Widget::~Widget()
{
delete ui;
}
//对按钮处理,每次按不同按钮,就会进行不同处理,比如按上下左右产生移动,按空格表示暂停,按其他键表示速度增加或减小
void Widget::keyPressEvent(QKeyEvent *event){
//用switch分别表示面对相应按钮的相应操作
switch (event->key()) {
//朝上
case Qt::Key_Up:
if(moveFlag != DIR_DOWN){
moveFlag = DIR_UP;
}
break;
//朝下
case Qt::Key_Down:
if(moveFlag != DIR_UP){
moveFlag = DIR_DOWN;
}
break;
//朝左
case Qt::Key_Left:
if(moveFlag != DIR_RIGHT){
moveFlag = DIR_LEFT;
}
break;
//朝右
case Qt::Key_Right:
if(moveFlag != DIR_LEFT){
moveFlag = DIR_RIGHT;
}
break;
//暂停
case Qt::Key_K:
latency=50;timer->start(latency);
break;
case Qt::Key_M:
latency=400;timer->start(latency);
break;
case Qt::Key_Space:
if(gamestart==false)//如果一开始就等于false,那么游戏是没开始的,那么按下空格键就会让游戏开始
{
gamestart = true;
// 可以把这里的界面改了,
// 改成初始界面选择速度
//启动定时器
timer->start(latency);
}
else //表示gamestart一开始是true,说明游戏是正在进行的,那么就让gamestart变为false
{
gamestart=false;
timer ->stop();
}
break;
default:
break;
}
}
//
void Widget::counttimeout()//实现超时对应函数,即每隔latency单位的时延,就会产生一个信号让this指针相应一个函数counttimeout的操作
{
//吃到食物
int counter = 1;
if(snake[0].intersects(rewardNode)){
counter++;
score++;
latency=latency-2;
timer->start(latency);
//吃到以后随机生成食物
addNewReward();
}
while(counter--)
{
switch(moveFlag){
case DIR_UP://顶部加方块
addTop();
break;
case DIR_DOWN:
addDown();
break;
case DIR_LEFT:
addLeft();
break;
case DIR_RIGHT:
addRight();
break;
}
}
deleteLast();
update();//自动调用重绘方法
}
void Widget::addTop(){//向上
QPointF leftTop;
QPointF rightBottom;
// if(snake[0].y() - nodeHeight < 0){
// leftTop = QPoint(snake[0].x(),this->height() - nodeHeight);
// rightBottom = QPointF(snake[0].x() + nodeWidht,this->height());
// }
// else{
leftTop = QPointF(snake[0].x(),snake[0].y()-nodeHeight);//左下角坐标
rightBottom = snake[0].topRight();//右下角坐标
// }
snake.insert(0,QRectF(leftTop,rightBottom));
}
void Widget::paintEvent(QPaintEvent *event){
//画游戏界面
QPainter painter(this);
QPen pen;
QBrush brush;
//背景图
QPixmap pix;
pix.load("D:/C++/1.jpg");
painter.drawPixmap(0,0,1524,950,pix);
//画蛇
pen.setColor(Qt::yellow);
brush.setColor(Qt::blue);
brush.setStyle(Qt::SolidPattern);
painter.setPen(pen);
painter.setBrush(brush);
//遍历snake链表所有数据,依次活出一块块蛇身
for(int i=0;i<snake.length();i++){
painter.drawRect(snake[i]);
}
//画食物
pen.setColor(Qt::green);
brush.setColor(Qt::green);
brush.setStyle(Qt::SolidPattern);
painter.setPen(pen);
painter.setBrush(brush);
painter.drawEllipse(rewardNode);
//结束画面
if(checkContact()){
QFont font("宋体",30,QFont::ExtraLight,false);
painter.setFont((font));
painter.drawText((this->width ()-300)/2,
(this->height()-30)/2,
QString("游戏结束"));
timer->stop();
}
//画分数记录
pen.setColor(Qt::red);
brush.setColor(Qt::red);
painter.setPen(pen);
painter.setBrush(brush);
QFont font("宋体",20,QFont::ExtraBold,false);
painter.setFont(font);
painter.drawText(0,nodeHeight*3,
QString("分数:"+QString::number(score*10)));
}
void Widget::deleteLast(){
snake.removeLast();
}
void Widget::addDown(){//向下
QPointF leftTop;
QPointF rightBottom;
//向下时如果接触到底端,则从对应的顶端重新生成蛇头
// if(snake[0].y() + nodeHeight * 2 > this->height()){
// leftTop = QPointF(snake[0].x(),0);
// rightBottom = QPointF(snake[0].x() + nodeWidht,nodeHeight);
// }
//没有触碰下边界时,正常加减节点
// else{
leftTop = snake[0].bottomLeft();
rightBottom = snake[0].bottomRight() + QPointF(0,nodeHeight);
// }
snake.insert(0,QRectF(leftTop,rightBottom));
}
void Widget::addLeft(){//向左
QPointF leftTop;
QPointF rightBottom;
// if(snake[0].x() - nodeWidht<0){
// leftTop = QPointF(this->width() - nodeWidht,snake[0].y());
// }
// else{
leftTop = snake[0].topLeft() - QPointF(nodeWidht,0);
// }
rightBottom = leftTop + QPointF(nodeWidht,nodeHeight);
snake.insert(0,QRectF(leftTop,rightBottom));
}
void Widget::addRight(){//向右
QPointF leftTop;
QPointF rightBottom;
// if(snake[0].x() + nodeWidht*2 > this->width()){
// leftTop = QPointF(0,snake[0].y());
// }
// else{
leftTop = snake[0].topRight();
// }
rightBottom = leftTop + QPointF(nodeWidht,nodeHeight);
snake.insert(0,QRectF(leftTop,rightBottom));
}
void Widget::addNewReward(){//随机生成食物
rewardNode = QRectF(
qrand()%(this->width()/30)*20,
qrand()%(this->height()/30)*20,
nodeWidht,
nodeHeight);
}
bool Widget::checkContact(){//身体和头接触结束
for(int i=1;i<snake.length();i++){
if(snake[0] == snake[i]||(snake[0].y() > this->height())||(snake[0].y() <=0)||(snake[0].x() <=0)||(snake[0].x() > this->width())){
return true;
}
}
return false;
}
实习项目三源代码:
1.Headers:mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPainter>
#include <QKeyEvent>
#include <QMessageBox>
#include <iostream>
#include "maze.h"
using namespace std;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
Maze *mymaze;
int X;
int Y;
bool bfs_fg;
private slots:
void slot_create();
void slot_search();
protected:
void paintEvent(QPaintEvent *);
void keyPressEvent(QKeyEvent *e);
};
#endif // MAINWINDOW_H
2.Headers:maze.h
#ifndef MAZE_H
#define MAZE_H
#include <QObject>
using namespace std;
static const int N = 650;
class Maze : public QObject
{
Q_OBJECT
public:
explicit Maze(QObject *parent = nullptr);
void set_n(int tn);
int get_n();
void printPath();//打印通路
void recoverPath();
void mazescr();//迷宫信息
int searchPath(int x, int y);//搜索路径
void print();
public:
// 值为0:绘制迷宫过道
// 值为1:绘制迷宫围墙
// 值为2:绘制你当前的位置
// 值为3:绘制迷宫终点
// 值为4:绘制你当前的位置
// 值为6:绘制最短路径提示
int maze[N][N];
struct point//定义结构体point
{
int x, y, pre;
}q[N*N], path[N*N];//结构体数组
private:
int n, len_path, nn;
int fa[N*N];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
void bfs();
void getPath(int pos);
};
#endif // MAZE_H
3.Sources:mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
int n = 31;//除了最外围的墙,一共有29行
mymaze = new Maze();
mymaze->set_n(n);//maze.cpp中的定义set_n,相当于让nn=n/2,相当于除了最外围那堵墙,一共有29列29行可以让
mymaze->mazescr();//创建迷宫
mymaze->print();//输出迷宫寻找的路径
this->setWindowTitle("迷宫");//将窗口姓名改为“迷宫”
this->setFixedSize(620,640);//将当前窗口大小设置为00*00像素
connect(ui->btn_create,SIGNAL(clicked()),this,SLOT(slot_create()));//点击“初始化新迷宫”按钮进行创造随机迷宫
connect(ui->btn_search,SIGNAL(clicked()),this,SLOT(slot_search()));//点击“自动寻路(寻找最短路径)”按钮
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slot_create()
{
mymaze->mazescr();
X = 1, Y = 0;
update();//更新画面,使重新构建的迷宫地图重新显示在画面中
}
//点击“自动寻路(寻找最短路径)”按钮,寻找迷宫到达终点的最短路径
void MainWindow::slot_search()
{
mymaze->printPath();
bfs_fg = true;//每次最短路径找到以后,更新bfs_fg的值为true,以便在自己移动时清除它
update();
}
//绘制地图的墙、起点和终点、最短路径的标记样子、过道
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int n = mymaze->get_n();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
//围墙设置为灰色
if(mymaze->maze[i][j] ==1){
painter.setPen(Qt::gray);
painter.setBrush(QBrush(Qt::gray,Qt::SolidPattern));
painter.drawRect(QRect(j*20,i*20,20,20));
}
//黄色的点表示起点
else if(mymaze->maze[i][j] == 2){
painter.setPen(Qt::yellow);
painter.setBrush(Qt::yellow);
painter.drawRect(j*20,i*20,20,20);
}
//红色的点表示终点
else if(mymaze->maze[i][j] == 3){
painter.setPen(Qt::red);
painter.setBrush(Qt::red);
painter.drawRect(j*20,i*20,20,20);
}
//过道设置为白色
else if(mymaze->maze[i][j] == 0){
painter.setPen(Qt::white);
painter.setBrush(QBrush(Qt::white,Qt::SolidPattern));
painter.drawRect(QRect(j*20,i*20,20,20));
}
//最短路径设置
else if(mymaze->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)//bfs_fg默认初始值为true
{
mymaze->recoverPath();//让显示出的最短路径的痕迹消除,以便更新因生成新的迷宫而改变的新的最短路径
bfs_fg = false;
update();
}
int tx = X, ty = Y;
int n = mymaze->get_n();
if(e->key()==Qt::Key_W)//上
{
if(X>0 && mymaze->maze[X-1][Y] != 1)//周围四块移动的区域不是出边界或者墙的时候,可以移动
{
X=X-1;
}
}
else if(e->key()==Qt::Key_S)//下
{
if(X<n-1 && mymaze->maze[X+1][Y] != 1)
{
X=X+1;
}
}
else if(e->key()==Qt::Key_A)//左
{
if(Y>0 && mymaze->maze[X][Y-1] != 1)
{
Y=Y-1;
}
}
else if(e->key()==Qt::Key_D)//右
{
if(Y<n-1 && mymaze->maze[X][Y+1] != 1)
{
Y=Y+1;
}
}
//通过上下左右移动后,XY的值都在发生了变化
int tmp = mymaze->maze[X][Y];
if(tmp == 3){
QMessageBox::information(this,"提示","朋友,恭喜你成功到达终点!",QMessageBox::Yes);
}else{
mymaze->maze[X][Y] = mymaze->maze[tx][ty];// /// 为什么要这么赋值???????????????????????????
mymaze->maze[tx][ty] = tmp;
}
update();
}
4.Sources:maze.cpp
#include "maze.h"
Maze::Maze(QObject *parent) : QObject(parent)
{
}
void Maze::set_n(int tn)
{
n = tn;
nn = n/2;
}
int Maze::get_n()
{
return n;
}
//绘制最短路径
void Maze::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 Maze::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 Maze::mazescr()
{
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;
maze[2*nn][2*nn+1] = 3;//终点在第31行,32列
//生成随机无符号数
srand((unsigned)time(NULL));
//生成的随机数在 [0, n]之间,生成路径
searchPath(rand()%nn+1, rand()%nn+1);//nn+1为随机生成数的最大值//rand()%nn+1=2
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;
}
//prim算法创建路径
int Maze::searchPath(int x, int y)
{
static int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
int zx = x*2;//zx=4
int zy = y*2;//zy=4
int next, turn, i;
maze[zx][zy] = 0;//制造随机的走道来打断原有的生成的迷宫的路径//maze[4][4] = 0
//设置turn为[0, 4)之间的任意一个奇数,分别表示上下左右
turn = rand()%2 ? 1 : 3;//
//next=rand()%4 取值范围[0, 4)
//next=(next+turn)%4 每个循环在奇数和偶数之间切换,[0, 4)遍历一遍
//在迷宫地图里,随机选一个地方,开始挖路,4次循环,往4个方向挖(由(next+turn)%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)
//判断上下左右的隔一个单位是否为1,为1则变为0
{
maze[zx+dir[next][0]][zy+dir[next][1]] = 0;
searchPath(x+dir[next][0], y+dir[next][1]);
}
return 0;
}
void Maze::print()
{
bfs();
}
void Maze::bfs()
{
int front, tail, start_x, start_y;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(maze[i][j] == 2)//maze[][]为头文件maze.h中的二维整型数组
{
start_x = i; start_y = j;
}
front = tail = 0;
q[tail].x = start_x;
q[tail].y = start_y;
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;
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;
}
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;
}
}