井字游戏:如何重置游戏?

时间:2021-04-08 13:40:42

标签: javascript

我有一个 handleReset 函数,我可以在其中获取重置按钮并使用 location.reload() 刷新页面,但我更愿意找到一种方法来“清空”单元格,这样就没有 X 或 O 标记和将所有内容恢复到开始时的状态(轮到玩家,文本提示玩家 1 等),因此刷新不会那么突然。有没有办法做到这一点?

// player factory function
const createPlayer = (name, marker) => {
    return {name, marker};
}

// gameboard object
const gameBoard = (() => {

    // generate board array
    let board = [];
    for (i = 0; i < 9; i++) {
        board.push('');
    }

    // display square for each cell
    let squares = document.querySelector('.squares');

    board.forEach((item, index) => {
        const square = document.createElement('div');
        square.className = 'square';
        squares.appendChild(square);
    })

    // add event listeners on each square
    Array.from(squares.children).forEach((square, index) => {
        square.addEventListener('click', () => {
            // display active player marker
            square.classList.add(game.currentPlayer.marker);
            square.setAttribute('data', game.currentPlayer.marker);
            // update array value to be that of active player
            board[index] = game.currentPlayer.marker;
            // remove event listener from the marked index
            square.style.pointerEvents = 'none';
            // update remainingSpots
            game.remainingSpots -= 1;
            // check winner: if all 3 values within any of these conditions are ===...
            game.handleWin();
            // check remaining spots
            if (game.winner == false) {
                if (game.remainingSpots > 0) {
                    game.alertNextPlayer();
                    game.nextPlayer();
                } else if (game.remainingSpots == 0) {
                    game.declareTie();
                }
            }
        })
    });


    // return
    return {
        board
    };
})();

// game object
const game = (() => {
   
    // declare players
    const playerOne = createPlayer('Player 1', 'X');
    const playerTwo = createPlayer('Player 2', 'O');

    // starting point
    let currentPlayer = playerOne;
    let winner = false;
    let remainingSpots = 9;

    // selectors
    let subtext = document.querySelector('.subtext'); // display winner/tie
    let playerName = document.querySelector('.player-name'); // alert player turn

    // winning conditions
    const winningAxes = [
        [0,1,2],
        [3,4,5],
        [6,7,8],
        [0,3,6],
        [1,4,7],
        [2,5,8],
        [0,4,8],
        [2,4,6],
    ];

    // check winner
    function handleWin() {
        winningAxes.forEach((item, index) => { // [0, 1, 2, 3, 4, 5, 6, 7]
            if (gameBoard.board[item[0]] === this.currentPlayer.marker && gameBoard.board[item[1]] === this.currentPlayer.marker && gameBoard.board[item[2]] === this.currentPlayer.marker) {
                subtext.innerHTML = `<b>Yay! ${this.currentPlayer.name} wins!</b>`;
                this.winner = true;
            } 
        })
    }

    // alert next player
    function alertNextPlayer() {
        this.currentPlayer === playerOne ? playerName.textContent = 'Player 2' : playerName.textContent = 'Player 1';
    }

    // next player
    function nextPlayer() {
        this.currentPlayer === playerOne ? this.currentPlayer = playerTwo : this.currentPlayer = playerOne;
        
    }

    // declare tie
    function declareTie() {
        subtext.innerHTML = "<b>It's a tie!?</b>";
    }

    // return
    return {
        currentPlayer,
        remainingSpots,
        handleWin,
        alertNextPlayer,
        nextPlayer,
        declareTie,
        winner
    };
})();

function handleReset(){
    document.querySelector('#reset').addEventListener('click', function(){   
     location.reload();
    });
}

handleReset();
 <html>
<body>
    <h1 class="neon">TIC TAC TOE</h1>
        
    
    <main class="gameboard">
        <p class="subtext"><span class="player-name">Player 1</span>, you're up!</p>
        <div class="squares"></div>
    </main>

    <button id="reset">RESET</button>


</body>
</html>

1 个答案:

答案 0 :(得分:1)

将您的逻辑包装在一个函数中并在重置时调用该函数。您还应该清理 DOM。

// player factory function
const createPlayer = (name, marker) => {
    return {name, marker};
}

function startGame() {
// gameboard object
const gameBoard = (() => {

    // generate board array
    let board = [];
    for (i = 0; i < 9; i++) {
        board.push('');
    }

    // display square for each cell
    let squares = document.querySelector('.squares');

    board.forEach((item, index) => {
        const square = document.createElement('div');
        square.className = 'square';
        squares.appendChild(square);
    })

    // add event listeners on each square
    Array.from(squares.children).forEach((square, index) => {
        square.addEventListener('click', () => {
            // display active player marker
            square.classList.add(game.currentPlayer.marker);
            square.setAttribute('data', game.currentPlayer.marker);
            // update array value to be that of active player
            board[index] = game.currentPlayer.marker;
            // remove event listener from the marked index
            square.style.pointerEvents = 'none';
            // update remainingSpots
            game.remainingSpots -= 1;
            // check winner: if all 3 values within any of these conditions are ===...
            game.handleWin();
            // check remaining spots
            if (game.winner == false) {
                if (game.remainingSpots > 0) {
                    game.alertNextPlayer();
                    game.nextPlayer();
                } else if (game.remainingSpots == 0) {
                    game.declareTie();
                }
            }
        })
    });


    // return
    return {
        board
    };
})();

// game object
const game = (() => {
   
    // declare players
    const playerOne = createPlayer('Player 1', 'X');
    const playerTwo = createPlayer('Player 2', 'O');

    // starting point
    let currentPlayer = playerOne;
    let winner = false;
    let remainingSpots = 9;

    // selectors
    let subtext = document.querySelector('.subtext'); // display winner/tie
    let playerName = document.querySelector('.player-name'); // alert player turn

    // winning conditions
    const winningAxes = [
        [0,1,2],
        [3,4,5],
        [6,7,8],
        [0,3,6],
        [1,4,7],
        [2,5,8],
        [0,4,8],
        [2,4,6],
    ];

    // check winner
    function handleWin() {
        winningAxes.forEach((item, index) => { // [0, 1, 2, 3, 4, 5, 6, 7]
            if (gameBoard.board[item[0]] === this.currentPlayer.marker && gameBoard.board[item[1]] === this.currentPlayer.marker && gameBoard.board[item[2]] === this.currentPlayer.marker) {
                subtext.innerHTML = `<b>Yay! ${this.currentPlayer.name} wins!</b>`;
                this.winner = true;
            } 
        })
    }

    // alert next player
    function alertNextPlayer() {
        this.currentPlayer === playerOne ? playerName.textContent = 'Player 2' : playerName.textContent = 'Player 1';
    }

    // next player
    function nextPlayer() {
        this.currentPlayer === playerOne ? this.currentPlayer = playerTwo : this.currentPlayer = playerOne;
        
    }

    // declare tie
    function declareTie() {
        subtext.innerHTML = "<b>It's a tie!?</b>";
    }

    // return
    return {
        currentPlayer,
        remainingSpots,
        handleWin,
        alertNextPlayer,
        nextPlayer,
        declareTie,
        winner
    };
})();
}

startGame();

function cleanUp() {
    document.querySelector('.subtext').innerHTML = `<span class="player-name">Player 1</span>, you're up!`;
    document.querySelector('.squares').innerHTML = '';
}

function handleReset(){
    document.querySelector('#reset').addEventListener('click', function(){
     cleanUp();
     startGame();
    });
}

handleReset();
<html>
<body>
    <h1 class="neon">TIC TAC TOE</h1>
    <main class="gameboard">
        <p class="subtext"><span class="player-name">Player 1</span>, you're up!</p>
        <div class="squares"></div>
    </main>

    <button id="reset">RESET</button>
</body>
</html>