注:项目设计时时间有限,并且独立完成,很多时间花在算法的编写上,界面设计和模块整合有待改正和优化。如果对您有帮助,客官不要吝惜star呀!
游戏界面展示:
一、前言
这是原项目的新整合。两年前,我为c++实践课程做了这个项目,但游戏本身有太多“不必要”的部分,比如登录或注册模块。这些对于项目的核心贡献来说是多余的,但有助于显示我的工作量让我拿个好成绩。
因此,现在我只保留了项目的核心部分:阿尔法-贝塔算法和Qt绘制的棋盘。
打开方式:使用Qt Creator 6.3打开项目,然后构建并运行代码。
项目内容:利用C++的知识和QT以及一些自行拓展的新知识,实现AI模式对战的五子棋游戏,尝试设计启发式算法,实现AI模式的五子棋游戏。
二、关键设计
2.1 游戏界面设计
首先我们设计一个类gamewindow,继承至qt的QMainWindow,数据成员为Chess类的指针。对于画出已下的棋子,Chess类的数据成员是个二维数组用来标记下棋位置及对应玩家,所以可以通过指针调用成员函数访问Chess类的二维数组获得下棋位置,之后用Qt的画笔和画刷实现绘画棋子,棋盘网格和棋盘的五个黑点等。
对于当前选择框的移动,这里采用鼠标移动事件,捕获捕获鼠标移动的位置,并在就近的位置画出红色的选择框。由于Qt的鼠标移动事件节省资源,实际的移动事件只有在按下鼠标才会捕捉,但为了设计界面红框随鼠标移动,需要setMouseTracking(true)。
对于选择位置后的下棋需要鼠标点击才可以下棋,这里的捕捉鼠标并需要按下鼠标才选择,所以并不需要setMouseTracking(true)。
对于最后执棋方最后落子位置采用全局的lastx和lasty来标记,采用Qt绘画时间在对应棋子中心画出红色十字。
学习参考:(1)https://blog.csdn.net/weixin_39788534/article/details/79496905
(2)https://blog.csdn.net/qq_19727693/article/details/105694194
2.2 AI模式下minmax及alphabet剪枝搜索算法设计
设计AI模式采用的是极大极小和剪枝算法,由于棋盘为15行15列,运算量巨大,这里采用了剪枝算法减少计算量。在待搜索队列地设计上,首先排除周围一颗棋子都没有的位置,再对敌方最后落子位置周围的位置插入搜素队列头部(他们周围是最可能我方落子地位置),来尽可能地剪枝。
此外,对于棋局局势的评估采用了启发式的搜索算法,如对于“活三”,“活四”等给出不同的评价,并根据我方得分减去对手得分来评估该落子位置。而且可以根据调整敌方得分及我方得分地比例,将AI设置为进攻型或者防守型。
评估模型如下(1代表棋子位置,0为空):
核心算法设计:minmax及剪枝搜索:
//负值极大算法搜索 alpha + beta剪枝, 合并极大节点和极小节点两种情况, 减少代码量
//在一盘棋局中, 若到棋手A走棋, alpha 相当于棋手A得到的最好的值, 对于棋手A的值, 从对手的角度看就要取负值.
int Chess::alpha_beta(int player, int h, int alpha, int beta)
//h搜索深度,player=1表示电脑,player=0表示人类
{
if (vec1.begin() != vec1.end() && vec2.begin() != vec2.