大概是最弱鸡的2D仿真

写作业中学到的可视化

Posted by 柠萌 on July 27, 2017

缘起

大二下学期的基础课特别多,大作业也特别多,就在几周前,我在大作业与考试复习的夹缝里顽强地生存。

大概是一个模拟草原上狼吃羊的过程,要求C++语言,使用OOP思想,使用图像可视化。


实验过程

具体的实验报告可以在GitHub - Wolf and Sheep上看,这里就不多叙述惹。

avatar


狼和羊的人工智障

比原来的要求增加了一些东西,优化的移动策略:

  • 狼会往狼多的方向移动
  • 羊会往远离追逐他的狼的方向逃跑,往狼少的地方移动
  • 繁殖时会为出生的宝宝选择最佳出生位置

实现方法非常简单,其实就是计算权重,也就是提供了一个决策方案的实现思路,越优先的考虑节点的权重乘以越高的位置。原理相当于设计一个函数计算优先度,我们考虑问题往往会一层一层的考虑比较(类似于决策树)。

如下图,羊首先考虑有没有狼在身边,一步就能吃掉自己,其次考虑移动后附近狼的数目多少,最后考虑移动后的草的数量。

avatar

因为活命永远是最重要的,所以首先不要逃离最接近的狼,然后再长远考虑移动后的情况。最后权重计算公式是W=Aw1+Bw2+C*w3,这里的为w1、w2、w3参数是可以变化的,具体要视情况而定,这个线性模拟策略参数设置可以考虑通过神经网络模型等得出。当然这里保证A、B、C小于10,将参数w1、w2、w3分别设为100、10、1,就可以得到一种简单的模拟方式:就是先比较A,再比较B,再比较C,只要策略一的A比策略二的大,就不考虑BC的值。

这部分也不是本文重点,就此略过。


可视化(QT)

最后我选择QT进行可视化,其中一个原因是QT是开源的,最重要的原因是跨平台,对于使用MacOS的我来说,写作业给老师比较烦就是老师用的是Windows,好多库都是不一样的。QT可以跨三个平台,大概有点不好的就是UI文件会有点错位,不过关系不大。

QT是一个可视化架构,通过QT可以很容易做出一些比较好看耐用的交互界面。而QT creator则是一个配套的IDE。

QT简介请看:关于QT、QT creator和编译器,新手入门必知的一些知识

avatar

1. QT的安装与配置

对于MacOS来说,下载一个QT Creater,这是一个大概是IDE的东西。感觉Mac版的话要自己配置Qt版本,之前我搞了好久都不行。建议安装编译器的时候用brew安装,

brew update
brew install qt

安装成功后然后终端会提示安装的路径(大概是/usr/local/Cellar/qt/5.9.0),然后在Qt Creator中设置版本(偏好设置->构建与运行->Qt Version->添加…)。这里最坑的是Mac的打开文件窗口不能直接访问系统保护的目录,这里有几个方法,一是直接Command+Shift+G,输入路径,二是前往文件夹或者终端cd路径,然后创建个快捷方式(替身),然后通过替身跳到文件夹。

avatar

avatar

配置完就可以使用了,左下角有个类似资源管理器的东西,选“项目”里面会有工程文件的Source和资源文件等。

avatar

然后旁边可以选择编译器、release、debug、build。

在Windows下的安装就傻瓜得多了,大概就是一个引导程序,比较傻瓜的装好就OK。编译器建议只选MingW的就够了。

2. QT的控件对象

QT的工程文件是.pro,项目的文件框架如下图所示。

avatar

Headers和Source是头文件和源文件,一般就是cpp实现的Source,Form是.ui文件,大概就是初始界面的框架。Resources是资源文件,一些图片一般放在里面用于调取。

.ui文件可以在“设计“模式(designer)中直接画出窗口相应的框架,这个有点像VB,如下图所示。这里指出在windows下里面的控件对象会错位。

avatar

操纵窗口是通过工程创建的一个类MainWindow实现的。该类相当于是一个窗口,包含一个指针成员ui,调用窗口的预先绘制好控件对象时,使用ui->ObjName作为对象名使用,尤其菜单栏,状态栏等就更应该如此。

ui->mainToolBar->setFixedHeight(10);//设置工具栏高度为10

当然,还可以自己创建控件对象,为了方便调用自己创建的对象,一般在MainWindow类中会创建一个指针成员,用于记录该对象。

timer = new QTimer(this);   //创建一个QTimer,之后可以使用timer来调用该对象
/* ----------------- */
delete timer;               //一般在析构函数中会调用delete删除对象

简而言之,QT是通过控制控件对象完成界面操作的。

3. QT的资源库

前面说到QT的resources文件夹用于存放资源,比如图片素材这类东西就可以放在里面,以备调用。

在右下角文件管理器中选项目,Resources文件夹右键-添加新文件,创建一个.qrc文件,然后往.qrc文件中添加资源,自后就可以调用其中的资源了。

avatar

avatar

img=new QImage(":/jpg/resource/green.png");   //从资源库调取文件green.png
pLabel->setPixmap(QPixmap::fromImage(*img));  //在QLabel中显示图片

4. QT的信号-槽机制

信号与槽是QT的两个重要概念,两者可以将不同对象联系起来,使程序更安全简洁。

信号指的是对象发出的触发指令,槽则是接受信号并触发的函数,两者以connect函数连接起来。

可以参考文章Qt入门之信号与槽机制

class MainWindow : public QMainWindow {

    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    //other code...

private slots:  //槽函数必须要在类的public/private/protected slots中声明,否则无法使用
    void function();

};

//语法:connect(sender, SIGNAL(signal), receiver, SLOT(slot));

connect(pushButton1,SIGNAL(clicked(bool)),label,SLOT(close()));
connect(pushButton2,SIGNAL(clicked(bool)),this,SLOT(function()));

5. QT的编译打包

release编译后,将.exe文件提取出来,用Qt命令行使用windeployqt来拷贝依赖包即可发布。

windeployqt Programme.exe

命令自动会将程序需要的第三方库(.dll文件)复制到.exe文件的的路径中。

在Mac下生成的app文件,也可以用macdeployqt来进行依赖库拷贝。

具体可以参考:Qt 程序打包发布总结


后记

做这个课程作业最大的收获大概就是接触到QT,可以将一些小程序可视化,能够做出一个界面,这个过程也是挺有趣的。

代码已发到GitHub - Wolf and Sheep

2017.07.27 于广州