我正在编写我的第一个完整程序,已经进行了两周的编程,但遇到了我似乎无法弄清楚的障碍。我正在制作一个 connect 4 游戏,并首先在 JavaScript 中构建逻辑,然后再推送到 DOM。我开始使用构造函数创建的单元对象来制作它,然后将其以二维数组的形式推送到游戏对象中。我已经成功创建了一个函数,每次都能播放,并使用 2 天的数组更改该列最低点的单元格的值。但是,我不确定如何让我的胜利检查功能运行。
到目前为止,我的逻辑是,对于二维数组中的每个点,您可以按行、按列和对角线进行检查。我理解如何检查胜利的逻辑,但我不明白如何按行和列遍历数组。在下面的示例中,this.cellsArray 是 Board 构造函数中的单元对象数组。该阵列有 7 个列阵列,每个阵列有 6 行,因为我翻转了典型的行列逻辑以考虑 Connect Four 基于列的性质。但是我无法像 this.cellsArray[col][row] 一样访问数组,因为 col 和 row 没有定义,而且我不确定如何定义索引值?任何帮助将不胜感激!
示例:
//array location is equal to an instance of this.cellsArray[col][row]
Board.prototype.checkRowRight = function (arrayLocation) {
if ((arrayLocation[i+1][i].value === arrayLocation.value) && (arrayLocation[i+2][i]=== arrayLocation.value) && (arrayLocation[i+3][i].value === arraylocation.value)){
this.winner = this.currentPlayer;
this.winnerFound = true;
console.log('Winner has been found!')
}
};
参考我在here找到的逻辑并重构获胜线检测代码,可以轻松地将其转换为Javascript,如下所示:
function chkLine(a,b,c,d) {
// Check first cell non-zero and all cells match
return ((a != 0) && (a ==b) && (a == c) && (a == d));
}
function chkWinner(bd) {
// Check down
for (r = 0; r < 3; r++)
for (c = 0; c < 7; c++)
if (chkLine(bd[r][c], bd[r+1][c], bd[r+2][c], bd[r+3][c]))
return bd[r][c];
// Check right
for (r = 0; r < 6; r++)
for (c = 0; c < 4; c++)
if (chkLine(bd[r][c], bd[r][c+1], bd[r][c+2], bd[r][c+3]))
return bd[r][c];
// Check down-right
for (r = 0; r < 3; r++)
for (c = 0; c < 4; c++)
if (chkLine(bd[r][c], bd[r+1][c+1], bd[r+2][c+2], bd[r+3][c+3]))
return bd[r][c];
// Check down-left
for (r = 3; r < 6; r++)
for (c = 0; c < 4; c++)
if (chkLine(bd[r][c], bd[r-1][c+1], bd[r-2][c+2], bd[r-3][c+3]))
return bd[r][c];
return 0;
}
还有一个测试电话:
x =[ [0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 1, 2, 2, 2, 0],
[0, 1, 2, 2, 1, 2, 0] ];
alert(chkWinner(x));
当用棋盘调用时,
chkWinner
函数将返回第一个(也是唯一的,假设每次移动仅更改一个单元格并且您在每次移动后检查)获胜玩家。
这个想法基本上是将检查限制在有意义的范围内。例如,当检查右侧的单元格时(参见第二个循环),您只需检查从最左边四列中的每一列开始的每一行
0-6
。那是因为从其他任何地方开始都会在找到可能的胜利之前偏离棋盘的右侧。换句话说,列集
0-3
、
{0,1,2,3}
、{1,2,3,4}
和 {2,3,4,5}
有效,但 {3,4,5,6}
无效(七个有效列是 {4,5,6,7}
)。我通过使用矩阵加法解决了这个问题。
假设您的游戏板作为 2D 数组存储在内存中,如下所示:
0-6
在每个“硬币掉落”中,您应该调用一个传递硬币的 x/y 位置的函数。
这是您计算用户赢得游戏的天气的地方
[ [0, 0, 0, 0, 0, 0, 0],
[0, 0, Y, 0, 0, 0, 0],
[0, 0, Y, 0, 0, 0, 0],
[0, 0, R, 0, 0, 0, 0],
[0, 0, Y, 0, 0, 0, 0],
[0, 0, R, R, R, 0, 0] ];
注意:矩阵符号中的“南”是
let directionsMatrix = {
vertical: { south: [1, 0], north: [-1, 0] },
horizontal: { east: [0, 1], west: [0, -1] },
backward: { southEast: [1, 1], northWest: [-1, -1] },
forward: { southWest: [1, -1], northEast: [-1, 1] },
};
,意思是“向下 1 个单元格,向右 0 个单元格”
现在我们可以循环遍历每个轴/方向来检查是否有 4 个连续。[1,0]
如果您想查看完整代码,这里有一个指向github 存储库现场演示