先贴出第一步代码
1234567var wins = [];for(let i=0 ; i < 15 ; i++ ) {wins[i] = [];for(let j = 0; j<15; j++) {wins[i][j] = [];}}这段代码仅仅只是创了一个准备用于记录所有赢法的三维空数组。
- 接下来第二部就是建立赢法数组,复制并建立索引。
代码:竖排123456789var count = 0;for(let i=0; i< 15 ;i++) {for(let j=0;j<11 ;j++) {for(let k=0;k<5;k++) {wins[i][j+k][count] = true;}count++;}}
本段代码的含义就是遍历了所有竖排列中存在的赢的组合,count为每一种赢法所对应的唯一索引。
例如:
12345 wins[0][0][0] = true;wins[0][1][0] = true;wins[0][2][0] = true;wins[0][3][0] = true;wins[0][4][0] = true;就是意味着我们将第一竖排前五个空格连成一线的赢法都列举出来,并给每一个格子赋值为true、给出的索引为count = 0(即第三维数组)。
同理,很容易可以写出遍历横排,45°角和135°角排列上的代码:
横排
45°
135°
相较于较为抽象的描述,还是图来的简单明了。
输赢判断
慕课网将其称为赢法统计,我总觉得过于抽象了。让我来理解,说是输赢判断,或者说是迈向胜利的进度,更加容易理解。
代码:
首相遍历count,两方胜利进度数组都赋值为0。
然后就要修改落子时的onclick事件的判定条件。
前面的代码是UI篇当中的。关于输赢判断,思路是在onclick事件下,每次落子,遍历count,并对落子坐标i,j所对应的赢法k胜利进度+1,胜利进度=5的时候,就代表在这一赢法下获胜了。
例如,在wins[0][0][k]的情况下,其实只有三种赢法,即向右五格,向下五格以及45°角五格,因此,当k不等于这三种赢法的索引时,myWins[k]就不会自加,即该赢法进度没有变化。PS:后面要做computer自动下子,所以这里只写了黑子的判定。
AI实现
代码:
很复杂的代码。通过遍历坐标,确定包含这个坐标的赢法,然后对这个赢法进行权重加成,赢法内拥有越多的黑子,权重越大。同时,对自己下子的每个坐标所对应的的赢法也进行加权,并且电脑获胜是的权重是高于人的。(这里很难用自己的话描述出来)。
以图为例:
当黑子落点为坐标[0][0]时,此时应当是有三个方向上,即横、竖、45°,三个赢法数组存在。并且所对应的元素均为true。黑子落点后,上面代码中的第一次循环因为if(hasCheer[0][0])为false,跳过,三种赢法内空余的格子都进入循环,每种myWin[k]都是一,所以横、竖、45°线上其他空格的分数均为200,因此第一次循环获取到坐标i=0,j=之后,后面的因为都与它相等不会获得更高权重,所以AI会落子在0,1处。
完整代码
|
|