井字游戏正则表达式
Tic-tac-Toe regex
我正在研究井字游戏算法并使用正则表达式来解决获胜条件。
9 个方块被赋予 0-8 值:
[0][1][2]
[3][4][5]
[6][7][8]
每当玩家 1 或 2 单击一个方块时,该值就会被推送到一个数组中,在收集到 3 个值后,正则表达式开始测试以确定玩家是否赢了。
问题.. 例如正则表达式测试以查看 012 102 的任何顺序是否存在但它无法匹配 03142.
如何修复我的正则表达式以查找 3 个数字,即使它们被其他数字分隔?
Let regexWin = /(?:^|\W)[012][012][012](?:$|\W)/gm,
假设将占据的方块推入对象moves
,其中包含每个玩家的数组,p1
和p2
,只需在每次推入后对数组进行排序。这样,可以保证索引是按升序比较的。
let moves = {p1: [], p2: []};
function move(player, spaceIndex) {
moves[player].push(spaceIndex);
moves[player].sort();
if (/012|345|678|036|147|258|048|246/.test(moves[player].join('')) {
//win!
}
}
从你问题中给出的细节来看,你似乎没有意识到你需要两个数组,而不是一个,否则获胜算法将不知道哪个玩家占据哪个 space,并且将仅在连续三个 space 被占用时报告获胜,即使它们在不同玩家之间共享也是如此。
您可以跟踪棋盘状态,因此您不需要依赖 moves
列表:定义 board
为长度为 9 的数组,初始化为全 0(表示每个单元格都是空的)。然后,当下一个动作时,将相应的插槽设置为“1”或“2”,具体取决于哪个玩家下该动作。
var board = Array(9).fill(0); // initial board
var moves = []; // initial move list
var turn = 1; // first player to move (other player is identified as 2)
// ...
function play(move) { // move is an index in board (0..8)
board[move] = turn; // turn is 1 or 2
moves.push(move); // this is the list you already have
// Use regular expression to detect any 3-in-a-row
let isWin = /^(?:...)*([12])|^.?.?([12])....|^([12])......|^..([12])../.test(board.join(""));
console.log("is winning move?", isWin);
turn = 3 - turn; // toggle the player that is to move
}
这样你也可以使用board
来更新显示。
有关完整实现、渲染和用于生成“最佳”着法的极小极大算法,请参阅 this answer。
我没有找到有效的正则表达式,所以我换了一个不同的想法。
根据 Alvaro Saburido 的文章,我学会了如何将 winArray 和 1&2 playerArray 用于 intersection 并测试获胜。
这篇文章很棒,我会继续寻找正则表达式解决方案,只是为了编码的乐趣。
https://medium.com/@alvaro.saburido/set-theory-for-arrays-in-es6-eb2f20a61848
let win = ["012", "345", "678", "036", "147", "258", "048", "246"];
function endGameEvaluation() {
if (joueur1Turn) {
resultMessage.innerHTML = `<div id="resultMessage">Player 1 Wins!! End of the game</div>`;
gameWon = true;
playerTurnMsg.innerHTML = "";
} else if (joueur2Turn) {
resultMessage.innerHTML = `<div id="resultMessage">Player 2 Wins!! End of the game</div>`;
gameWon = true;
playerTurnMsg.innerHTML = "";
}
}
function winner(player) {
for (var i = 0; i < 8; i++) {
let won = win[i]
let inCommon = player.filter(x => won.includes(x));
if (inCommon.length == 3) {
endGameEvaluation();
}
}
}
tdClickArea.forEach(item => {
item.addEventListener('click', e => {
let btnArea = e.target;
let player;
if (btnArea.innerHTML == "X" || btnArea.innerHTML == "O") {
alert("tricheur! Choisi une autre case")
} else {
if (joueur1Turn) {
btnArea.innerHTML = "X";
joueur1Sq.push(btnArea.getAttribute("value"));
player = joueur1Sq;
} else if (joueur2Turn) {
btnArea.innerHTML = "O";
joueur2Sq.push(btnArea.getAttribute("value"));
player = joueur2Sq;
}
}
if (joueur1Sq.length >= 3 || joueur2Sq.length >= 3) {
winner(player);
}
counter++;
changeTurn();
// Here we end the game if nobody won until the last posibble move
if (counter == 9 && gameWon == false) {
resultMessage.innerHTML = `<div id="resultMessage">End of the game</div>`;
}
})
});
我正在研究井字游戏算法并使用正则表达式来解决获胜条件。 9 个方块被赋予 0-8 值:
[0][1][2]
[3][4][5]
[6][7][8]
每当玩家 1 或 2 单击一个方块时,该值就会被推送到一个数组中,在收集到 3 个值后,正则表达式开始测试以确定玩家是否赢了。
问题.. 例如正则表达式测试以查看 012 102 的任何顺序是否存在但它无法匹配 03142.
如何修复我的正则表达式以查找 3 个数字,即使它们被其他数字分隔?
Let regexWin = /(?:^|\W)[012][012][012](?:$|\W)/gm,
假设将占据的方块推入对象moves
,其中包含每个玩家的数组,p1
和p2
,只需在每次推入后对数组进行排序。这样,可以保证索引是按升序比较的。
let moves = {p1: [], p2: []};
function move(player, spaceIndex) {
moves[player].push(spaceIndex);
moves[player].sort();
if (/012|345|678|036|147|258|048|246/.test(moves[player].join('')) {
//win!
}
}
从你问题中给出的细节来看,你似乎没有意识到你需要两个数组,而不是一个,否则获胜算法将不知道哪个玩家占据哪个 space,并且将仅在连续三个 space 被占用时报告获胜,即使它们在不同玩家之间共享也是如此。
您可以跟踪棋盘状态,因此您不需要依赖 moves
列表:定义 board
为长度为 9 的数组,初始化为全 0(表示每个单元格都是空的)。然后,当下一个动作时,将相应的插槽设置为“1”或“2”,具体取决于哪个玩家下该动作。
var board = Array(9).fill(0); // initial board
var moves = []; // initial move list
var turn = 1; // first player to move (other player is identified as 2)
// ...
function play(move) { // move is an index in board (0..8)
board[move] = turn; // turn is 1 or 2
moves.push(move); // this is the list you already have
// Use regular expression to detect any 3-in-a-row
let isWin = /^(?:...)*([12])|^.?.?([12])....|^([12])......|^..([12])../.test(board.join(""));
console.log("is winning move?", isWin);
turn = 3 - turn; // toggle the player that is to move
}
这样你也可以使用board
来更新显示。
有关完整实现、渲染和用于生成“最佳”着法的极小极大算法,请参阅 this answer。
我没有找到有效的正则表达式,所以我换了一个不同的想法。 根据 Alvaro Saburido 的文章,我学会了如何将 winArray 和 1&2 playerArray 用于 intersection 并测试获胜。 这篇文章很棒,我会继续寻找正则表达式解决方案,只是为了编码的乐趣。
https://medium.com/@alvaro.saburido/set-theory-for-arrays-in-es6-eb2f20a61848
let win = ["012", "345", "678", "036", "147", "258", "048", "246"];
function endGameEvaluation() {
if (joueur1Turn) {
resultMessage.innerHTML = `<div id="resultMessage">Player 1 Wins!! End of the game</div>`;
gameWon = true;
playerTurnMsg.innerHTML = "";
} else if (joueur2Turn) {
resultMessage.innerHTML = `<div id="resultMessage">Player 2 Wins!! End of the game</div>`;
gameWon = true;
playerTurnMsg.innerHTML = "";
}
}
function winner(player) {
for (var i = 0; i < 8; i++) {
let won = win[i]
let inCommon = player.filter(x => won.includes(x));
if (inCommon.length == 3) {
endGameEvaluation();
}
}
}
tdClickArea.forEach(item => {
item.addEventListener('click', e => {
let btnArea = e.target;
let player;
if (btnArea.innerHTML == "X" || btnArea.innerHTML == "O") {
alert("tricheur! Choisi une autre case")
} else {
if (joueur1Turn) {
btnArea.innerHTML = "X";
joueur1Sq.push(btnArea.getAttribute("value"));
player = joueur1Sq;
} else if (joueur2Turn) {
btnArea.innerHTML = "O";
joueur2Sq.push(btnArea.getAttribute("value"));
player = joueur2Sq;
}
}
if (joueur1Sq.length >= 3 || joueur2Sq.length >= 3) {
winner(player);
}
counter++;
changeTurn();
// Here we end the game if nobody won until the last posibble move
if (counter == 9 && gameWon == false) {
resultMessage.innerHTML = `<div id="resultMessage">End of the game</div>`;
}
})
});