源代码

GitHub上:Github livingsu/Gobang-ai:极大极小搜索和α-β剪枝

引言

alphaGo击败围棋冠军李世石的新闻让我对棋类博弈产生了浓厚的兴趣,无奈本人不会围棋,但算是一个五子棋业余爱好者,于是乎希望通过实现一个五子棋ai来了解相关算法和知识。

五子棋在英文中又称Gobang,five-in-row,还有两个称呼:gomoku和renju(连珠)。我来简要介绍一下区别。由于五子棋已经被机器严格证明了是一种“不公平”的游戏,先手黑子是绝对占优的,并且先手有必胜的套路。由于先手必胜,必须对先手进行一定的规则限制,于是就出现了“禁手”一说,即某些位置(比如能形成双活3、活3冲4)黑子不能下,不然就算黑子输。在日本,五子棋的理论得到极大发展,有禁手规则的五子棋被称为“连珠”(renju),而一般无禁手规则的叫做gomoku。由于大部分普通人下五子棋只是图一个乐趣,并不需要深入研究其中的理论规则,所以反而是gomoku在学生之间非常流行(我高二时就经常和同学玩五子棋,了解了一些套路但不深入)。

我实现的五子棋ai是无禁手规则的(考虑到有禁手的太复杂。。),标准棋盘大小为1515,规则是黑子先下*,由于黑子占据优势,我一般是人执黑子,ai执白子。之前说过黑子绝对占优且有必胜套路,所以实现的无禁手规则的ai执后手时,如果人用必胜套路,ai肯定会输。但是我们业余玩家不用考虑这些,我的目的是想实现一个能打败大部分执先手普通人的ai。所以,如果你能战胜按照我的博客实现的ai,也不用太过惊讶。

实现的效果图如下所示。
双人(玩家)模式:

人机(ai)模式:

界面设计

qt的界面设计非常方便。widget类是开始的欢迎界面,有两个按钮来选择玩家模式或者ai模式。gameWidget类用来绘制棋盘、棋子、分数等,并需要对鼠标事件进行相应以便落子。由于我写的ai需要反复查看棋盘信息,所以我把棋盘放在了chessAi类里面作为public成员,gameWidget可以通过访问ai.chesses来访问棋子信息并进行绘制。

重要效果的实现:
1.在棋盘内时屏蔽鼠标光标,鼠标在某个可以落子的位置附近时,在那个位置上显示一个有颜色(哪一方)的小正方形表示光标,鼠标在某个不可以落子的位置附近时显示禁止光标。

gameWidget类中有成员:

    int cursorRow;//光标位置int cursorCol;

然后重写鼠标移动函数:

void gameWidget::mouseMoveEvent(QMouseEvent *event){if(event->x()>=5&&event->x()<=455&&event->y()>=5&&event->y()<=455){//5=20-15,455=20+14*30+15setCursor(Qt::BlankCursor);for(int i=0;i<15;++i)for(int j=0;j<15;++j){float x=event->x(),y=event->y();//判断鼠标落在哪一个点附近(正方形范围)if((x>=(chessboard[i][j].x()-15))&&(x<(chessboard[i][j].x()+15))&&(y>=(chessboard[i][j].y()-15))&&(y<(chessboard[i][j].y()+15))){cursorRow=j;cursorCol=i;if(ai.chesses[cursorRow][cursorCol]!=C_NONE)setCursor(Qt::ForbiddenCursor);//展示图标坐标QString str="坐标:";str+=QString::number(j);str+=",";str+=QString::number(i);if(turn==T_BLACK)ui->lb_black_position->setText(str);else ui->lb_white_position->setText(str);break;}}}else setCursor(Qt::ArrowCursor);update();
}

解释一下,棋盘左上点位置为(20,20),棋盘每格长度为30。判断鼠标落在哪个位置附近用一个正方形区域(边长也为30)去判断。设置鼠标光标用setCursor()就可以了。

有一个问题要注意:监视鼠标移动函数是默认关闭的,要鼠标点击一下才开启,为了避免这个问题,只需要在gameWidget的构造函数中添加setMouseTracking(true)。

    setMouseTracking(true);//不用点击鼠标也一直追踪

2.由于玩家和ai都要下棋,模拟走一步棋可以用一个函数oneChessMove()来写:

void gameWidget::oneChessMove(int row, int col){if(turn==T_BLACK){turn=T_WHITE;ai.chesses[row][col]=C_BLACK;}else{turn=T_BLACK;ai.chesses[row][col]=C_WHITE;}gameResult result=ai.evaluate(ai.chesses).result;QMessageBox msg;msg.setIcon(QMessageBox::Critical);msg.setStandardButtons(QMessageBox::Yes);if(result!=R_DRAW){status=FINISH;if(result==R_BLACK){msg.setText("黑棋赢");score_black++;}else {msg.setText("白棋赢");score_write++;}msg.exec();ui->lcd_black->display(score_black);ui->lcd_write->display(score_write);}else if(isDeadGame()){status=FINISH;msg.setText("平局");msg.exec();}update();
}

3.玩家落子的位置获取:
重写鼠标释放函数:

void gameWidget::mouseReleaseEvent(QMouseEvent *event){if(mode==PLAYER){if(chessOneByPlayer()){if(status==FINISH)initializeGame();}}else{if(chessOneByPlayer()){if(status==UNDERWAY){chessOneByAi();if(status==FINISH)initializeGame();}else initializeGame();}}
}

其中chessOneByPlayer()用当前的cursorRow和cursorCol来走一步棋。

bool gameWidget::chessOneByPlayer(){if(ai.chesses[cursorRow][cursorCol]==C_NONE){oneChessMove(cursorRow,cursorCol);return true;}return false;
}

结束

简单实现了界面,但还没实现胜负判断和ai。我将胜负判断放到了ai的评估函数中实现。

下一篇:五子棋ai:极大极小搜索和α-β剪枝算法的思想和实现(qt和c++)(二)贪心算法和评估函数

五子棋ai:极大极小搜索和α-β剪枝算法的思想和实现(qt和c++)(一)引言和界面设计相关推荐

  1. atitit 方便搜索的文档文章结构框架.docx 目录 1.1. 三种搜索模式 tree hash关键词模式 关联搜索,对应的三种索引 1 1.2. 好的标题规范与副标题 1 1.3. Tr

    atitit 方便搜索的文档文章结构框架.docx 目录 1.1. 三种搜索模式  tree  hash关键词模式  关联搜索,对应的三种索引 1 1.2. 好的标题规范与副标题 1 1.3. Tre ...

  2. 五子棋ai:极大极小搜索和α-β剪枝算法的思想和实现(qt和c++)(四)算杀模块的简单实现

    一.什么是算杀?为什么要算杀? 算杀就是只算杀棋. 我用五子棋ai跟别人下了一阵子之后发现,用博弈树看6层深度(模拟ai走4步,模拟人走3步)其实根本不够,因为真正的高手看到的远比6层要多.高手进行谋 ...

  3. 经典运动估计算法之全搜索、三步搜索、四步搜索、菱形搜索

    全搜索算法 三步搜索算法 四步搜索算法 菱形搜索算法 由于搜索方法的不同,因此有多种运动估计算法,较为经典的运动估计搜索算法有全搜索法.三步搜索法.菱形搜索法以及四步搜索法等等.以下是几种运动估计搜索 ...

  4. 经典数据挖掘算法(介绍了包括18大数据挖掘在内的多种经典数据挖掘算法)

    前言 文章标题的两个概念也许对于许多同学们来说都相对比较陌生,都比较偏向于于理论方面的知识,但是这个算法非常的强大,在很多方面都会存在他的影子.2个概念,1个维特比算法,1个隐马尔可夫模型.你很难想象 ...

  5. (只此一篇便绝b能懂的)五子棋AI算法原理,博弈树、极大极小搜索、αβ剪枝

    我在最近撰写五子棋AI程序设计报告时,翻阅了很多的资料博客,但却发现大佬们的博客,没有一篇是能让我只看它就能理解全部的AI算法.在看了众多博客后,我终于对博弈树.极大极小搜索.αβ剪枝恍然大悟,其实这 ...

  6. 五子棋AI算法第三篇-Alpha Beta剪枝

    剪枝是必须的 五子棋AI教程第二版发布啦,地址:https://github.com/lihongxun945/myblog/labels/%E4%BA%94%E5%AD%90%E6%A3%8BAI% ...

  7. alpha-beta剪枝五子棋c语言,五子棋AI算法第三篇-Alpha Beta剪枝

    剪枝是必须的 上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义. 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250 ...

  8. python博弈树_博弈树alpha-beta剪枝搜索的五子棋AI

    最近机器学习很火, 乘着这把火,我也学习了一把,但是没有直接学习深度学习,而是遵从一位老前辈,一定要把人工智能的所有方法都了解掌握了,才能真正的掌握人工智能... 我只能说, 路漫漫.. 对于博弈类人 ...

  9. python博弈树_GitHub - xxttmmk/gobang_AI: 基于博弈树α-β剪枝搜索的五子棋AI

    最近机器学习很火, 乘着这把火,我也学习了一把,但是没有直接学习深度学习,而是遵从一位老前辈,一定要把人工智能的所有方法都了解掌握了,才能真正的掌握人工智能... 我只能说, 路漫漫.. 对于博弈类人 ...

最新文章

  1. php加载不了图片不显示,图片显示不出来,但是数据库里有显示
  2. Eclipse安装反编译插件
  3. 异常信息配置文件已被另一个程序更改_抢先目睹:SpringBoot2.4配置文件加载机制大变化
  4. 流式细胞凋亡检测实验常见问题解析
  5. Angular8 - 稳定版修改概述(Angular 8的新特性介绍)
  6. 听说用 C# 写 TensorFlow 更高效?
  7. 判断输入的日期字符串是否小于当前日期
  8. oracle数据库中could not get next sequence value的解决
  9. java程序设计_Java程序设计--接口interface(笔记)
  10. butterfly配置 hexo_Hexo博客之butterfly主题优雅魔改系列(持续更新)
  11. ubuntu-浏览caj文件
  12. 淘宝主播榜单丨2月22日-2月28日淘宝直播榜单
  13. 场地预约小程序解决方案
  14. pgsql:添加注释与查询注释
  15. 基于树莓派和LD3320模块的语音识别控制
  16. java高德地图api
  17. 针对CSS说一说|技术点评
  18. CODEVS1214
  19. 基于SSM+SpringBoot+MySQL+Bootstrap的OA在线办公自动化管理系统
  20. win7优化设置_Win7旗舰版系统磁盘碎片整理程序几种打开方法

热门文章

  1. Notion-数据导入
  2. 华为OJ平台——将真分数分解为埃及分数
  3. python实现图数据结构_Python描述数据结构之图实战篇
  4. spi遵循_我今天将遵循样式指南
  5. 手牵手教你使用ngComponentOutlet创建一个支持自定义插入子组件的angular公共搜索表单组件
  6. macOS终端字体颜色DIY教程
  7. 测试linux写文件系统,Linux系统性能测试工具(九)——文件系统的读写性能测试工具之iozone...
  8. 使用Modulated Convolutions修改 StarGAN V2
  9. 02.Python网络爬虫第二弹(http和https协议)
  10. java计算机毕业设计乐勤网书店源码+系统+mysql数据库+lw文档