基于博弈树的开源五子棋AI教程[1 位棋盘]

0 引子

常见的五子棋棋盘大小为15x15,最直观的表示就是一个二维数据。本文为了易于拓展一开始使用的是QVector<QVector>的数据,但是在分支因子为10的情况下只能搜索到4层左右,后面深度加深,搜索时间呈指数倍数增长。这种实现方式下,六层搜索深度下搜索时间大于1min。
接着使用二维数组(int[][])来表示一个搜索状态,搜索速度略有加快,时间大约在2倍左右(记忆模糊了)。
目前实现方式中使用的位棋盘,这样可以有效的减少寻址时间,取出一行或者一列只需要从内存中取出一个int32(考虑到17x17或者19x19)。有些读者可能想问一个格子有三种状态(黑/白/空),bool又能如何表示呢?答案就是使用两个int32数组表示,一个数组表示是否有子,另一个表示黑子还是白子。

1 15X15棋盘

1 定义

一般而言一组二维数组就可以充分的表示棋盘信息,但是在后续棋盘静态评估的需求中发现,本文需要对棋盘的四个方向上评估出基础棋型。因而从不同角度冗余的描述棋盘信息就是必要的。

//棋子值的定义[保证0 1为黑子或者白子]
#define PLAYER_BLACK 0
#define PLAYER_WHITE 1
#define PLAYER_NONE  2
//四方向
#define MMainDiagonal 0 //主对角线
#define MSubDiagonal  1 //副对角线
#define MHorizontal   2 //水平
#define MVertical     3 //竖直

这里也简单给出棋盘信息完备表示,为了简化搜索过程的的边界处理,对所有棋盘加墙(白棋搜索时,墙就是黑子)。对角线上只保留了可以构成连五的线。

    //定义含有边界所有连线上的棋子,用于更新棋型int searchBoard[boardSize+2];int searchBoardMask[boardSize+2];int searchBoardVertical[boardSize+2];int searchBoardVerticalMask[boardSize+2];int searchBoardMainDiag[2*boardSize - 9];int searchBoardMainDiagMask[2*boardSize - 9];int searchBoardSubDiag[2*boardSize - 9];int searchBoardSubDiagMask[2*boardSize - 9];

2 实现

有了棋盘信息的表示,就需要实现如何更新棋盘信息。这里实现可能略微复杂,没有做代码的精简。在象棋百科中有通过棋盘旋转的方式来获取不同方向的信息,那里是使用通过和一个魔法数位运算来实现的,理论上这里也是可以的。
这里具体实现时需要注意三点:一是边界点的判定,二是位运算如何某数位置0或者置1,,三是位移量的求解。

void GameBoard::setSearchBoardPiece(const MPoint &position, MPlayerType player)
{int row = position.x();int col = position.y();if(!isValidSearchPosition(row,col)) return ;if(player == PLAYER_WHITE){//player == white(1)searchBoard[row] |= (1 << col);searchBoardMask[row] |= (1 << col);searchBoardVertical[col] |= (1 << row);searchBoardVerticalMask[col] |= (1<<row);//主对角线[右下]if(abs(col-row)<=boardSize-5){if(row>col){searchBoardMainDiag[boardSize- 5 - row + col] |=(1 << col);searchBoardMainDiagMask[boardSize- 5 - row + col] |=(1 << col);}else{searchBoardMainDiag[boardSize- 5 + col - row] |= (1 << row);searchBoardMainDiagMask[boardSize- 5 + col - row] |= (1 << row);}}//副对角线[右上]if(row+col>=6 && row+col<= boardSize*2-4){if(col < boardSize -row  + 1){searchBoardSubDiag[row + col - 6] |= (1 << col);searchBoardSubDiagMask[row + col - 6] |= (1 << col);}else{searchBoardSubDiag[row+col-6] |= (1 << (boardSize+1-row));searchBoardSubDiagMask[row+col-6] |= (1 << (boardSize+1-row));}}}else if(player == PLAYER_BLACK){//player == black(0)searchBoard[row] &= ~(1 << col);searchBoardMask[row] |= (1 << col);searchBoardVertical[col] &= ~(1 << row);searchBoardVerticalMask[col] |= (1<<row);//主对角线if(abs(col-row)<=boardSize-5){if(row>col){searchBoardMainDiag[boardSize- 5 - row + col] &= ~(1 << col);searchBoardMainDiagMask[boardSize- 5 - row + col] |=(1 << col);}else{searchBoardMainDiag[boardSize- 5 + col - row] &= ~(1 << row);searchBoardMainDiagMask[boardSize- 5 + col - row] |= (1 << row);}}//副对角线if(row+col>=6){if(col < boardSize -row  + 1){searchBoardSubDiag[row + col - 6] &= ~(1 << col);searchBoardSubDiagMask[row + col - 6] |= (1 << col);}else{searchBoardSubDiag[row+col-6] &= ~(1 << (boardSize+1-row));searchBoardSubDiagMask[row+col-6] |= (1 << (boardSize+1-row));}}}else{//player==none(2)searchBoardMask[row] &= ~(1 << col);searchBoardVerticalMask[col] &= ~(1 << row);searchBoard[row] &= ~(1 << col);searchBoardVertical[col] &= ~(1 << row);//主对角线if(abs(col-row)<=10){if(row>col){searchBoardMainDiagMask[boardSize- 5 - row + col] &= ~(1 << col);searchBoardMainDiag[boardSize- 5 - row + col] &= ~(1 << col);}else{searchBoardMainDiagMask[boardSize- 5 + col - row] &= ~(1 << row);searchBoardMainDiag[boardSize- 5 + col - row] &= ~(1 << row);}}//副对角线if(row+col>=6){if(col < boardSize -row  + 1){searchBoardSubDiagMask[row + col - 6] &= ~(1 << col);searchBoardSubDiag[row + col - 6] &= ~(1 << col);}else{searchBoardSubDiagMask[row+col-6] &= ~(1 << (boardSize+1-row));searchBoardSubDiag[row+col-6] &= ~(1 << (boardSize+1-row));}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/235148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python中的复数

复数一般表示为abi(a、b为有理数)&#xff0c;在python中i被挪着它用&#xff0c;虚数单位是不区分大小写的J。 (笔记模板由python脚本于2023年12月19日 18:58:39创建&#xff0c;本篇笔记适合认识复数的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https:/…

Just Laws -- 中华人民共和国法律文库,简单便捷的打开方式

链接&#xff1a;JustLaws | Home 一个简洁便捷的中华人民共和国法律文库&#xff0c;而且收录比较完善&#xff0c;都是平常网民可能用到比较多的法律知识&#xff0c;目前包括宪法及宪法相关法、民商法、行政法、经济法、社会法、刑法和程序法等等 页面以文档的风格展示每一…

vue打包内存问题解决办法<--- Last few GCs ---><--- JS stacktrace --->

**<— Last few GCs —> [18484:0000026763669610] 106760 ms: Mark-sweep 4016.0 <— JS stacktrace —> FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory** 解决办法&#xff1a; set NODE_OPTION…

设计模式(三)-结构型模式(3)-装饰模式

一、为何需要装饰模式&#xff08;Decorator&#xff09;? 在软件设计中&#xff0c;某个对象会组合很多不同的功能&#xff0c;如果把所有功能都写在这个对象所在的类里&#xff0c;该类会包含很多复杂的代码逻辑&#xff0c;导致代码不美观且难以维护。于是就有了再定义一些…

Pytest自动化测试 - 必知必会的一些插件

Pytest拥有丰富的插件架构&#xff0c;超过800个以上的外部插件和活跃的社区&#xff0c;在PyPI项目中以“ pytest- *”为标识。 本篇将列举github标星超过两百的一些插件进行实战演示。 插件库地址&#xff1a;http://plugincompat.herokuapp.com/ 1、pytest-html&#xff1…

【物联网无线通信技术】WiFi从理论到实践(ESP8266)

文章从理论基础到具体实现完整的介绍了最常见的物联网无线通信技术&#xff1a;WiFi。 文章首先介绍了WiFi这种无线通信技术的一些基本概念&#xff0c;并针对其使用的802.11协议的基本概念与其定义的无线通信连接建立过程进行了简单的介绍&#xff0c;然后对WiFi开发常常涉及的…

【强化学习】Deep Q Learning

Deep Q Learning 在前两篇文章中&#xff0c;我们发现RL模型的目标是基于观察空间 (observations) 和最大化奖励和 (maximumize sum rewards) 的。 如果我们能够拟合出一个函数 (function) 来解决上述问题&#xff0c;那就可以避免存储一个 (在Double Q-Learning中甚至是两个…

git的使用思维导图

源文件在github主页&#xff1a;study_collection/cpp学习/git at main stu-yzZ/study_collection (github.com)

Unity的UI界面——Text/Image

编辑UI界面时&#xff0c;要先切换到2d界面 &#xff08;3d项目的话&#xff09; 1.Text控件 Text控件的相关属性&#xff1a; Character:&#xff08;字符&#xff09; Font&#xff1a;字体 Font Style&#xff1a;字体样式 Font Size&#xff1a;字体大小 Line Spac…

华清远见嵌入式学习——ARM——作业1

要求&#xff1a; 代码&#xff1a; mov r0,#0 用于加mov r1,#1 初始值mov r2,#101 终止值loop: cmp r1,r2addne r0,r0,r1addne r1,r1,#1bne loop 效果&#xff1a;

用户管理第2节课--idea 2023.2 后端规整项目目录

目的&#xff1a;当项目文件多了之后&#xff0c;咱们也能够非常清晰的去找到代码的一个目录 一、项目规整了两大处 1.1 com.yupi.usercenter & resources 二、具体操作 com.daisy.usercenter 2.1 原版 & 鱼皮有出入&#xff0c;demos.web就不删除了 原因&#…

Aurora8B10B(二) 从手册和仿真学习Aurora8B10B

一. 简介 在上篇文章中&#xff0c;主要结合IP配置界面介绍了一下Aurora8B10B&#xff0c;这篇文章将结合文档来学习一下Aurora8B10B内部的一些细节 和 相关的时序吧。文档主要是参考的是这个 pg046-aurora-8b10b-en-us-11.1 二. Aurora8B10B内部细节 在手册上&#xff0c;对…

VR全景是什么?普通人该如何看待VR全景创业?

如果你还没有开始了解VR&#xff0c;那么不妨驻足几分钟细致的了解一下&#xff0c;你就会对VR全景行业有不一样的看法。VR全景与普通的平面图片和视频相比&#xff0c;具有更加丰富的视觉体验和交互性&#xff0c;基于真实场景的全景图像的虚拟现实技术&#xff0c;制作流程简…

Maven仓库上传jar和mvn命令汇总

目录 导入远程仓库 命令结构 命令解释 项目pom 输入执行 本地仓库导入 命令格式 命令解释 Maven命令汇总 mvn 参数 mvn常用命令 web项目相关命令 导入远程仓库 命令结构 mvn deploy:deploy-file -Dfilejar包完整名称 -DgroupIdpom文件中引用的groupId名 -Dartifa…

Ubuntu 常用命令之 apt-get 命令用法介绍

apt-get是Ubuntu系统下的一个命令行工具&#xff0c;用于处理包。这个命令可以自动下载和安装软件包及其依赖项。它是Advanced Packaging Tool (APT)的一部分&#xff0c;APT是处理包的高级工具&#xff0c;可以处理复杂的包关系&#xff0c;如依赖关系等。 apt-get命令的常见…

一个真正的软件测试从业人员必备技能有哪些?

协同开发能力&#xff1a; 1. 项目管理&#xff08;SVN、Git&#xff09; 2. 数据分析能力&#xff08;Fiddler、Charles、浏览器F12&#xff09;。 接口测试&#xff1a; 1. 概念及接口测试原理概念&#xff08;概念、接口测试原理&#xff09; 2. 接口测试工具&#xff…

数据工作者最爱的AI功能,你知道吗~

在工作中难以避免的一项任务就是各种数据总结和汇报&#xff0c;怎么分析总结&#xff1f;以何种形式汇报&#xff1f;都是具有一定的难点&#xff0c;所以我要推荐的就是具有AI图表解析功能的可视化工具——Easyv数字孪生低代码可视化平台。可实现对数据的可视化展示&#xff…

软件测试项目测试报告总结

测试计划概念&#xff1a;就在软件测试工作实施之前明确测试对象&#xff0c;并且通过资源、时间、风险、测试范围和预算等方面的综合分析和规划&#xff0c;保证有效的实施软件测试。 需求挖掘的6个方面&#xff1a; 1、输入方面 2、处理方面 3、结果输出方面 4、性能需求…

linux 驱动——杂项设备驱动

杂项设备驱动 在 linux 中&#xff0c;将无法归类的设备定义为杂项设备。 相对于字符设备来说&#xff0c;杂项设备的主设备号固定为 10&#xff0c;而字符设备不管是动态分配还是静态分配设备号&#xff0c;都会消耗一个主设备号&#xff0c;比较浪费主设备号。 杂项设备会自…

uml用例图是什么?有哪些要素?

UML用例图是什么&#xff1f; UML用例图&#xff08;Unified Modeling Language Use Case Diagram&#xff09;是一种用于描述系统功能和用户之间交互的图形化建模工具。它是UML的一部分&#xff0c;主要用于识别和表示系统中的各个用例&#xff08;用户需求或功能点&#…