五指棋人机大战之ai篇
话说之前把ui篇说了,接下来就是整个游戏的核心部分了。
废话不多说,完成AI部分总共有几个难点
1. 计算机如何落子
2. 判断胜负
在阐述代码之前,先上流程图。备注一下:玩家先手(黑子) 电脑白子
总流程图:
具体步骤:
步骤一:初始化工作
1 用一个三维数组来存放五子棋的所有赢法
2 用两个数组来存放玩家的赢法总数,一个存放计算机的赢法总数
这里理解起来是比较难的,先放代码
![](/assets/blank.gif)
![](/assets/blank.gif)
var count = 0 ;// 赢法数组的索引// 横线赢法 for(var i = 0;i < 15;i++){for(var j = 0;j < 11;j++){for(var k = 0;k < 5;k++){wins[i][j+k][count] = true}count ++;} }// 竖线赢法 for(var i = 0;i < 15;i++){for(var j = 0;j < 11;j++){for(var k = 0;k < 5;k++){wins[j+k][i][count] = true}count ++;} }// 斜线赢法 左上右下 for(var i = 0;i < 11;i++){for(var j = 0;j < 11;j++){for(var k = 0;k < 5;k++){wins[i+k][j+k][count] = true}count ++;} } // 斜线赢法 左下右上 for(var i = 0;i <11 ;i++){for(var j = 14;j > 3;j--){for(var k = 0;k < 5;k++){wins[i+k][j-k][count] = true}count ++;} }console.log(count)// 初始化统计数组 for(var i = 0;i < count;i++){myWin[i] = 0computerWin[i] = 0 }
View Code
这里赢法数组部分理解可能有问题,我用左右方向举例说明
// 横线赢法for(var i = 0;i < 15;i++){ for(var j = 0;j < 11;j++){ for(var k = 0;k < 5;k++){ wins[i][j+k][count] = true } count ++; }}
i 表示当前行,j表示当前的行的每个棋子,为什么j的最大值是10呢,要连成5颗才能赢。枚举法说明
这样,刚好把每一行的每个棋子在这行上的横向赢的总数统计了,其他方向一样
步骤二:在棋盘上点击,画棋子的主要工作
1 . 判断游戏是否结束
2. 计算机落子
判断游戏是否结束:
画完棋子之后(当前是玩家),循环遍历赢法数组,如果在这个点的wins[i][j][k] == true,玩家myWins[k] ++ ,计算机在在该点上就没有赢的可能了,把computerWin[k]置为一个无效值,当myWin[k] == 5的时候,说明玩家赢了。
这里详细解释一下:
我们在之前统计赢法的时候,对于每一种赢法都对应五个点,而myWins[]数组又是与wins[]数组对应的,每存在一个点使得wins[][][k]=true时,让myWins[k]的值加1,当myWins[k]=5时,说明已经有五颗棋子连成一起了。
那还有问题,会不会出现黑白棋子一起连成5颗的时候就myWins[k]等于5呢?不会,因为在点击的时候就已经判断当前是黑棋还是白棋了。只有是玩家的情况才画棋子。如果之前没有进行判断则会出现这种情况。
![](/assets/blank.gif)
![](/assets/blank.gif)
// 画棋子// 没有棋子才能落子if(chessBoardArr[i][j] == 0){oneStep(i,j,me)chessBoardArr[i][j] = 1for(var k = 0; k < count;k++){if(wins[i][j][k]){myWin[k] ++;computerWin[k] = 6;if(myWin[k] == 5){alert('你赢了!')over = true}}}if(!over){me = !me;computerAI()}}
View Code
如果还没结束,就到计算机落子了,另一个难点又来了。
计算机落棋规则:找到棋盘上没有落子的棋格,并分别计算玩家和计算机在该点上的分值并与当前的最高分进行比较,计算机在比较之后的最高分的棋格落子。
首先:我们需要使用两个二维数组来分别存放玩家和计算机在棋盘上每一格的分数,max来存放当前所有的最高分,u、v存放当前最高分的坐标
![](/assets/blank.gif)
![](/assets/blank.gif)
// 得分数组var myScore = []var computerScore = []var max = 0 //用来保存最高分var u = 0,v = 0 ;//用来保存最高分的坐标for(var i = 0;i < 15;i++){myScore[i] = []computerScore[i] = []for(var j = 0;j < 15;j++){myScore[i][j] = 0computerScore[i][j] = 0}}
View Code
其次:遍历棋盘上没有棋子的每一格,并对该格遍历赢法数组,判断在该格上落子是否有价值。分两种情况:分别统计玩家和计算机在该点上第k种赢法的当前连子数,连子数越高,分数也就越高。
对该棋格统计完分数之后,分别把玩家和计算机在该棋格上的分数和最高分进行比较:
A. 玩家
1. myScore[i][j]>max ,那我们认为这个点是最好的,把最高分重置为当前玩家在这个点的分数,最高分的坐标也改成这个点的坐标。
2. myScore[i][j] == max , 如果计算机在该点上的分数大于计算机在最高分这个点的分数,那我们也认为这个点比较好,更新最大分数的值和坐标
B 计算机
和玩家的情况是一样的。
不过这里需要注意一点,因为当前是计算机,还需要对玩家进行一个阻碍,所以在连子数累加分的时候可以设置比玩家连子数累加分高一些。
接下来:遍历完整个棋盘之后,画棋子,并且判断是否结束(判断逻辑跟玩家的一样)
![](/assets/blank.gif)
![](/assets/blank.gif)
// 遍历棋盘for(var i = 0;i < 15;i++){for(var j = 0;j < 15;j++){if(chessBoardArr[i][j] == 0){ // 如果没有棋子// 循环比遍历赢法数组,判断在这个点落子有价值for(var k = 0;k < count;k++){if(wins[i][j][k]){// 分值计算if(myWin[k] == 1){myScore[i][j] += 200}else if(myWin[k] == 2){myScore[i][j] += 400}else if(myWin[k] == 3){myScore[i][j] += 2000}else if(myWin[k] == 4){myScore[i][j] += 10000}//电脑if(computerWin[k] == 1){computerScore[i][j] += 220}else if(computerWin[k] == 2){computerScore[i][j] += 420}else if(computerWin[k] == 3){computerScore[i][j] += 2100}else if(computerWin[k] == 4){computerScore[i][j] += 20000}}} // 遍历赢法数组 eif(myScore[i][j] > max){max = myScore[i][j]u = iv = j}else if(myScore[i][j] == max){if(computerScore[i][j] > computerScore[u][v]){u = iv = j}}if(computerScore[i][j] > max){max = computerScore[i][j]u = iv = j}else if(computerScore[i][j] == max){if(myScore[i][j] > myScore[u][v]){u = iv = j}}}}} // 循环遍历 棋盘 e oneStep(u,v,false)chessBoardArr[u][v] = 2for(var k = 0; k < count;k++){if(wins[u][v][k]){computerWin[k] ++;myWin[k] = 6;if(computerWin[k] == 5){alert('电脑赢了!')over = true}}}if(!over){me = !me;}
View Code
最后:要么结束,要么继续博弈
说到这里,整个五指棋-人机大战算是完成了,其中逻辑部分个人感觉还是有点绕的,在网上看了很多五指棋逻辑的资料,分为VCF和VCT,这个版本应该算VCF吧。还待继续研究。
上面有些地方可能说的不恰当,希望大神指正,也希望有兴趣的小伙伴多多分享交流。
运行效果:http://hjjia.github.io/js_exercises/demo-chess/
转载于:https://www.cnblogs.com/i-jia/p/5348190.html
五指棋人机大战之ai篇相关推荐
- 四子棋 java_java智能四子棋人机大战游戏设计(附项目,以及原创PSD,设计文档)...
本项目是使用java技术+自创"假设下子"算法开发的人机大战四子棋游戏客户端. 具体项目,以及原创PSD,设计文档,在文件末尾的百度云连接. 一. 小组说明: 组名:CST 组长: ...
- java--五子棋人机大战--课程设计
南京中医药大学 <Java 程序设计>课程设计 2020-2021 学年 二 学期 日期: 2021 年 5 月 30 日 人工智能与信息技术学院 项目名称: 五子棋 南京中医药大学 2 ...
- 李世石宣布退役,高呼AI不可战胜:将举行史上首次让子人机大战
那个被 AlphaGo 击败的人类围棋世界冠军李世石,在韩国宣布退役了. 机器之心报道,参与:泽南.蛋酱. 提到前围棋世界冠军.韩国棋手李世石,人们的认知可能大多是「他是第一个被 DeepMind 人 ...
- 哥们哥们,人机大战晓得吧玩家对战晓得吧,简易三子棋,呕心沥血500行代码手把手带你制作第一个小游戏,可以保存收藏以后接着看哟,最后有源码哦
目录 前言 一.游戏想要有意思,函数不可少,整活的函数 二.三子棋的游戏界面 三.三子棋的功能步骤分析 1.菜单 2.三子棋实现的总体框架 3.棋盘创建 4.棋盘初始 ...
- AI一分钟 | AI溃败,Dota2人机大战首场终结;阿里公布第一财季财报,净利76.50亿元...
▌AI 溃败,Dota2 最强人机大战首场终结 8 月 24 日早间,OpenAI 的人工智能在 DOTA2 国际邀请赛(Dota 2 at The International)中输给了人类职业玩家. ...
- C语言人机大战之决战三子棋之巅
文章目录 C语言人机大战之三子棋 一.游戏规则 二.游戏实现 (1)游戏界面 (2)游戏ing 初始化棋盘 打印棋盘 玩家落子 电脑落子 判断输赢 棋盘满否 三.代码总结 (1)game.h (2)t ...
- 五子棋输赢算法php,js实现AI五子棋人机大战
本文实例为大家分享了js实现AI五子棋人机大战的具体代码,供大家参考,具体内容如下 实现原理就是计算五子棋所有赢的种类,利用canvas实现五子棋排版落子. 五子棋 #canvas{ display: ...
- 【C语言五子棋、三子棋人机对战篇的详细介绍】
C语言--五子棋.井字棋人机对"战" 针对 "[C语言实现五子棋.三子棋人机对战,包含电脑人工智能对战(可攻可守)](非标题党)" 的详细介绍 五子棋.三子棋人 ...
- 450位骨科医生迎来“人机大战”,不敌阿里云AI系统
昨天上午(5月11日),中国医师协会骨科医师分会年会在杭举办,一场骨科人工智能研讨会吸引骨科医生前来对战.450名骨科医生对战骨科AI智能阅片,AI得90分,略高于医生综合得分. 去年12月,为响应国 ...
最新文章
- 助你进大厂,这些Mysql索引底层知识你是必须知道的。
- java集成groovy
- 网页实现凭证金额分割线_一位整理过5000个网页书签的大神分享:实用的书签管理方案...
- 1079 Total Sales of Supply Chain(甲级)
- 第二章:React 面向组件编程
- requests有意思的proxies参数-何时使用代理有效
- Oracle索引树的结构
- JSP中的include的两种用法
- c语言输出合法的出栈算法,c语言栈的实现以及操作
- Oracle执行计划使用分析SQL执行效率
- 为什么证券投资是世界上最难成功的行业
- 用计算机代码模拟基因,一种通过计算机程序模拟产生简化DNA甲基化测序数据的方法与流程...
- 彻底关闭WINDOWS默认共享的4种方法
- Spring Boot 实现通用 Auth 认证的 4 种方式!
- 金三银四已过,为大家整理一批高频java面试题,花点耐心看完,offer拿到手软!
- win10设置锁屏密码_【Win10 技巧】把手机当成电脑一对一专属密匙,人机分离自动锁屏...
- Linux服务器CPU使用率过高
- Android自定义视频播放器(三)
- 从零开始学架构 01-架构基础【笔记】
- 天津高一计算机会考,09天津高中计算机会考复习.doc
热门文章
- 【计算机网络相关】内网穿透介绍以及使用FRP实现内网穿透Windows远程桌面
- DPARSF关键字含义
- 算法笔记4.5.2二分扩展:凸多边形的外接圆之最大半径
- Spring注入:配置注入(set注入和构造器注入)与注解注入
- 直播泡沫?3.5万亿红人经济的未来在这几个字里
- 关于电脑特别卡的解决方法.(管用, 真的)
- java计算机毕业设计BS高校教师考勤系统源码+mysql数据库+系统+lw文档+部署
- windows下安装wafw00f
- lzma和gzip压缩命令简介
- 最小堆的魅力!思路清晰求解「至少需要多少间会议室」