冯地龙
五子棋大家都玩过,双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。五子棋起源于中国,还是全国智力运动会竞技项目之一。由于规则简单,老少皆宜,而且趣味横生,引人入胜(图1)。
今天跟大家分享怎么用Scratch制作五子棋游戏。想要把五子棋的规则完全用Scratch编程实现还是不容易的。在编写程序之前,我们先梳理一下思路,程序需要实现以下目标:
①绘制棋盘
②限制光标移动
③实现落子功能
④判断棋盘状态
⑤判断五子连珠
⑥实现人机对下
2021年第3期我们曾经介绍过用Scratch制作五子棋,当时实现了绘制棋盘和黑白交替落子功能,也就是完成了前3项功能,后面几项没能实现。现在我们的编程能力已经提高了,本文将能实现前5项功能,完成五子相连的胜负判断。由于前3项功能已经介绍过,本文只提示一下要点,重点还是在于判断棋盘状态和判断五子连珠。至于实现人机对下涉及算法策略,我们以后再来实现。
1.用一个角色隐藏绘制棋盘。
2.为了方便计算,起点坐标值取整数(XY轴方向分别为-150、150)。重复绘制16条横线和竖线,每条长度300。
3.绘制XY方向的间距为20(也就是步长)。
4.用画笔功能完成绘制15×15的棋盘。
参考代码如图2:
1.创建新的角色“光标”,用来提示当前操作者,含有两个造型(黑色光标造型编码为1;白色光标造型编码为2),光标角色稍大于五子棋(因五子棋在光标内落子)。
2.利用逻辑与配合棋盘大小的坐标值把光标控制在棋盘内跟随鼠标指针移动。
3.根据光标跟随鼠标的坐标值可以计算出在棋盘的行数和列数,储存在新建变量的“行数Y”和变量“列数X”中。“行数Y”是因为Y值不同则行数不同,同理两个棋子的X值不同Y值一样则两个棋子在同一行,有相同的“行数Y”。
4.通过计算,把变量“行数Y”和“列数X”计算出来的舞台坐标值分别赋值到鼠标XY轴坐标上,同时设为当前坐标,这样我们就可以把角色固定在棋盘XY两轴相交点上。
5.棋盘大小是15×15,行数和列数相交点也就是225个。
6.通过变量“行数Y”和变量“列数X”中的计算得出光标在棋盘内X、Y(行列相交的点)新的坐标值,赋值在新建变量ID上。(ID相当于在棋盘行列相交点的每一个坐标。每一个相交点都有一个对应的ID值。)
参考代码如图3:
1.创建角色五子棋,棋的造型为两个,黑色棋1和白色棋2(对应光标造型的颜色)。
2.在光标角色里通过按下鼠标成立与不成立的逻辑,按下就广播新建消息落子,切换下一个造型,如果没有按下鼠标就一直等待。落子代码在图3中。
3.当角色五子棋接收到落子的消息,换成光标的造型编码,移动到角色光标的位置盖上图章(实现落子功能)。如图4。
1.新建“棋盘状态”列表,这是15×15=225项的列表。将0加入状态(空状态)(图5)。
2.通过在光标角色里按下鼠标成立与不成立的逻辑,嵌套条件判断如果列表的ID项等于0(也就是空状态,没有棋子),广播消息落子,并把造型的编号赋值在列表棋盘状态的ID项(造型编号两个,也就赋值1的状态,1就是黑棋),下一个造型。
3.如果列表的ID项不等于0(状态两种,0是空状态,1代表黑子和2代表白子),有棋子状态的情况不能广播落子消息,无动作。等待光标移动到棋盘是0的ID项才能实现按下鼠标条件成立并广播落子的消息。具体代码请参考图3。落子之后列表对应效果如图6。
1.判断五子连珠首先要知道五子棋的连珠规则,以最近一个棋子落下为原点,横竖斜等八个方向有5颗同色棋子连成一条线代表此方胜利。
2.创建绘制新的角色“判断”。鼠标在棋盘内移动,注意行列的变量,你会发现方向变化的规律,总结出往八个方向每走一格数据的变化:
正方向,向上走X增加0、Y增加1;斜上走X增加1、 Y增加1;右走X增加1、Y增加0;斜下走X增加1、Y减少1(如图7)。
反方向走的规律变化类似,只是根据方向变成负数,变量“列数X”和“行数Y”增加负1。
3.新建变量“判断列数X”和“判断行数Y”,并把变量“列数X”和“行数Y”赋值给这两个变量上,用于判断五子连珠。
4.自定义函数积木“判断连珠XYK”,参数XY表示纵横坐标,K为系数用作正反方向。
原理:变量“列数X”和“行数Y”分别赋值到对应“判断列数X”和“判断行数Y”;然后开始判断,将“判断列数X”和“判断行数Y”增加“判断连珠”函数里的X和Y的值乘以系数K(正数1和负数1),这样可以将8个方向都试一遍。
先判断落子在棋盘内,在行数与列数是-1到15之间。
如果棋盘状态的ID项等于当前的造型编号(1或2)时,将变量计数增加1,重复4次,如果等于棋盘状态的1或者2时,表示旁边有同色的棋子,就按这个方向继续去检测,如果可以重复4次就表示五子连珠了,否则就停止这个脚本(如图8)。
5. 在角色光标里,按下鼠标成立,广播新建消息判断方向消息,当判断角色接收到判断方向消息后把自定义函数积木判断连珠方向值传送一遍。
6. 自定义函数积木方向,把判断连珠函数里面的系数K正反值输入进去,将变量检测设为1,如果变量计数的值检测到大于4,且光标的造型編码等于1,黑棋赢,等于2白棋赢(如图9)。
到这里,我们的五子棋游戏也就成功了。其实五子棋的难点在于思路,判断逻辑要明确清楚,涉及的数学知识比较广泛,比如参数K就是向量知识。根据鼠标的指针坐标计算变量行数Y,变量列数X以及变量ID。你需要充分理解自定义积木里面参数之间的关系,判断胜负的条件等。
这里我们只用五子连珠来判断胜负,真实比赛中为了平衡先手的优势还会对黑棋规定“禁手”。如三三禁手(两个以上的活三)、四四禁手、长连禁手。黑方禁手形成时,白方应立即指出。若白方在之后继续落子,则禁手失效。黑方出现禁手,无论是自愿下或被迫下,均判负。黑方五连与禁手同时形成,判黑方胜。
最后给大家留一个问题,在目前的五子棋游戏中是属于双人对战,如果把一方改为自动(机器AI)落子实现人机大战呢?好了,这个问题就交给下一篇文章了。我们一起动脑思考一下吧。