100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > scratch五子棋人机对战

scratch五子棋人机对战

时间:2021-10-21 15:57:03

相关推荐

scratch五子棋人机对战

扫描关注微信公众号获取更多内容

今天跟大家分享下scratch五子棋的程序,五子棋我们都玩过,当黑子或者白子横、竖、斜连成五子,游戏就结束啦。想要把五子棋的规则完全实现出来还是很不容易的。

那在做之前,我们先梳理下思路:

1.棋盘背景——横、竖线相隔单位保持一致

2.黑子(人)——跟随鼠标,且中心落点在黑线的交叉点

3.白子(电脑)——自主判断落点,且中心落点在黑线的交叉点上

看起来似乎比较简单,但是还有很多隐藏的问题(至关重要)

比如:

1.一个交叉点只能落一子

2.不能在棋盘外落子

3.电脑的AI

4.判断胜负的条件

今天我们就来解决棋盘背景和落子的问题。

棋盘的背景可以通过画笔的方式绘制

我们可以把棋盘看成是由竖线和横线组成,且每条线相隔的距离也相同,假设这个距离为20个像素点。

那么可以先找到一个合适的位置(-200,-160),向上移动画一条黑线,然后移动到(-200,-160),将坐标x增加20后,再画条黑线,重复此过程,通过控制循环的次数控制线的数量,横线也是一样,只需要改成向右画线,且每次y变化20,就可以了

竖线

横线

接下来我们要解决的问题是:

1.黑子跟随鼠标移动,点击鼠标落子

2.每次落子要正好在交叉点的中间

我们新建一个黑子角色,调整为合适大小(半径小于10个像素点),且黑子的位置如下图所示:

这有这样才能保证 运行时,鼠标指针正对黑子的圆心。当点击鼠标后,落子,盖章。这样就能实现跟随鼠标移动,点击落子的功能了

最后要解决落子要在交叉点中间的关键就是,当鼠标指针在交叉点附近时(红圆里任意位置),点击鼠标,黑子不会直接盖章,而是黑子圆心会移动到交叉点上再去盖章。

根据之前绘图时的坐标可以发现,交叉点的X或Y坐标都是20的整数倍,且红色圆圈半径为10。那我们可以把它看成一个数学问题。

假设交叉点坐标为(X,Y),鼠标的坐标可能是(X+a,Y+b),且-10<a<10,-10<b<10,用鼠标的坐标除以20后得到的数字四舍五入后,再乘20就是交叉点的坐标。

比如,假设交叉点(40,80),鼠标指针为(43,82),按照上述公式计算可以得到最后的落点就是交叉点。

要讲的内容是:

如何保证交叉点不重复落子

如何保证不会在棋盘外落子

如何判定胜负

先解决第一个问题‘不重复落子’,都知道每个交叉点有一个独一无二的(X,Y),为了保证不重复落子,也就是交叉点的(X,Y)只能使用一次,在落子前,就需要判断列表内是否存在交叉点的(X,Y)。如果有,那么不盖章(不落子)。如果没有则盖章(落子),并且将交叉点的(X,Y)存储到列表中。

这里有个问题大家可以思考下,为什么需要用逗号连接坐标,不用逗号,直接连接行不行?

第一个问题解决了,接下来解决第二个问题,如何保证不会在棋盘外落子。这个问题的关键就是找到棋盘内和棋盘外的区别,也就是坐标范围的不同,棋盘的坐标范围:-210<X<110,-170<Y<150(思考为什么不是-200<X<100,-160<Y<140),所以只要落子的X和Y在此范围内那么一定是在棋盘内。

注意此时的逻辑关系是“与”

黑旗的落子程序为:

黑旗的落子视频:

接下来最为关键的就是如何判定胜负,判定胜负的方法有很多比如列表,在这里给大家提供一种新的思路,假设你和三岁的小朋友下五子棋,小朋友会怎么去判定胜负呢?

他会用手指指到黑子,然后看手指往上看有没有黑子,如果有则继续往上,重复直到上面没有黑子为止。紧接回到最开始的黑子上,然后看手指往下看有没有黑子,如果有则继续往下,重复直到下面没有黑子。在这个过程中每数到黑子就计数加1。这样就将一条竖线上的黑子的数量计算出来了。

用程序实现就是:新建一个角色(大小不能超过黑子),控制它像小朋友的手指一样数连着的黑子数量,用来检测是否胜利。问题:为什么大小不能超过黑子?

当黑子落下盖章后,并发出消息表示可以开始检测了

变量黑和表示黑子的连接数,检测是否胜利的程序如下:

这样就可以判定竖直方向上黑子的最大数,同理也可以用这种方式检测横、斜的黑子的最大数(换方向检测后,黑和需重新设为0)。我们只需要将检测横、斜方向(更改X Y的坐标)的程序写在下面就可以了,一旦黑和等于6时则黑子胜利。

问题:1.为什么从最后落子的位置开始检测?

2.为什么黑和需重新设为0?

3.为什么判断胜负的条件是等于6而不是等于5?

这篇推送是五子棋的最后一篇啦,主要是进行讲解白子的AI。

这里给大家分享一个简单策略,就是让白子以防守为主。所谓防守就是在黑子数量最多的位置去下白子,也就是下图所示的黑子左侧或右侧。

但是假设黑子已经连成四颗了,且左侧或者右侧已经有一颗白子了,那么白子就需要下在另外一侧。所以白子防守的思路就是:先找到黑子数目最多的一条线,判断判断其左侧或者右侧是否有白子,根据情况下到对应的位置。

也就是现在需要解决的问题是:

1.如何找到黑子连成数目最多的位置

2.需要存储该位置左右两侧的坐标

3.判断左右两侧有无被白子占用

第一个问题其实我们在上期推送已经说明了(点此看第二期内容),变量黑和最大的时候就是黑子连成数目最多的时候

那么如何找到最大值,以及最大值对应的左右/上下坐标,又是多少呢?可以将检测角色在移动过程中没有碰到黑子的位置坐标存储到列表中,并且同时将变量黑和也存到新的列表中。不断重复此过程,直到最后,在从列表里找到黑和最大值,并以此找到黑和最大时对应的两个坐标。

由上图程序我们可以看出,假设列表(黑和最大值)的序号为N,列表M(白旗坐标)为2N-1和2N。也就是只要找到列表(黑和最大值)里面最大数字对应的序号,就可以找到白子的的坐标。

如上图所示,在列表黑和最大值中,让索引项不断的和其他项进行比较,如果出现其他项较大时,则让索引项变成较大的项,再继续和其他项进行比较,直到结束,这样最后索引项就是最大值了

所以接下来的思路就是:

1.判断此时白子的两个坐标是否在棋盘外

2.判断此时白子的两个坐标是否有被占用

3.白子落子后,判断白子有无胜利

4.同时发出消息切换造型变成黑子的主动权。

上面的类容前面两篇都讲过了这里就不在重复了。大家可以发送消息“五子棋”获得程序,当然为了鼓励大家能自己思考,这里的程序还差上面的 1到4步,相信大家在看过这几篇推文后一定能自己做出来。有任何问题可以留言问我哦。

扫码关注卫星公众号

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。