#javascript #arrays #regex
#javascript #массивы #регулярное выражение
Вопрос:
Ниже приведен код для игры в крестики-нолики 3х3. Это работает отлично, но есть вещи, которые я не понимаю.
Цель функции — вернуть:
- -1 если доска еще не закончена (есть пустые места),
- 1 если «X» выиграл,
- 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. Почему это?
Код абсолютно в порядке, но я не понимаю, что происходит. Не могли бы вы объяснить?
Комментарии:
1. что такое
.test(board)
?2. @SaadAnees это: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /… . Синтаксис
regexObj.test(str)
.
Ответ №1:
Регулярное выражение содержит 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. 1....1....1
Имеет длину 11 символов и может совпадать только в позиции 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") amp;amp; -1);
}
Комментарии:
1. @trincol большое спасибо. Ваше объяснение сделало мой день лучше. Obrigado.
Ответ №2:
.
сопоставьте с любым символом, чтобы
222
сопоставьте с
-------------
| 2 | 2 | 2 |
-------------
| | | |
-------------
| | | |
-------------
OR
-------------
| | | |
-------------
| 2 | 2 | 2 |
-------------
| | | |
-------------
OR
-------------
| | | |
-------------
| | | |
-------------
| 2 | 2 | 2 |
-------------
и 2...2...2
сопоставьте с
-------------
| 2 | . | . | .
-------------
| 2 | . | . | .
-------------
| 2 | | |
-------------
OR
-------------
| | 2 | . | .
-------------
| . | 2 | . | .
-------------
| . | 2 | |
-------------
OR
-------------
| | | 2 | .
-------------
| . | . | 2 | .
-------------
| . | . | 2 |
-------------
.
за пределами доски совпадают с разделителем -
.
А два других более или менее одинаковые.
Ответ №3:
После операций join
и replace
, board
будет строка, подобная этой:
001-012-210
Каждая строка разделяется -
.
111
Случай тестируется на строку, полную крестиков.
1...1...1
Случай тестируется на наличие столбца, полного крестиков. Есть 3 точки, потому что там также есть -
символ.
1..1..1
Случай тестируется на диагональ, полную крестиков.
Ответ №4:
В регулярных выражениях альтернативные шаблоны разделяются |
и .
совпадают в точности с любым символом.
Доска преобразуется в строку, которая выглядит следующим образом:
001-012-210
Это означает, что игрок 1
выигрывает, когда
- они заполнили строку, что означает, что строка содержит подстроку
111
- они заполнили столбец, что означает, что строка либо
1xx-1xx-1xx
,x1x-x1x-x1x
либоxx1-xx1-xx1
. В этих случаях между каждым из них ровно три символа1
, которым соответствует1...1...1
в регулярном выражении. - они заполнили диагональ, что означает, что строка либо
xx1-x1x-1xx
, либо1xx-x1x-xx1
. В этих случаях между каждым из них есть либо ровно два, либо четыре символа1
, которым соответствует либо1..1..1
, либо1....1...1
.