游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)

提到井字棋,想必大家都不陌生,就是两个玩家轮流在一个井字型的 9 宫格里画 x 和 o,当某一方的棋子连成了一条线(横向,竖向和对角线),那么该方获胜,如果格子被填满也没有人成功连线,则平局。这次我们来学习如何用 micro:bit 实现一个井字棋小游戏。

通过 「图形化编程」Micro:bit 井字棋游戏(一) 我们实现了光标移动,A B 玩家轮流下棋的逻辑,通过 「图形化编程」Micro:bit 井字棋游戏(二) 我们学习了处理异常情况,比如当前光标位置已经有棋子了,显示一个 X,不让玩家再在当前位置下棋,当棋盘满了没有玩家获胜就显示一个 “Draw Game” 表示平局,这节教程我们将会实现井字棋游戏剩下的部分,判断输赢,这节教程会稍微难一些,涉及到一个简单的算法来算输赢,我会用一些图形来解释原理方便理解,不要被算法两个字吓到,没那么难啦,如果实现的过程中碰到什么问题可以在我的公众号给我留言,让我们开始吧

什么是算法

算法,英文名是 Algorithm,表示的是为了解决特定问题的一组指令的集合,一个算法通常会有五个特征。

  1. 有限性(Finiteness):一个算法必须保证执行有限步之后结束。
  2. 确切性(Definiteness): 一个算法的每一步骤必须有确切的定义。
  3. 输入(Input):一个算法有零个或多个输入,以表示运算对象的初始情况,所谓零个输入是指算法本身给定了初始条件。
  4. 输出(Output):一个算法有一个或多个输出。没有输出的算法毫无意义。
  5. 可行性(Effectiveness): 一个算法的任何计算步骤都是可以被分解为基本可执行的操作,每个操作都能够在有限时间内完成。

对于井字棋游戏来说,输入就是当前棋盘上棋子的坐标,输出就是有没有一方胜出或平局。

如何计算井字棋的输赢

井字棋的输赢判定有很多种不同的算法,这里我选了一种比较好理解的,我叫它计分法。井字棋的赢棋情况一共有 8 种,横竖各 3 条线加 2 个对角线,来看下面的图:

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(1)

搭配这张坐标图,得到 8 种情况每种对应的 3 个棋子坐标如下

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(2)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(3)

具体算法是

  1. 初始化一个有 8 个元素的数组,每个元素都是 0
  2. 在每次落子时,判断落子的 x 坐标和 y 坐标符合上面哪条规律,给对应数组元素编号(数组元素是从0开始的,还记得吗)的数字加 1 或者减 1,这里规定 如果是玩家 A 下的棋,则 加 1,如果是玩家 B 下的棋,则减 1,需要注意的是上面的规则可能会同时满足,比如 (4,4) 同时满足 3、6、7 这 3条规则
  3. 遍历这个数组,如果有其中一个数字是 3 或者 -3,就表明有玩家胜出了,如果为 3 则玩家 A 胜出,如果是 -3 则为玩家 B 胜出
  4. 如果下到 9 个格子都满了也没有胜出,那就平局,平局的逻辑 上节教程 已经处理过啦。

之所以叫计分法,是指当有一方玩家落子之后,给对应的胜负情况计 1 分或计 -1 分,最后判断只要有一方先到 3 分或者 -3 分则胜出,是不是没有那么难呀。

举个例子(如果聪明的你已经理解了,那么就可以跳过下面的例子解释,直接看实现部分啦)

1.玩家 A 在棋盘中间走了一步,即 (2,2),符合编号 2、5、7,则给数组元素编号为 1、4、6的元素分别加 1

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(4)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(5)


2.玩家 B 走了右上角 (4,0),符合编号 3、4、8,则给数组元素 2、3、7 分别减 1

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(6)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(7)


3.玩家 A 走了第一行中间 (2,0),符合编号 2、4,给元素 1、3 加 1

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(8)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(9)


4.玩家 B 封堵,走了下面中间 (2,4),符合 2、6,给元素 1、5 减 1

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(10)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(11)


5.玩家 A 另辟蹊径下在左上角 (0,0),符合 1、4、7,给元素 0、3、6 加 1

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(12)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(13)


6.玩家 B 发现破绽逆转局势,下在右下角 (4,4),符合 3、6、7,给元素 2、5、6 减 1

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(14)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(15)


7.玩家 A 尽力封堵,但为时已晚,下在右边中间 (4,2),符合 3、5,给元素 2、4 加 1

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(16)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(17)


8.玩家 B 下在 (0,4),符合 1、6、8,给元素 0、5、7 减 1,元素 5 为 -3,即符合编号为 6 的胜出条件,获胜

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(18)


游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(19)


你也可以自己画一个井字格和一个数组推导一下整个过程,有助于理解这个算法,如果有不清楚的地方可以给我留言。下面我们来实现这个算法。

代码实现

首先打开 makecode(https://makecode.microbit.org/) 网站,载入 「图形化编程」Micro:bit 井字棋游戏(二)已经做好的部分,如果你还没有来得及看上节教程,可以在 GitHub - ZhengkunWang/Microbit_Tutorial 下载上节教程已经做好的 hex 文件,然后接着实现

当开机时

  1. 创建一个变量,命名为 jifenliebiao
  2. 设置 jifenliebiao 为 空数组
  3. 从 循环 分类下拖入一个 重复 x 次 模块,把 x 改为 8
  4. 从 数组 分类下拖入一个 将值 x 添加到结尾 模块 到循环体中,把 变量改为 jifenliebiao,把 x 改为 0,意思是 添加 8 个 0 到 jifenliebiao 里

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(20)

修改 luozi 函数

  1. 创建一个新变量,命名为 fenshu
  2. 如果 Axiaqi 为 true,则设置 fenshu 为 1
  3. 否则 设置 fenshu 为 -1
  4. 添加一个新的函数,命名为 jifen,我们会在下面实现它
  5. 在 调用 jianchashengfu 之前调用 jifen 函数

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(21)

计分函数

这里我们需要一个新的函数,用于计分,计分规则上面已经讲过了,一共 8 个规则,我们分别实现这 8 条规则

  1. 创建一个新变量,命名为 x,设置值为 dangqianbu 的 x 坐标
  2. 创建一个新变量,命名为 y,设置值为 dangqianbu 的 y 坐标
  3. 如果 x 为 0,则 将数组 jifenliebiao 中索引 0 的值设置为 从数组 jifenliebiao 中取得索引 0 的值 加上 fenshu,即符合编号 1 的规则,给编号 1 对应的 数组元素 0 计 1 分或 -1 分
  4. 同样的,实现编号 2 的规则,如果 x 为 2,则 将数组 jifenliebiao 中索引 1 的值设置为 从数组 jifenliebiao 中取得索引 1 的值 加上 fenshu,这里有个小技巧,可以在代码区选中 上一步实现的 如果 x 为 0模块,按一下 ctrl c 复制,然后再 ctrl v 粘贴,然后修改一下相应的数字就可以快速实现剩下的规则了
  5. 实现编号 3 的规则,如果 x 为 4,则 将数组 jifenliebiao 中索引 2 的值设置为 从数组 jifenliebiao 中取得索引 2 的值 加上 fenshu
  6. 实现编号 4 的规则,如果 y 为 0,则 将数组 jifenliebiao 中索引 3 的值设置为 从数组 jifenliebiao 中取得索引 3 的值 加上 fenshu
  7. 实现编号 5 的规则,如果 y 为 2,则 将数组 jifenliebiao 中索引 4 的值设置为 从数组 jifenliebiao 中取得索引 4 的值 加上 fenshu
  8. 实现编号 6 的规则,如果 y 为 4,则 将数组 jifenliebiao 中索引 5 的值设置为 从数组 jifenliebiao 中取得索引 5 的值 加上 fenshu
  9. 实现编号 7 的规则,如果 x 等于 y,则 将数组 jifenliebiao 中索引 6 的值设置为 从数组 jifenliebiao 中取得索引 6 的值 加上 fenshu
  10. 实现编号 8 的规则,如果 x y 为 4,则 将数组 jifenliebiao 中索引 7 的值设置为 从数组 jifenliebiao 中取得索引 7 的值 加上 fenshu

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(22)

检查胜负函数

最后一步,修改检查胜负函数,我们需要检查 jifenliebiao 数组里有没有一个元素为 3 或者 -3,如果有一个元素为 3,代表 A 赢了,如果为 -3,代表 B 赢了,如果都没有,就走原来的逻辑,判断棋盘是不是满了,如果满了就平局,如果没满就什么也不做,因为棋还没有分出胜负

  1. 新建一个变量,命名为 fen,这是个用于访问 jifenliebiao 的变量
  2. 从 循环 分类下 拖一个 将数组 x 中的元素逐个取出,以 fen 引用每次取出的值,意思是把 jifenliebiao 中的元素一个一个取出,并把元素的值赋值给变量 fen,然后执行循环体
  3. 判断 如果 fen 为 3,显示字符串 A Win,游戏结束
  4. 判断 如果 fen 为 -3,显示字符串 B Win,游戏结束

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(23)

到这里就完成整个井字棋游戏啦,快和你的小伙伴一起下井字棋吧,这里也要给自己鼓鼓掌呦,因为你已经实现了第一个算法,棒棒哒

完整程序图

游戏自走棋ai战斗算法机制(图形化编程Micro:bit井字棋游戏)(24)

Hex 文件

这篇教程的 Hex 文件可以在 GitHub - ZhengkunWang/Microbit_Tutorial 下载

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页