在井字游戏中为计算机选择随机位置无法正常工作

时间:2019-12-24 04:17:24

标签: javascript html css logic

好的,所以我一次用Python制作了一个非常简单的Tic-Tac-Toe游戏,而且非常有趣,所以我想我会对其进行调味,并在HTML / JS / CSS中进行制作再漂亮一点一切都很好,但是当为游戏制作简单的“ AI”时,我遇到了一些困难。这款游戏的简易AI应该是完全随机的,但是,有时它会占据一个已经占据的正方形,有时甚至根本不会移动,所以我知道这可能很简单,我就是不知道我认为它可能在此代码块中的某处,但我不知道:

function computerEasyModeMove(){
  if(player == 'x'){
    computer = 'o';
  }
  if(player == 'o'){
    computer = 'x';
  }
  var computerMove = Math.floor(Math.random() * 9) + 1;
  while(computerMove == 1 && (topLeftBox.innerHTML == 'o' || topLeftBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
   while(computerMove == 2 && (topMiddleBox.innerHTML == 'o' || topMiddleBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
   while(computerMove == 3 && (topRightBox.innerHTML == 'o' || topRightBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
   while(computerMove == 4 && (middleLeftBox.innerHTML == 'o' || middleLeftBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 5 && (middleMiddleBox.innerHTML == 'o' || middleMiddleBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 6 && (middleRightBox.innerHTML == 'o' || middleRightBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 7 && (bottomLeftBox.innerHTML == 'o' || bottomLeftBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 8 && (bottomMiddleBox.innerHTML == 'o' || bottomMiddleBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 9 && (bottomRightBox.innerHTML == 'o' || bottomRightBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }

  if(computerMove == 1){
      topLeftBox.innerHTML = computer;
      topLeftBox.style.pointerEvents = 'none';
  }
  if(computerMove == 2){
      topMiddleBox.innerHTML = computer;
      topMiddleBox.style.pointerEvents = 'none';
  }
  if(computerMove == 3){
      topRightBox.innerHTML = computer;
      topRightBox.style.pointerEvents = 'none';
  }
  if(computerMove == 4){
      middleLeftBox.innerHTML = computer;
      middleLeftBox.style.pointerEvents = 'none';
  }
  if(computerMove == 5){
      middleMiddleBox.innerHTML = computer;
      middleMiddleBox.style.pointerEvents = 'none';
  }
  if(computerMove == 6){
      middleRightBox.innerHTML = computer;
      middleRightBox.style.pointerEvents = 'none';
  }
  if(computerMove == 7){
      bottomLeftBox.innerHTML = computer;
      bottomLeftBox.style.pointerEvents = 'none';
  }
  if(computerMove == 8){
      bottomMiddleBox.innerHTML = computer;
      bottomMiddleBox.style.pointerEvents = 'none';
  }
  if(computerMove == 9){
      bottomRightBox.innerHTML = computer;
      bottomRightBox.style.pointerEvents = 'none';
  }
}

基本上,这是我用于简易AI的代码,下面是完整代码。我认为我的游戏看起来不错。如果您想尝试一下,我一直在repl.it(https://repl.it/@AnthonyRobinso2/Tic-Tac-Toe-HTMLJS)上进行,如果这样可以更轻松地为我提供帮助。我仍在开发游戏,以及更困难的AI模式,因此我仍然需要完成这些工作,但是我想拥有一个可玩的游戏,即使它真的很简单。再次感谢!

HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <center>
      <div id='setup'>
        Hey! Welcome to my Tic-Tac-Toe game! Please choose some settings below!
        <br>
        <div class='xOrO'>
          <h3>Player:</h3>
          Do you want to be X's?<input type='checkbox' id='Xs' value='X' onchange='player = "x"'>
          &nbsp; &nbsp; Or do you want to be O's?<input type='checkbox' id='Os' value='O' onchange='player = "o"'>
          <h3>Opponent AI Level:</h3>
          Easy<input type='checkbox' id='easy' value='easyMode'>
          &nbsp; &nbsp; Medium (Coming Soon)<input type='checkbox' id='medium' value='mediumMode'>
          &nbsp; &nbsp; Hard (Coming Soon)<input type='checkbox' id='hard' value='hardMode'>
          <br>
          <h4>Do you want to go first, or have the computer go first?</h4>
          First<input type='checkbox' id='goFirst' value='first' onchange='playerFirst = true'>
          &nbsp; &nbsp Second<input type='checkbox' id='goSecond' value='second' onchange='playerFirst = false'>
          <br>
          <br>
          <br>
          <button id='confirm' onclick='getGameUp()'>Confirm</button>
      </div>


      <div id='ticTacBoard'>
        <div id='topLeft' onclick='move("topLeft")'>&nbsp;</div>
        <div id='topMiddle' onclick='move("topMiddle")'>&nbsp;</div>
        <div id='topRight' onclick='move("topRight")'>&nbsp;</div>
        <br>
        <div id='middleLeft' onclick='move("middleLeft")'>&nbsp; </div>
        <div id='middleMiddle' onclick='move("middleMiddle")'>&nbsp; </div>
        <div id='middleRight' onclick='move("middleRight")'>&nbsp;</div>
        <br>
        <div id='bottomLeft' onclick='move("bottomLeft")'>&nbsp;</div>
        <div id='bottomMiddle' onclick='move("bottomMiddle")'>&nbsp;</div>
        <div id='bottomRight' onclick='move("bottomRight")'>&nbsp;</div>
      </div>
      <br>
      <br>
      <br>
      <br>
      <br>
      <div id='winDiv'>
        <h1 id='winHeader'>
          YOU WON!!!
        </h1>
      </div>
      <div id='lossDiv'>
        <h1 id='lossHeader'>
          You lost...
        </h1>
      </div>
      <div id='tieDiv'>
        <h1 id='tieHeader'>
          It's a tie!
        </h1>
      </div>
    </center>
    <script src="script.js"></script>
  </body>
</html>

Javascript:

var player;
var computer;
var playerFirst;
var topLeftBox = document.getElementById('topLeft');
var topMiddleBox = document.getElementById('topMiddle');
var topRightBox = document.getElementById('topRight');
var middleLeftBox = document.getElementById('middleLeft');
var middleMiddleBox = document.getElementById('middleMiddle');
var middleRightBox = document.getElementById('middleRight');
var bottomLeftBox = document.getElementById('bottomLeft');
var bottomMiddleBox = document.getElementById('bottomMiddle');
var bottomRightBox = document.getElementById('bottomRight');
var winDiv = document.getElementById('winDiv');
var lossDiv = document.getElementById('lossDiv');
var ticTacBoard = document.getElementById('ticTacBoard');
var setup = document.getElementById('setup');
function getGameUp(){
  setup.style.visibility = "hidden";
  ticTacBoard.style.visibility = "visible";
  if(playerFirst == false){
    computerEasyModeMove();
  }
}

function move(x){
  if(x=='topLeft'){
    if(topLeftBox.innerHTML != 'o' && topLeftBox.innerHTML != 'x'){
      topLeftBox.innerHTML = player;
      topLeftBox.style.pointerEvents = 'none';
    }
  }
  if(x=='topMiddle'){
    if(topMiddleBox.innerHTML != 'o' && topMiddleBox.innerHTML != 'x'){
      topMiddleBox.innerHTML = player;
      topMiddleBox.style.pointerEvents = 'none';
    }
  }
  if(x=='topRight'){
    if(topRightBox.innerHTML != 'o' && topRightBox.innerHTML != 'x'){
      topRightBox.innerHTML = player;
      topRightBox.style.pointerEvents = 'none';
    }
  }
  if(x=='middleLeft'){
    if(middleLeftBox.innerHTML != 'o' && middleLeftBox.innerHTML != 'x'){
      middleLeftBox.innerHTML = player;
      middleLeftBox.style.pointerEvents = 'none';
    }
  }
  if(x=='middleMiddle'){
    if(middleMiddleBox.innerHTML != 'o' && middleMiddleBox.innerHTML != 'x' ){
      middleMiddleBox.innerHTML = player;
      middleMiddleBox.style.pointerEvents = 'none';
    }
  }
  if(x=='middleRight'){
    if(middleRightBox.innerHTML != 'o' && middleRightBox.innerHTML != 'x'){
      middleRightBox.innerHTML = player;
      middleRightBox.style.pointerEvents = 'none';
    }
  }
  if(x=='bottomLeft'){
    if(bottomLeftBox.innerHTML != 'o' && bottomLeftBox.innerHTML != 'x'){
      bottomLeftBox.innerHTML = player;
      bottomLeftBox.style.pointerEvents = 'none';
    }
  }
  if(x=='bottomMiddle'){
    if(bottomMiddleBox.innerHTML != 'o' && bottomMiddleBox.innerHTML != 'x'){
      bottomMiddleBox.innerHTML = player;
      bottomMiddleBox.style.pointerEvents = 'none';
    }
  }
  if(x=='bottomRight'){
    if(bottomRightBox.innerHTML != 'o' && bottomRightBox.innerHTML != 'x'){
      bottomRightBox.innerHTML = player;
      bottomRightBox.style.pointerEvents = 'none';
    }
  }
  checkWinCondition();
  if(winDiv.style.visibility != 'visible'){
    computerEasyModeMove();
    checkWinCondition();
  }
}

function computerEasyModeMove(){
  if(player == 'x'){
    computer = 'o';
  }
  if(player == 'o'){
    computer = 'x';
  }
  var computerMove = Math.floor(Math.random() * 9) + 1;
  while(computerMove == 1 && (topLeftBox.innerHTML == 'o' || topLeftBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
   while(computerMove == 2 && (topMiddleBox.innerHTML == 'o' || topMiddleBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
   while(computerMove == 3 && (topRightBox.innerHTML == 'o' || topRightBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
   while(computerMove == 4 && (middleLeftBox.innerHTML == 'o' || middleLeftBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 5 && (middleMiddleBox.innerHTML == 'o' || middleMiddleBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 6 && (middleRightBox.innerHTML == 'o' || middleRightBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 7 && (bottomLeftBox.innerHTML == 'o' || bottomLeftBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 8 && (bottomMiddleBox.innerHTML == 'o' || bottomMiddleBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }
  while(computerMove == 9 && (bottomRightBox.innerHTML == 'o' || bottomRightBox.innerHTML == 'x')){
    computerMove = Math.floor(Math.random() * 9) + 1;
  }

  if(computerMove == 1){
      topLeftBox.innerHTML = computer;
      topLeftBox.style.pointerEvents = 'none';
  }
  if(computerMove == 2){
      topMiddleBox.innerHTML = computer;
      topMiddleBox.style.pointerEvents = 'none';
  }
  if(computerMove == 3){
      topRightBox.innerHTML = computer;
      topRightBox.style.pointerEvents = 'none';
  }
  if(computerMove == 4){
      middleLeftBox.innerHTML = computer;
      middleLeftBox.style.pointerEvents = 'none';
  }
  if(computerMove == 5){
      middleMiddleBox.innerHTML = computer;
      middleMiddleBox.style.pointerEvents = 'none';
  }
  if(computerMove == 6){
      middleRightBox.innerHTML = computer;
      middleRightBox.style.pointerEvents = 'none';
  }
  if(computerMove == 7){
      bottomLeftBox.innerHTML = computer;
      bottomLeftBox.style.pointerEvents = 'none';
  }
  if(computerMove == 8){
      bottomMiddleBox.innerHTML = computer;
      bottomMiddleBox.style.pointerEvents = 'none';
  }
  if(computerMove == 9){
      bottomRightBox.innerHTML = computer;
      bottomRightBox.style.pointerEvents = 'none';
  }
}


function computerMediumModeMove(){

}

function computerHardModeMove(){

}

function checkWinCondition(){
  //Top 3 Player
  if(topLeftBox.innerHTML == player && topMiddleBox.innerHTML == player && topRightBox.innerHTML == player){
    ticTacBoard.style.pointerEvents = 'none';
    winDiv.style.visibility = 'visible';
  }
  //Top 3 Computer
  if(topLeftBox.innerHTML == computer && topMiddleBox.innerHTML == computer && topRightBox.innerHTML == computer){
    ticTacBoard.style.pointerEvents = 'none';
    lossDiv.style.visibility = 'visible';
  }
  //Middle 3 Player
  if(middleLeftBox.innerHTML == player && middleMiddleBox.innerHTML == player && middleRightBox.innerHTML == player){
    ticTacBoard.style.pointerEvents = 'none';
    winDiv.style.visibility = 'visible';
  }
  //Middle 3 Computer
  if(middleLeftBox.innerHTML == computer && middleMiddleBox.innerHTML == computer && middleRightBox.innerHTML == computer){
    ticTacBoard.style.pointerEvents = 'none';
    lossDiv.style.visibility = 'visible';
  }
  //Bottom 3 Player
  if(bottomLeftBox.innerHTML == player && bottomMiddleBox.innerHTML == player && bottomRightBox.innerHTML == player){
    ticTacBoard.style.pointerEvents = 'none';
    winDiv.style.visibility = 'visible';
  }
  //Bottom 3 Computer
  if(bottomLeftBox.innerHTML == computer && bottomMiddleBox.innerHTML == computer && bottomRightBox.innerHTML == computer){
    ticTacBoard.style.pointerEvents = 'none';
    lossDiv.style.visibility = 'visible';
  }
  //Left 3 Player (Up and Down)
  if(bottomLeftBox.innerHTML == player && topLeftBox.innerHTML == player && middleLeftBox.innerHTML == player){
    ticTacBoard.style.pointerEvents = 'none';
    winDiv.style.visibility = 'visible';
  }
  //Left 3 Computer (Up and Down)
  if(bottomLeftBox.innerHTML == computer && topLeftBox.innerHTML == computer && middleLeftBox.innerHTML == computer){
    ticTacBoard.style.pointerEvents = 'none';
    lossDiv.style.visibility = 'visible';
  }
  //Middle 3 Player (Up and Down)
  if(bottomMiddleBox.innerHTML == player && topMiddleBox.innerHTML == player && middleMiddleBox.innerHTML == player){
    ticTacBoard.style.pointerEvents = 'none';
    winDiv.style.visibility = 'visible';
  }
  //Middle 3 Computer (Up and Down)
  if(bottomMiddleBox.innerHTML == computer && topMiddleBox.innerHTML == computer && middleMiddleBox.innerHTML == computer){
    ticTacBoard.style.pointerEvents = 'none';
    lossDiv.style.visibility = 'visible';
  }
  //Right 3 Player (Up and Down)
  if(bottomRightBox.innerHTML == player && topRightBox.innerHTML == player && middleRightBox.innerHTML == player){
    ticTacBoard.style.pointerEvents = 'none';
    winDiv.style.visibility = 'visible';
  }
  //Right 3 Computer (Up and Down)
  if(bottomRightBox.innerHTML == computer && topRightBox.innerHTML == computer && middleRightBox.innerHTML == computer ){
    ticTacBoard.style.pointerEvents = 'none';
    lossDiv.style.visibility = 'visible';
  }
  //Diagonal Left to Right Player (Down Slope) 
  if(bottomRightBox.innerHTML == player && topLeftBox.innerHTML == player && middleMiddleBox.innerHTML == player){
    ticTacBoard.style.pointerEvents = 'none';
    winDiv.style.visibility = 'visible';
  }
  //Diagonal Left to Right Computer (Down Slope) 
  if(bottomRightBox.innerHTML == computer && topLeftBox.innerHTML == computer && middleMiddleBox.innerHTML == computer){
    ticTacBoard.style.pointerEvents = 'none';
    lossDiv.style.visibility = 'visible';
  }
  //Diagonal Right to Left Player (Up Slope) 
  if(bottomLeftBox.innerHTML == player && topRightBox.innerHTML == player && middleMiddleBox.innerHTML == player){
    ticTacBoard.style.pointerEvents = 'none';
    winDiv.style.visibility = 'visible';
  }
  //Diagonal Right to Left Computer(Up Slope) 
  if(bottomLeftBox.innerHTML == computer && topRightBox.innerHTML == computer && middleMiddleBox.innerHTML == computer){
    ticTacBoard.style.pointerEvents = 'none';
    lossDiv.style.visibility = 'visible';
  }
}

CSS:

#setup{
  background-color:white;
  height:75vh;
  width:75vw;
}
#ticTacBoard{
  text-transform:capitalize;
  font-size:0vw;
  background-color:white;
  visibility:hidden;
  position:absolute;
  top:2vh;
}
#winDiv{
  visibility:hidden;
  background-color:white;
  position:relative;
  border:2px solid black;
}
#lossDiv{
  visibility:hidden;
  background-color:white;
  position:relative;
  border:2px solid black;
}
#tieDiv{
  visibility:hidden;
  background-color:white;
  position:relative;
  border:2px solid black;
}
#topLeft{
  display:inline-block;
  padding:30px;
  border-right:2px solid black;
  border-bottom:2px solid black;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#topLeft:hover{
  background-color:lightgrey;
}
#topMiddle{
  display:inline-block;
  padding:30px;
  border-bottom:2px solid black;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#topMiddle:hover{
  background-color:lightgrey;
}
#topRight{
  display:inline-block;
  padding:30px;
  border-left:2px solid black;
  border-bottom:2px solid black;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#topRight:hover{
  background-color:lightgrey;
}
#middleLeft{
  display:inline-block;
  padding:30px;
  border-right:2px solid black;
  border-bottom:2px solid black;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#middleMiddle:hover{
  background-color:lightgrey;
}
#middleMiddle{
  display:inline-block;
  padding:30px;
  border-bottom:2px solid black;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#middleLeft:hover{
  background-color:lightgrey;
}
#middleRight{
  display:inline-block;
  padding:30px;
  border-left:2px solid black;
  border-bottom:2px solid black;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#middleRight:hover{
  background-color:lightgrey;
}
#bottomLeft{
  display:inline-block;
  padding:30px;
  border-right:2px solid black;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#bottomLeft:hover{
  background-color:lightgrey;
}
#bottomMiddle{
  display:inline-block;
  padding:30px;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#bottomMiddle:hover{
  background-color:lightgrey;
}
#bottomRight{
  display:inline-block;
  padding:30px;
  border-left:2px solid black;
  width:15vw;
  height:15vh;
  font-size:9vw;
  cursor:pointer;
}
#bottomRight:hover{
  background-color:lightgrey;
}
body{
  background-color:grey;
}

2 个答案:

答案 0 :(得分:3)

发生这种情况是因为您的逻辑存在缺陷。我将拿一小部分代码(如下所示):

var computerMove = Math.floor(Math.random() * 9) + 1;
while(computerMove == 1 && (topLeftBox.innerHTML == 'o' || topLeftBox.innerHTML == 'x')){
  computerMove = Math.floor(Math.random() * 9) + 1;
}
 while(computerMove == 2 && (topMiddleBox.innerHTML == 'o' || topMiddleBox.innerHTML == 'x')){
   computerMove = Math.floor(Math.random() * 9) + 1;
}

请考虑以下情况:代码的第一行生成computerMove = 1 ,并且 topLeftBox已经用'x'或'o'填充了(没关系)。然后,我们转到第二行(第一个while循环)。因为它检测到topLeftBox已被填充,所以它将随机化一个数字。假设随机化得到computerMove = 2。然后,由于computerMove不再是1,因此第一个while循环退出,进入第二个while循环。为了这个示例,我们假设topMiddleBox也已经用'x'或'o'填充。它满足循环条件,因此,它使数字随机化。假设它随机化computerMove = 1。要求computerMove的值为2的第二个循环条件未满足,因此退出循环。问题:它产生了computerMove的{​​{1}},并且1已经填充。那是您的代码失败的时候。

我还注意到您给了所有topLeftBox唯一的ID。但是,在这种特定情况下,您可以通过仅为所有div提供一个可以迭代的类来简化代码。请参见以下代码,该代码可以解决您的问题,并且在您的特定情况下,无需为每个div使用特定的ID:

JS

div

HTML(在let actionBox = document.querySelectorAll('div.action-box') function computerEasyModeMove() { let randomizeMove = () => Math.floor(Math.random() * 9) let computerMove = randomizeMove() computer = player == 'x' ? 'o' : 'x' while (actionBox[computerMove].innerHTML.trim() != '&nbsp;') { computerMove = randomizeMove() } actionBox[computerMove].innerHTML = computer actionBox[computerMove].style.pointerEvents = 'none' } 内部)

div#ticTacBoard

分叉的代码:here

答案 1 :(得分:3)

我还没有测试过,但是我认为如果将其更改为跟随它应该可以工作(将9 while循环替换为1 while循环)。想法是确保获取下一个随机单元格(如果已被占用)。

var computerMove = Math.floor(Math.random() * 9) + 1;
while (computerMove == 1 && (topLeftBox.innerHTML == 'o' || topLeftBox.innerHTML == 'x')
  || (computerMove == 2 && (topMiddleBox.innerHTML == 'o' || topMiddleBox.innerHTML == 'x'))
  || (computerMove == 3 && (topRightBox.innerHTML == 'o' || topRightBox.innerHTML == 'x'))
  || (computerMove == 4 && (middleLeftBox.innerHTML == 'o' || middleLeftBox.innerHTML == 'x'))
  || (computerMove == 5 && (middleMiddleBox.innerHTML == 'o' || middleMiddleBox.innerHTML == 'x'))
  || (computerMove == 6 && (middleRightBox.innerHTML == 'o' || middleRightBox.innerHTML == 'x'))
  || (computerMove == 7 && (bottomLeftBox.innerHTML == 'o' || bottomLeftBox.innerHTML == 'x'))
  || (computerMove == 8 && (bottomMiddleBox.innerHTML == 'o' || bottomMiddleBox.innerHTML == 'x'))
  || (computerMove == 9 && (bottomRightBox.innerHTML == 'o' || bottomRightBox.innerHTML == 'x'))) {
  computerMove = Math.floor(Math.random() * 9) + 1;
}