![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/2dc2727264f62ff5.png)
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/00424cb7e3607358.png)
比如,假设交叉点(40,80),鼠标指针为(43,82),按照上述公式计算可以得到最后的落点就是交叉点。
要讲的内容是:
如何保证交叉点不重复落子
如何保证不会在棋盘外落子
如何判定胜负
先解决第一个问题‘不重复落子’,都知道每个交叉点有一个独一无二的(X,Y),为了保证不重复落子,也就是交叉点的(X,Y)只能使用一次,在落子前,就需要判断列表内是否存在交叉点的(X,Y)。如果有,那么不盖章(不落子)。如果没有则盖章(落子),并且将交叉点的(X,Y)存储到列表中。
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/c7c60a4ca24dde54.png)
这里有个问题大家可以思考下,为什么需要用逗号连接坐标,不用逗号,直接连接行不行?
第一个问题解决了,接下来解决第二个问题,如何保证不会在棋盘外落子。这个问题的关键就是找到棋盘内和棋盘外的区别,也就是坐标范围的不同,棋盘的坐标范围:-210<X<110 , -170<Y<150(思考为什么不是-200<X<100 , -160<Y<140) ,所以只要落子的X和Y在此范围内那么一定是在棋盘内。
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/7c19b67d6566e84f.png)
注意此时的逻辑关系是“与”
黑旗的落子程序为:
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/b330c1a1f696de04.png)
黑旗的落子视频:
接下来最为关键的就是如何判定胜负,判定胜负的方法有很多比如列表,在这里给大家提供一种新的思路,假设你和三岁的小朋友下五子棋,小朋友会怎么去判定胜负呢?
他会用手指指到黑子,然后看手指往上看有没有黑子,如果有则继续往上,重复直到上面没有黑子为止。紧接回到最开始的黑子上,然后看手指往下看有没有黑子,如果有则继续往下,重复直到下面没有黑子。在这个过程中每数到黑子就计数加1。这样就将一条竖线上的黑子的数量计算出来了。
用程序实现就是:新建一个角色(大小不能超过黑子),控制它像小朋友的手指一样数连着的黑子数量,用来检测是否胜利。问题:为什么大小不能超过黑子?
当黑子落下盖章后,并发出消息表示可以开始检测了
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/415255a7978c0fe9.png)
变量黑和表示黑子的连接数,检测是否胜利的程序如下:
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/ffb5cb66683a5437.png)
这样就可以判定竖直方向上黑子的最大数,同理也可以用这种方式检测横、斜的黑子的最大数(换方向检测后,黑和需重新设为0)。我们只需要将检测横、斜方向(更改X Y的坐标)的程序写在下面就可以了,一旦黑和等于6时则黑子胜利。
问题:1.为什么从最后落子的位置开始检测?
2.为什么黑和需重新设为0?
3.为什么判断胜负的条件是等于6而不是等于5?
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/5a1605612ada46e3.png)
这篇推送是五子棋的最后一篇啦,主要是进行讲解白子的AI。
这里给大家分享一个简单策略,就是让白子以防守为主。所谓防守就是在黑子数量最多的位置去下白子,也就是下图所示的黑子左侧或右侧。
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/697dabc73077147f.png)
但是假设黑子已经连成四颗了,且左侧或者右侧已经有一颗白子了,那么白子就需要下在另外一侧。所以白子防守的思路就是:先找到黑子数目最多的一条线,判断判断其左侧或者右侧是否有白子,根据情况下到对应的位置。
也就是现在需要解决的问题是:
1.如何找到黑子连成数目最多的位置
2.需要存储该位置左右两侧的坐标
3.判断左右两侧有无被白子占用
第一个问题其实我们在上期推送已经说明了(点此看第二期内容),变量黑和最大的时候就是黑子连成数目最多的时候
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/ffb5cb66683a5437.png)
那么如何找到最大值,以及最大值对应的左右/上下坐标,又是多少呢?可以将检测角色在移动过程中没有碰到黑子的位置坐标存储到列表中,并且同时将变量黑和也存到新的列表中。不断重复此过程,直到最后,在从列表里找到黑和最大值,并以此找到黑和最大时对应的两个坐标。
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/90dd0fd1baa65c71.png)
由上图程序我们可以看出,假设列表(黑和最大值)的序号为N,列表M(白旗坐标)为2N-1和2N。也就是只要找到列表(黑和最大值)里面最大数字对应的序号,就可以找到白子的的坐标。
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/41bad7f2f3b4ab93.png)
如上图所示,在列表黑和最大值中,让索引项不断的和其他项进行比较,如果出现其他项较大时,则让索引项变成较大的项,再继续和其他项进行比较,直到结束,这样最后索引项就是最大值了
所以接下来的思路就是:
1.判断此时白子的两个坐标是否在棋盘外
2.判断此时白子的两个坐标是否有被占用
3.白子落子后,判断白子有无胜利
4.同时发出消息切换造型变成黑子的主动权。
上面的类容前面两篇都讲过了这里就不在重复了。大家可以发送消息“五子棋”获得程序,当然为了鼓励大家能自己思考,这里的程序还差上面的 1到4步,相信大家在看过这几篇推文后一定能自己做出来。有任何问题可以留言问我哦。
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/ca183ff08fce342d.png)
扫码关注卫星公众号![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/5d831b3eb43d8820.png)
![《scratch五子棋人机对战》](https://img8.php1.cn/3cdc5/128ca/b64/7b40c708c4605fd4.png)