Qt开发人机象棋

Qt开发人机象棋

前段时间在网上看到有人在用qt做象棋,心血来潮准备自己也实现一下,先看一波效果图(项目存在一些瑕疵):

效果图

1. 类关系图

类图

本程序较为简单,设计上分为四个没有继承关系的类:

  • Widget:界面类;负责界面重绘,鼠标点击和按钮点击事件响应,并创建棋子,控制类,计算类等
  • ChessPiece:棋子类;包含棋子的属性:id, 所在行列, 是否是红方阵营, 是否死亡
  • Control:控制类;包括棋子走棋方法:是否可以走棋, 保存走棋路径等等
  • Computer:电脑计算类;运用最大最小值算法求得最优走棋

类包含图

2. 用到的技术手段

2.1 界面计算分离

由于博弈树会很大,如果将所有的计算都放在widget类中计算会出现卡界面问题;所以通过类的设计,分为widget和computer两个类,通过棋子这个中间变量来进行通信

2.2 线程

使用多线程来实现界面计算分离,使得计算最优走棋时不会出现卡界面问题

2.3 定时器

定义定时器,timeout连接槽函数,更新各方等待时间

3. Qt开发象棋过程问题记录

3.1 问题 1. 在初次开发中存在内存泄漏问题

问题描述:在初次开发中,出现运行后电脑卡机现象

解决: 一般出现运行程序电脑卡机现象,是大量内存泄漏导致的;回顾程序,大量使用堆内存的地方就是博弈树vector保存路径;查看后发现在使用该vector时,只是removeLast,并未真正释放申请的堆内存,然后delete,解决。

3.2 问题 2. 类设计糟糕,使得计算和界面未分离

问题描述:由于时间关系,在类的设计上显得糟糕,计算机计算类直接继承于界面类,导致计算量大时,存在卡界面问题

解决: 花时间将项目重写,对项目进行功能分割,使得项目分为:界面类,控制类,棋子类,电脑计算类;从而使得计算和界面分离

3.3 问题 3. 重写项目后,效率降低了十倍

问题描述:重写项目后,发现计算效率差了十倍,花了两天业余时间,通过不断缩小范围qDebug,还是找不到问题

解决: 无奈就又开始重写,最后发现是因为原来项目中使用原始数组来存储棋子,但是新的项目使用QVector存储棋子,原因就在这里,不清楚为什么使用QVector的效率这么低,最后还是换成了数组存储。

3.4 问题 4. 信号和槽连接问题

问题描述:自定义类和继承自QWidget的类使用信号和槽通信,发现连接不上

QObject::connect: No such slot QObject::startComputerSlot() in ..\ChineseChess\widget.cpp:34
QObject::connect:  (sender name:   'Widget')
QObject::connect: No such signal QObject::sendComputerBestStep(Step *) in ..\ChineseChess\widget.cpp:35
QObject::connect:  (receiver name: 'Widget')

解决: 这个问题以前有遇到过; 在自定义的类中,使用信号和槽,需要继承自QObject类,并且在类头添加 Q_OBJECT

3.5 问题 5. 使用线程之后,界面频繁重绘

问题描述:将项目重写一遍后,做好了界面和计算分离,可以添加线程使得计算时不会卡界面;但是在添加线程后会出现界面频繁重绘问题( 现象就是棋子会频繁跳动)

解决: 虽然还不清楚为什么添加线程后会出现这样的问题,但是可以知道线程和界面唯一的联系就是棋子变量,所以只需要在线程中做一份棋子变量的拷贝,让其在线程计算中使用即可

4. 项目尚存在的问题

4.1 算法问题

算法较为初级,棋力水平一般(当然不会下象棋的我下不过它),本想加入一些开局库和残局库的,但是没有心思再搞下去了

4.2 程序完成性问题

程序大部分都完成了,除了小部分:

  • 一方输之后,只是简简单单的弹框了事,没有后续
  • 默认红方先手(即人一方);机器先手的按钮没实现,不过不难
  • 输出棋谱方面,不懂象棋方面的术语,所以输出的棋谱以坐标表示走棋路径
  • 定时器方面存在问题

4.2 程序重绘问题

项目在程序的绘制方面存在小瑕疵

5. 项目体验地址

项目体验地址

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值