井字游戏正则表达式

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,其中包含每个玩家的数组,p1p2,只需在每次推入后对数组进行排序。这样,可以保证索引是按升序比较的。

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 的文章,我学会了如何将 winArray1&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>`;
        }
    })
});