如何使用 JavaScript 中的 DOM 使石头剪刀布游戏在回合之间前进?

问题描述 投票:0回答:1

我正在用 JavaScript 制作石头、剪刀、布游戏,但我陷入了困境。问题是我无法使循环工作以允许我在游戏中玩 5 轮、保留轮计数器并更新分数。该游戏是为了练习 DOM 操作。

最后,我希望程序能够给我最终分数,并向用户发送一条消息,通知他们是赢了还是输了。

我正在与您分享我的完整代码。

let humanScore = 0
let computerScore = 0
let rounds = 0;

const getComputerChoice = () => {
  const items = ["rock", "paper", "scissors"];
  const randomItems = items[(Math.floor(Math.random() * items.length))];
  return randomItems;
}

const getHumanChoice = () => {
  return new Promise((resolve) => {
    const rockSelection = document.querySelector("#rock");
    const paperSelection = document.querySelector("#paper");
    const scissorsSelection = document.querySelector("#scissors");

    rockSelection.addEventListener("click", () => {
      rockSelection.setAttribute("class", "animation");
      resolve("rock"), {
        once: true
      };
    });

    paperSelection.addEventListener("click", () => {
      paperSelection.setAttribute("class", "animation");
      resolve("paper"), {
        once: true
      };
    });

    scissorsSelection.addEventListener("click", () => {
      scissorsSelection.setAttribute("class", "animation");
      resolve("scissors"), {
        once: true
      };
    });
  });
}


const playRound = (humanChoice, computerChoice) => {
  const textResponse = document.querySelector("#display");
  const para = document.createElement("p");
  para.classList.add("para");
  para.textContent = "";
  textResponse.appendChild(para);

  if (humanChoice == "rock" && computerChoice == "scissors") {
    para.textContent = `You win! ${humanChoice} 🗿 beats ${computerChoice} ✂️`;
    humanScore++;
  } else if (humanChoice == "scissors" && computerChoice == "paper") {
    para.textContent = `You win! ${humanChoice} ✂️ beats ${computerChoice} 🧻`;
    humanScore++;
  } else if (humanChoice == "paper" && computerChoice == "rock") {
    para.textContent = `You win! ${humanChoice} 🧻 beats ${computerChoice} 🗿`;
    humanScore++;
  } else if (humanChoice === computerChoice) {
    para.textContent = `You draw! 😐. The computer choose ${computerChoice} too!`;
  } else {
    para.textContent = `You lose! 😩. The computer choose ${computerChoice}`;
    computerScore++;
  }
}

const playGame = async() => {

  const humanChoice = await getHumanChoice();
  const computerChoice = getComputerChoice();

  playRound(humanChoice, computerChoice);

  const score = document.querySelector("#score");
  const newPara = document.createElement("p");
  newPara.classList.add("Score");
  newPara.textContent = `ROUND ${rounds}: You ${humanScore},
    The computer: ${computerScore}`;
  score.appendChild(newPara);

  if (rounds < 5) {
    const nextDiv = document.createElement("div");
    const nextRound = document.createElement("button");
    nextDiv.classList.add("nextDiv");
    nextRound.classList.add("button");
    nextRound.textContent = "Next round";
    newPara.appendChild(nextDiv);
    nextDiv.appendChild(nextRound);

    return new Promise((resolve) => {
      nextRound.addEventListener("click", () => {
        resolve();
      }, {
        once: true
      });
    });
  }
};

const loopRounds = async() => {
  while (rounds < 5) {
    rounds++;
    await playGame()
  }

  const finalMessage = document.createElement("p");
  if (humanScore > computerScore) {
    finalMessage.textContent = "You are the best!";
  } else if (humanScore < computerScore) {
    finalMessage.textContent = "You are the worst in the world!";
  } else {
    finalMessage.textContent = "It's a draw!"
  }

  document.querySelector("#score").appendChild(finalMessage);

}

loopRounds();
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Piedra Papel y tijera</title>
  <style>
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    
    #botones {
      display: flex;
      gap: 10px;
      justify-content: center;
      align-items: center;
      height: 100px;
    }
    
    .animation {
      background-color: #5240F5;
    }
    
    #title {
      display: flex;
      justify-content: center;
    }
    
    #subTitle {
      display: flex;
      justify-content: center;
    }
    
    button {
      font-size: 20px;
      font-weight: bold;
      border-radius: 5px;
      border: none;
      padding: 10px;
      background-color: #3FA2F6;
      color: white;
    }
    
    #display {
      display: flex;
      justify-content: center;
    }
    
    #score {
      display: flex;
      justify-content: center;
    }
    
    .Score {
      justify-content: center;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      font-weight: bold;
      font-size: 25px;
    }
    
    .para {
      justify-content: center;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      font-weight: bold;
      font-size: 25px;
    }
    
    .nextDiv {
      display: flex;
      justify-content: center;
      margin: 15px;
    }
  </style>
</head>

<body>
  <div id="title">
    <h1>🗿🧻✂️Rock, Paper and Scissors 🗿🧻✂️</h1>
  </div>
  <div id="subTitle">
    <h2>Pick an option 👇</h2>
  </div>

  <div id="botones">
    <button id="rock" value="Rock">Rock</button>
    <button id="paper" value="Paper">Paper</button>
    <button id="scissors" value="Scissors">scissors</button>
  </div>

  <div id="display"></div>
  <div id="score"></div>
  <script src="codigo.js"></script>
</body>

</html>

javascript dom
1个回答
0
投票

getHumanChoice 内的事件监听器设置错误。

事情应该是这样的:

rockSelection.addEventListener("click", () => {
  rockSelection.setAttribute("class", "animation");
  resolve("rock")
}, {
  once: true
});

paperSelection.addEventListener("click", () => {
  paperSelection.setAttribute("class", "animation");
  resolve("paper")
}, {
  once: true
});

scissorsSelection.addEventListener("click", () => {
  scissorsSelection.setAttribute("class", "animation");
  resolve("scissors")
}, {
  once: true
});

我想添加一些代码审查评论:

  1. while循环完全没有必要,我建议你在
    loopRounds
    结束时调用
    playGame
    并检查计数
  2. 将事件侦听器移至顶层
  3. 不解决承诺,而是调用
    playGame
    函数并传递所选选项
  4. 删除
    once
    属性,如果您已将事件侦听器移至顶层,则强制仅执行一次事件侦听器是没有意义的
  5. 删除承诺,对于您的实际代码和项目来说,这是不必要的,而且只会使其变得过于复杂

希望这对您有帮助,编码愉快

© www.soinside.com 2019 - 2024. All rights reserved.