本文是以Java语言进行讲解。最近抽空整理了一下代码,已经分享在:https://github.com/CuteReimu/gobang ,需要的可以自取。

之前说想写一些比较大型的算法,想了半天,还是觉得写五子棋的AI比较合适。一则因为自己研究过这个,有一些基础,二则尽管现在网上有很多五子棋AI算法的资料,但是确实都有些晦涩难懂。就想着借这个机会,凭自己的理解,尽量的讲通俗一些。然而,这个算法确实有些复杂,想要通俗一些需要较大的篇幅,一篇博客难以讲完,这里就分很多个章节,一点一点的深入探讨。为了让文章更加通俗一些,我会略去一部分很简单但是占用篇幅很长的代码,改为用几行注释说明。

框架的搭建

首先,我们计划是做一个五子棋AI,也就是说让玩家和这个AI对下。整个游戏的框架是这样的:

其中,棋盘是一个Object,存放当前的棋局情况,通知每个Player“轮到你下棋了”、“对方下了什么棋”、“游戏结束,XXX获胜”等消息,并且从每个Player那里获取他下了什么棋。两个Player分别是人类玩家和AI。Player的基类应该是一个interface,里面只有三个方法。人类玩家和AI是它的子类,分别实现这三个方法。

public interface Player {Point play();void display(Point p);void notifyWinner(int color);
}
public final class Point {public final int x;public final int y;public Point(int x, int y) {this.x = x;this.y = y;}@Overridepublic String toString() {return "(" + x + "," + y + ")";}
}

解释一下:

  • play 方法,告知“轮到你下棋了”,并且返回一个Point,也就是下一步下的棋。对于人类玩家,则就是阻塞,等待玩家在界面上选取一个点,并且将这个点的坐标返回。对于AI,则是直接开始用我们的AI算法进行计算,并返回计算结果。
  • void display(Point p) 方法,告知“对方下了什么棋”。对于人类玩家,则就是将对方下了的棋在界面上显示出来。对于AI,则是将对方下了的棋记在AI的缓存中,以便后续的计算。
  • void notifyWinner(int color) 方法,告知“游戏结束,XXX玩家赢了”。对于人类玩家,则就是在界面上展示谁赢了的文字及特效,并且从此之后再点击棋盘就不再有反应了。对于AI,则是通知AI不要再计算了。

当然了,如果打算连续下多盘棋,可能还需要一个reset方法,通知人类玩家和AI清空当前棋盘。当然了,这个和我们的算法关系不大就不列出来了。
然后,我们的interface Player需要两个实现类,分别叫做HumanPlayerRobotPlayer,这个RobotPlayerplay方法将是五子棋AI算法的核心内容,后面会花费大量篇幅进行讲解。
接下来就是我们的棋盘:

public abstract class Constant {public static int MAX_LEN = 15;
}
public class ChessBoard {private byte[][] board = new byte[Constant.MAX_LEN][Constant.MAX_LEN];private Player[] players = new Player[2];private int whoseTurn = 0;private int count = 0;private boolean isEnd = false;private boolean checkForWin(Point p) {/* 因为篇幅问题,此处省略十几行代码 *//* 这个函数就是在下完每一步棋时调用,只需要判断以这步棋若形成五连珠即可判定获胜 */return false;}public void play() {if (isEnd) return;Point p = players[whoseTurn].play(); //调用Player的play方法,获取下一步下的棋if (board[p.y][p.x] != 0) //严谨,以防万一throw new IllegalArgumentException(p.toString() + board[p.y][p.x]);board[p.y][p.x] = (byte) (whoseTurn + 1);System.out.println((whoseTurn == 0 ? "黑" : "白") + p.toString()); //打印日志if (++count == Constant.MAX_LEN * Constant.MAX_LEN) //严谨,如果棋盘下满了游戏结束isEnd = true;if (checkForWin(p)) //如果下了这步棋后赢了,游戏结束isEnd = true;whoseTurn = 1 - whoseTurn; //切换当前下棋的人players[whoseTurn].display(p); //调用Player的display方法,告知他对方下了哪步棋if (isEnd) { //如果下完这一步棋后有一方赢了,则调用Player的notifyWinner方法通知players[0].notifyWinner(2 - whoseTurn);players[1].notifyWinner(2 - whoseTurn);}}public static void main(String[] args) {ChessBoard b = new ChessBoard();b.players[0] = new HumanPlayer(1); //这里我从构造函数中传入了颜色,例如1表示执黑,2表示执白b.players[1] = new RobotPlayer(2);while (b.getWinner() == null) {b.play();}}
}

棋盘的代码确实很简单易懂,也做了很多注释,就不多介绍了。
接下来,就只剩下HumanPlayerRobotPlayer的实现了。

人类玩家

人类玩家无非就是实现三个方法:

  • play 方法,阻塞等待玩家点击棋盘上的一个点并返回这个点
  • display 方法,将AI下的棋展示在界面上
  • notifyWinner 方法,显示一行字“你赢(输)了”

这段代码与本文无关,就不贴出来了,我把我做的这个丑陋的界面贴出来展示一下,哈哈。

(不要吐槽我的界面,这不是重点。)

RobotPlayer

AI才是重点内容,涉及了大量的算法和数学知识,博弈树、评估函数、极大极小值搜索、启发式搜索、α-β剪枝等等,将会占用大量的篇幅。从下篇博客开始,将对此逐一展开。
五子棋AI算法(二)

五子棋AI算法(一)相关推荐

  1. java五子棋AI算法人机对战(春物彩羽版可下载试玩PC端)

    五子棋AI算法 前言: 坐标西安,写于疫情封城期间.改进了之前写的基于极大极小值策略AI五子棋游戏,是用java实现的,采用了java老旧的jframe窗体和绘图类.写好之后整理成了这篇博客. 游戏采 ...

  2. 基于博弈树的五子棋 AI 算法及其 C++ 实现

    基于博弈树的五子棋 AI 算法及其 C++ 实现 摘要 一   五子棋的游戏规则 二   五子棋对弈的算法描述 2.1 博弈树搜索算法 2.2 α ─ β 剪枝 2.3 估价函数 三   五子棋对弈的 ...

  3. 基于C++实现五子棋AI算法思想

    更多精彩,请点击上方蓝字关注我们! 今天我想要分享一下我做五子棋AI的思路.因为在做这个之前,我没有接触过任何像这种类似的东西.通过这一次,我也算是有所了解,我的思路也是来自很多网络上的博客,看了很多 ...

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

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

  5. 课程设计书五子棋AI算法及其实现

    五子棋AI,能根据棋盘局势判断棋子应落在何处获胜,主要算法有权值法和博弈树法两种实现方案. 权值法 在数理统计中,有一种名为蒙特卡洛法的方法常被使用,其主要内容为:根据事件出现的概率估计某些特征,并将 ...

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

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

  7. 五子棋AI算法第二篇-极大极小值搜索算法

    AI实现的基本思路-极大极小值搜索算法 五子棋AI教程第二版发布啦,地址:https://github.com/lihongxun945/myblog/labels/%E4%BA%94%E5%AD%9 ...

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

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

  9. 五子棋AI算法-Alpha Beta剪枝

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

  10. 五子棋算杀c语言,五子棋AI算法-算杀(示例代码)

    关于剪枝问题 前面讲到的通过Alpha-Beta剪枝和启发式搜索可以将4层搜索的平均时间降低到1秒以下.只有这两个优化方式其实目前最多可以做到6层搜索,就是把AI和玩家各向后推算三步. 6层搜索的棋力 ...

最新文章

  1. python爬虫小说代码示例-中文编程,用python编写小说网站爬虫
  2. 20180530更新
  3. Python基础教程:内置类型之比较
  4. pro缺点和不足 一加7t_2021年元旦有哪些一加手机值得购买?
  5. [转]C++中的三种继承public,protected,private
  6. 将Teams app升级到net6
  7. Codeforces Round #675 (Div. 2) F. Boring Queries 区间lcm + 主席树
  8. 趣文:程序员等级图鉴
  9. Android 系统(64)---Android中m、mm、mmm、mma、mmma的区别
  10. 无平行文本照样破解密码,CipherGAN有望提升机器翻译水平
  11. matlab 求积分上限,matlab求解积分上限
  12. vue实现滑块滑动校验
  13. 人工智能的认知技术,主要包含哪些?
  14. 热血仙境服务器修改,热血仙境安卓首发服务器爆红 - 07073手机游戏
  15. php七牛云,php七牛云
  16. Throttling
  17. 闲鱼月收入10万的案例分享
  18. Python使用numpy获取列表行数与列数
  19. 知识图谱技术发展详解(一)
  20. 红宝书读书笔记 第八章

热门文章

  1. php版ueditor配置_ThinkPHP配置UEditor
  2. 1500个前端开发常用JavaScript特效
  3. ListView的优化
  4. CommandName 与 CommandArgument
  5. AKKA:大数据下的并发编程模型
  6. 内蒙古工业大学2022年数据结构习题集
  7. java题库组卷系统_基于java的题库管理系统.doc
  8. c#开发的一套完整的题库管理系统
  9. wacom win10 未连接任何设备 驱动的问题 解决影拓3手绘板等老设备驱动无法在win10使用的问题
  10. 模型训练中batch_size的选择