井字棋游戏--正则表达式需要比3x3的棋盘更多的字符吗?

4
我有以下代码用于3x3的井字棋游戏,它可以正常工作,但有些地方我不理解。 该函数的目标是返回:
  • 如果棋盘未完成(还有空位),则返回-1
  • 如果“X”赢,则返回1
  • 如果“O”赢,则返回2
  • 如果是平局,则返回0。

function isSolved(board) {
   board = board.join('-').replace(/,/g,'');
   if(/222|2...2...2|2....2....2|2..2..2/.test(board)) return 2;
   if(/111|1...1...1|1....1....1|1..1..1/.test(board)) return 1;
   if(/0/.test(board)) return -1;
   return 0;

}

var result = isSolved([[0, 0, 1],[0, 1, 2],[2, 1, 0]]); //board is 3 dimensional array.

console.log(result); // -1

我不理解if语句中正则表达式的一部分,即1....1....1,因为棋盘可以输入的最大数字是9,但这里似乎是11。为什么会这样?

代码完全没有问题,但我不明白发生了什么。你能解释一下吗?


.test(board) 是什么? - Saad Anees
2
@SaadAnees 这是:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test。语法是 regexObj.test(str) - Gerardo Furtado
4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
5

这个正则表达式查看了11个字符,因为board已经与两个额外的-字符连接在一起:

board = board.join('-')

假设原始的board是一个2D数组,并且在这个连接过程中引入了逗号(因为嵌套的数组在字符串化过程中被处理),则可以使用以下代码删除:

.replace(/,/g,'');

因此,像这样的原始电路板:

[
    [1, 0, 1],
    [2, 2, 0],
    [0, 0, 0]
]

使用.join("-")将其转换为字符串:

"1,0,1-2,2,0-0,0,0"

...最后清除逗号:


"101-220-000".
额外的分隔符使得查找某些模式变得更容易,而不会导致错误的匹配。例如,当匹配到222时,可以确定它们将在同一行中,而匹配1..1..1将同时检测到三个可能的垂直3连,而不会有误报,因为它只能在位置0、1或2开始匹配。长度为11个字符的1....1....1只能在对角线之一的位置0匹配。最后,1..1..1也只能在一个位置匹配,即位置2,否则横线中的一个将与模式中的1冲突。匹配表示相反的对角线。

进一步改进

可以使用后向引用将两个正则表达式合并为一个(节省一些执行时间),并使用一些逻辑将所有可能性组合成一个表达式。
function isSolved(board) {
   board = board.join('-').replace(/,/g,'');
   var match = board.search(/([12])(\1|...\1...|....\1....|..\1..)\1/);
   return +(board[match] || board.includes("0") && -1);
}

@trincol 非常感谢。你的解释让我开心了。Obrigado. - Arjun Kumar

2
在执行joinreplace操作之后,board将会变成以下格式的字符串:"最初的回答"。
001-012-210
每一行都用-分隔。 111情况测试的是一排X方块。 1...1...1情况测试的是一列X方块。有3个点是因为还有一个字符-1..1..1情况测试的是一条斜线上全是X方块。

2

. 通配符可以匹配任意字符,因此

222 可以匹配

最初的回答:

-------------
| 2 | 2 | 2 |
-------------
|   |   |   |
-------------
|   |   |   |
-------------

OR

-------------
|   |   |   |
-------------
| 2 | 2 | 2 |
-------------
|   |   |   |
-------------

OR

-------------
|   |   |   |
-------------
|   |   |   |
-------------
| 2 | 2 | 2 |
-------------

and 2...2...2 match with

-------------
| 2 | . | . | . 
-------------
| 2 | . | . | . 
-------------
| 2 |   |   | 
-------------

OR

-------------
|   | 2 | . | . 
-------------
| . | 2 | . | . 
-------------
| . | 2 |   | 
-------------

OR

-------------
|   |   | 2 | . 
-------------
| . | . | 2 | . 
-------------
| . | . | 2 |
-------------

点号.在板子外面与分隔符-匹配。

而另外两个则差不多。

注:Original Answer可翻译成“原始答案”、“初始回复”等,具体根据上下文语境而定。

1
在正则表达式中,用|分隔不同的模式,.匹配任意一个字符。

该板被转换为字符串,看起来像这样:

001-012-210

这意味着当玩家1

  • 填满一行,也就是字符串包含子串111
  • 填满一列,也就是字符串为1xx-1xx-1xxx1x-x1x-x1xxx1-xx1-xx1。在这些情况下,每个1之间恰好有三个字符,这与正则表达式中的1...1...1匹配。
  • 填满对角线,也就是字符串为xx1-x1x-1xx1xx-x1x-xx1。在这些情况下,每个1之间恰好有两个或四个字符,这与正则表达式中的1..1..11....1...1匹配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,