1. 棋盘和棋子的绘制。
先创建一个15 * 15的二维数组,通过对数组的两层遍历,创建出一个 15 * 15 的表格,这样棋盘就有了。用数组来绘制棋盘的好处是便于查找和筛选。每一个td都对应着一个空对象,下棋的时候通过给这个对象添加一个 num 的属性,num 为 1 时,就渲染成黑色,2 就渲染成白色,再稍微调整一下 css 样式,这样棋盘和棋子就绘制好了。每一个 td 都有自己的自定义属性 x 和 y,类似于坐标,这样就可以很方便的把 td 标签和数组里对应的值联系起来。下面是 css 代码
2. 轮流下棋的点击事件
下棋的逻辑很简单,就是点击棋盘的时候,给点击的td对应的那个对象添加一个num属性,黑棋就是1,白棋就是2,然后渲染出来就可以了。下棋顺序可以通过一个全局变量flag来控制,同时声明两个全局数组,用来存放所有的黑棋和白棋。后面判断胜负时,要对这两个数组先进行遍历。
3.获胜条件判断
接下来就是写获胜条件了。我分成了 4 种情况,横轴,数轴,正斜轴和反斜轴。这 4 种情况逻辑和方法大致都是相同的,就是里面的数据有些细微差别。
3.1 横轴获胜
以横轴为例,如何判断获胜,先判断是黑棋还是白棋,然后遍历对应的数组。已黑棋为例,遍历之后把y值相同的黑棋筛选出来都放入一个数组中,也就是同一行的黑棋。接着比较这一行的这些黑棋的x值,如果有5个连续的x值,则说明横轴上有5个连续的黑棋,就可以判断获胜了。怎么比较这些x值呢,我的做法是先将他们用sort()方法排序,接着从小到大依次比较。建一个新数组,第二个值等于第一个值加1,就把他们扔到这个新数组中,如果出现某个值不连续了,就将这个数组清空,这样通过判断这个数组的长度,就能判断胜负了。
3.2 数轴获胜
竖轴和横轴代码基本上也相同
只是换了个条件,把 if (item[0] == td.dataset.y) 换成了 if (item[1] == td.dataset.x),意思就是选出这一列所有的棋子。后面的逻辑和代码就和横轴一样了。
3.3 正斜轴获胜
斜轴困难一点的地方就是,怎么筛选出这一条斜线上的所有棋子。
只要能把这条斜线上的棋子给找出来,后面的逻辑判断就都一样了。所有的斜线都是 45 度角,也就是说斜线上的任意两个棋子,他们的x值之差于y值之差是相等的。这样的话,判断起来就简单了。if ((item[0] - td.dataset.y) == (item[1] - td.dataset.x))
这样就可以了。斜线上的棋子找出来后,后面的步骤就都一样了,复制粘贴即可。
3.4 反斜轴获胜
反斜轴同理,条件改成 if (0 - (item[0] - td.dataset.y) == (item[1] - td.dataset.x)),其余的复制粘贴。
把这些函数放到下棋事件里面调用,整个功能就完成了。
4. 悔棋功能
最后写一下悔棋功能,点击悔棋,把对应数组里面的数据删除,然后重新渲染棋盘就完事了。
总结
整个代码写下来,都是些 js 的基本语法,几个数组的方法来回用,希望能给 js 初学者一些帮助。