以下是通俗易懂的解决方案,没有过多循环(只提供伪代码,如果需要更多解释,请告诉我):
我假设你的二维数组是这样运行的:
board = [
[...],
[...],
[...],
...
];
即,内部数组表示棋盘的水平行。
我还假设该数组由“b”、“w”和“x”填充,分别表示黑子、白子和空方块。
我的解决方案有点分而治之,所以我将其分成了以下3种情况。请耐心等待,它可能比仅运行多个嵌套循环更复杂,但是概念易于理解、阅读,并且通过正确的方法,编码相当简单。
水平线
首先,让我们考虑仅在线条水平时检测获胜情况的情况——这是最简单的情况。首先,使用类似于board[0].join("")
的方法将一行连接成一个字符串。对每一行都这样做。你最终得到一个像这样的数组:
rows = [
"bxwwwbx...",
"xxxwbxx...",
"wwbbbbx...",
...
]
现在加入这个数组,但在元素之间插入“x”以分隔每一行:
rows.join("x")
。
现在你有一个表示棋盘的长字符串,只需要应用正则表达式来查找恰好为5个长度的连续“w”或“b”:
superString.test(/(b{5,5})|(w{5,5})/)
。如果测试返回
true
,则存在获胜情况。如果没有,我们就转向垂直线。
垂直线
您想重用上述代码,因此创建一个名为
testRows
的函数。测试垂直线的过程与测试水平线完全相同,但您希望将棋盘
转置,使行变成列,列变成行。然后应用相同的
testRows
函数。可以通过将值复制到新的二维数组中来完成转置,也可以编写一个简单的
getCol
函数,并在其中使用它来在
testRows
中使用。
对角线
再次,我们想重用'testRows'函数。例如这样的对角线:
b x x x x
x b x x x
x x b x x
x x x b x
x x x x b
可以转换为垂直形式,如下所示:
b x x x x
b x x x
b x x
b x
b
通过将行
i向右移动
i个位置。现在只需要转置,我们就可以回到测试水平的问题上了。您需要对另一条方向的对角线执行相同的操作,但这次将行
i向右移动
length - 1 - i
个位置,或者在您的情况下,是
18 - i
个位置。
函数式JavaScript
顺便说一句,我的解决方案很适合函数式编程,这意味着如果您有函数式编程工具,它可以很容易地进行编码,尽管这并不是必需的。我建议使用
underscore.js,因为您很可能需要在许多不同的游戏算法中使用基本工具,如
map
、
reduce
和
filter
。例如,我关于测试水平线的部分可以用
map
的一行JavaScript代码来编写:
_(board).map(function (row) {return row.join("")}).join("x").test(/(b{5,5})|(w{5,5})/);