井字游戏:重置游戏后无限获胜

时间:2020-10-20 17:22:19

标签: javascript html css tic-tac-toe

我正在使用HTML,CSS和JS重新创建经典的Tic Tac Toe。

我已经让游戏成功运行了一次,但是在创建“新游戏”选项后功能似乎出现了一些错误。点击新游戏后,每次玩家标记一个正方形时,都会弹出赢家消息。

游戏检查算法在gameBoard变量内部,名为checkWin。更新视图后,在displayController内部调用它。

显示问题的图片:

) 在显示最终的X位置(左下角)之前弹出弹出的中奖消息,正常工作

enter image description here 问题::单击新游戏后,我单击一个正方形,然后弹出获胜消息。

let counter = 0;
let gameBoard = (function() {
  // 'use strict';

  let Board = ["", "", "", "", "", "", "", "", ""];

  let winningCombinations = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
  ]

  // has array 
  return {
    Board: Board,
    clickSquare: function(player) {
      document.querySelectorAll('td').forEach(item => {
        item.addEventListener('click', event => {
          // console.log(item.id.replace('_',''));
          player.markSquare(item.id.replace('_', ''));
        })
      });
    },
    checkWin: function() {
      return winningCombinations.some(combination => {
        return combination.every(index => {
          return Board[index] === "X"
        }) || combination.every(index => {
          return Board[index] === "O"
        })
      })
    }
  }
})();



let displayController = (function() {
  'use strict';

  function updateView(square) {
    console.log(square);
    document.querySelector("#_" + square).textContent = gameBoard.Board[square];
    if (gameBoard.checkWin() && counter % 2 === 0) {
      alert("Player One Wins!");
    } else if (gameBoard.checkWin() && counter % 2 !== 0) {
      alert("Player Two Wins!");
    } else if (counter == 8) {
      alert("TIE!");
    }
    counter++;
  }
  return {
    updateView: updateView
  }
})();

function createPlayer(name) {
  return {
    name: name,
    markSquare(square) {
      if (gameBoard.Board[square] === "") {
        if (counter % 2 === 0) {
          gameBoard.Board[square] = "X";
        } else {
          gameBoard.Board[square] = "O";
        }

        displayController.updateView(square);
      }
    }
  }
}

function gameFlow() {
  let player1 = createPlayer("Phil");
  gameBoard.clickSquare(player1);

  let resetGame = document.querySelector("button");
  resetGame.addEventListener('click', function() {
    for (let i = 0; i <= 8; i++) {
      document.querySelector("#_" + i).textContent = "";
    }
    gameBoard.Board = ["", "", "", "", "", "", "", "", ""];
    counter = 0;
  });

}
gameFlow();
body {
  margin: 0;
  font-family: 'Nunito', sans-serif;
}

h1 {
  text-align: center;
}

#playerNames {
  margin: auto;
  align-items: center;
  justify-content: center;
  display: flex;
}

input {
  width: 170px;
  height: 40px;
  font-size: 30px;
  margin: 0 30px 0 30px;
}

button {
  width: 100px;
  height: 100px;
  font-size: 30px;
  border-radius: 50%;
  background-color: yellow;
}

table {
  margin: auto;
}

td {
  width: 190px;
  height: 190px;
  text-align: center;
  font-size: 100px;
}

tr td:nth-of-type(2) {
  border-left: 2px solid black;
  border-right: 2px solid black;
}

tr:nth-of-type(2) td {
  border-top: 2px solid black;
  border-bottom: 2px solid black;
}
<!DOCTYPE html>
<html>

<head>
  <title></title>
  <link rel="stylesheet" type="text/css" href="TicTac.css">
  <link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
</head>

<body>
  <h1><b>Tic Tac Toe</b></h1>
  <div id="playerNames">
    <input id="pOne" placeholder="Player One" type="text">
    <button>New Game</button>
    <input id="pTwo" placeholder="Player Two" type="text">
  </div>

  <div>
    <table>
      <tr>
        <td id="_0"></td>
        <td id="_1"></td>
        <td id="_2"></td>
      </tr>
      <tr>
        <td id="_3"></td>
        <td id="_4"></td>
        <td id="_5"></td>
      </tr>
      <tr>
        <td id="_6"></td>
        <td id="_7"></td>
        <td id="_8"></td>
      </tr>

    </table>
  </div>

  <script src="TicTac.js"></script>
</body>

</html>

1 个答案:

答案 0 :(得分:1)

您非常亲密,但是您遇到了两个问题。

一个原因是您没有将click事件正确地添加到“新游戏”按钮。我进行了快速编辑以使其正常运行,但是还有其他方法可以实现。

第二个是您正在为gameBoard.Board.Board分配一个新数组。我不确定为什么这行不通,但是在您已有的循环中重置当前值确实行得通。

进行这两个较小的更改似乎可以使事情正常进行。我使用console.log来确保不仅可以正确运行,而且可以查看变量中的值。它帮助我快速确定单击按钮时未调用“重置”方法,并确认未按预期更新数据。我已经留在那些日志中,因此您可以将它们视为如何使用它们的示例。我还在注释掉的代码中留下了一些区别,所以请不要忘记清理所有这些内容。

顺便说一句,有些事情可以做得更好一些,但是到目前为止做得还不错。这在工作时真的很干净简洁。

let counter = 0;
let gameBoard = (function() {
    // 'use strict';

    let Board = ["", "", "", "", "","","","",""];

    let winningCombinations = [
        [0,1,2],
        [3,4,5],
        [6,7,8],
        [0,3,6],
        [1,4,7],
        [2,5,8],
        [0,4,8],
        [2,4,6]
    ]

    // has array 
    return {
        Board: Board,
        clickSquare: function(player) {
            document.querySelectorAll('td').forEach(item => {
                item.addEventListener('click', event => {
                    // console.log(item.id.replace('_',''));
                    player.markSquare(item.id.replace('_',''));
                })
            });       
        },
        checkWin: function() {
        console.log(Board);
            return winningCombinations.some(combination => {
                return combination.every(index => {
                    return Board[index] === "X"
                }) || combination.every(index => {
                    return Board[index] === "O"
            })
        })
        }
    }
})();



let displayController = (function() {
    'use strict';

    function updateView(square) {
            console.log(square);
            document.querySelector("#_"+square).textContent = gameBoard.Board[square];
            if (gameBoard.checkWin() && counter %2 === 0) {
                alert("Player One Wins!");
            }
            else if (gameBoard.checkWin() && counter %2 !== 0) {
                alert("Player Two Wins!");
            }
            else if (counter == 8) {
                alert("TIE!");
            }
            counter++;
    }
    return {
        updateView: updateView
    }
})();

function createPlayer(name) {
    return {
        name: name,
        markSquare(square) {
            if (gameBoard.Board[square] === "") {
                if (counter %2 === 0) {
                    gameBoard.Board[square] = "X";
                }
                else {
                    gameBoard.Board[square] = "O";
                }
                
                displayController.updateView(square);
            }
        }
    }
}

function gameFlow() {
    let player1 = createPlayer("Phil");
    gameBoard.clickSquare(player1);

    let resetGame = document.getElementById("resetbutton");
    resetGame.addEventListener('click', function() {
        console.log("reset");
        for (let i =0; i<=8; i++) {
            document.querySelector("#_"+i).textContent="";
            gameBoard.Board[i] = "";
        }
        //gameBoard.Board = ["", "", "", "", "","","","",""];
        counter = 0;
    });
        
}
gameFlow();
body {
    margin: 0;
    font-family: 'Nunito', sans-serif;

}
h1 {
    text-align: center;
}
#playerNames {
    margin: auto;
    align-items: center;
    justify-content: center;
    display: flex;
}
input {
    width:170px;
    height: 40px;
    font-size: 30px;
    margin: 0 30px 0 30px;
}
button {
    width:100px;
    height: 100px;
    font-size: 30px;
    border-radius: 50%;
    background-color: yellow;
}
table {
    margin: auto;
}
td {
    width: 190px;
    height: 190px;
    text-align: center;
    font-size: 100px;
}
tr td:nth-of-type(2) {
    border-left: 2px solid black;
    border-right:2px solid black;
}
tr:nth-of-type(2) td {
    border-top: 2px solid black;
    border-bottom: 2px solid black;
}
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <link rel="stylesheet" type="text/css" href="TicTac.css">
    <link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
</head>
<body>
    <h1><b>Tic Tac Toe</b></h1>
    <div id="playerNames">
        <input id="pOne" placeholder="Player One" type="text">
        <button id="resetbutton">New Game</button>
        <input id="pTwo" placeholder="Player Two" type="text">
    </div>
    
    <div>
    <table>
        <tr>
            <td id="_0"></td>
            <td id="_1"></td>
            <td id="_2"></td>
        </tr>
        <tr>
            <td id="_3"></td>
            <td id="_4"></td>
            <td id="_5"></td>
        </tr>
        <tr>
            <td id="_6"></td>
            <td id="_7"></td>
            <td id="_8"></td>
        </tr>

    </table>
</div>

<script src="TicTac.js"></script>
</body>
</html>