尝试在 JS Rock、Paper、Scissors 游戏中设置一个 span 元素等于一个变量值

IT技术 javascript html dom
2021-03-22 09:05:59

我正在编写一个程序来玩石头,纸,剪刀。在我编码时,一切都很顺利,直到我添加了:

userScore_span.InnerHTML = userScore;

线。在测试 win 功能时,我添加了一个 console.log('you win'); 它工作正常,但是一旦我从上面添加了一行,当我按下三个按钮中的任何一个时,我就会出错。

我试图将结果从 userScore 传递到 userScore_span,因为在赢得比赛后 userScore 会增加

userScore++;
userScore_span.innerHTML = userScore;

但是,当我按下任何按钮时,出现以下错误:

Uncaught TypeError: Cannot set property 'innerHTML' of null
at lose (app.js:34)
at game (app.js:58)

我不确定 chrome Dev 工具是什么意思。如何解决这个问题?

let userScore = 0;
let computerScore = 0;
const userScore_span = document.getElementById("user-score");
const computerScore_span = document.getElementById("computer-score");
const scoreBoard_div = document.querySelector(".score-board");
const result_p = document.querySelector(".result > p");
const rock_div = document.getElementById('r');
const paper_div = document.getElementById('p');
const scissors_div = document.getElementById('s');

function getComputerChoice() {
  const choices = ['r', 'p', 's'];
  const randomNumber = (Math.floor(Math.random() * 3));
  return choices[randomNumber];
}

function convertToWord(letter) {
  if (letter === "r") return "Rock";
  if (letter === "p") return "Paper";
  return "Scissors";
}

function win(userChoice, computerChoice) {
  userScore++;
  userScore_span.innerHTML = userScore;
  computerScore_span.innerHTML = computerScore;
  const smallUserWord = "user".fontsize(3).sub();
  const smallCompWord = "comp".fontsize(3).sub();
  result_p.innerHTML = `${convertToWord(userChoice)}${smallUserWord} beats ${convertToWord(computerChoice)}${smallCompWord}. You win!`;
}

function lose(userChoice, computerChoice) {
  computerScore++;
  userScore_span.innerHTML = userScore;
  computerScore_span.innerHTML = computerScore;
  const smallUserWord = "user".fontsize(3).sub();
  const smallCompWord = "comp".fontsize(3).sub();
  result_p.innerHTML = `${convertToWord(userChoice)}${smallUserWord} loses to ${convertToWord(computerChoice)}${smallCompWord}. You lost!`;
}

function draw(userChoice, computerChoice) {
  const smallUserWord = "user".fontsize(3).sub();
  const smallCompWord = "comp".fontsize(3).sub();
  result_p.innerHTML = `${convertToWord(userChoice)}${smallUserWord} equals ${convertToWord(computerChoice)}${smallCompWord}. It's a draw`;
}

function game(userChoice) {
  const computerChoice = getComputerChoice();
  switch (userChoice + computerChoice) {
    case "rs":
    case "pr":
    case "sp":
      win(userChoice, computerChoice);
      break;
    case 'rp':
    case 'ps':
    case 'sr':
      lose(userChoice, computerChoice);
      break;
    case 'rr':
    case 'pp':
    case 'ss':
      draw(userChoice, computerChoice);
      break;
  }
}

function main() {
  rock_div.addEventListener('click', function() {
    game('r');
  })
  paper_div.addEventListener('click', function() {
    game('p');
  })
  scissors_div.addEventListener('click', function() {
    game('s');
  })
};

main();
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: #24272E;
  font-family: avenir;
}

header {
  background: white;
  padding: 20px;
}


/*header each one*/

header>h1 {
  color: #24272E;
  text-align: center;
}

.score-board {
  border: 3px solid white;
  border-radius: 4px;
  width: 200px;
  margin: 20px auto;
  /*20px (top/bottom) & center (left/right) */
  color: white;
  padding: 15px 20px;
  text-align: center;
  font-size: 46px;
  position: relative;
}

.badge {
  background: #E2584D;
  font-size: 14px;
  padding: 2px 10px;
}

#user-label {
  position: absolute;
  top: 30px;
  left: -25px;
}

#computer-label {
  position: absolute;
  top: 30px;
  right: -30px;
}

.result {
  font-size: 40px;
  color: white;
}

.result>p {
  text-align: center;
  font-weight: bold;
}

.choices {
  text-align: center;
  margin-top: 50px;
}

.choice {
  display: inline-block;
  border: 4px solid white;
  border-radius: 50%;
  padding: 10px;
  margin: 0 20px;
  transition: all 0.3s ease;
}

.choice:hover {
  cursor: pointer;
  background: darkblue;
}

img {
  height: 100px;
  width: 100px;
}

#action-message {
  text-align: center;
  color: white;
  font-weight: bold;
  font-size: 20px;
  margin-top: 20px
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Rock Paper Scissors</title>
  <meta name="description" content="DESCRIPTION">
  <link rel="stylesheet" href="styles.css">

</head>

<body>
  <header>
    <h1>Rock Paper Scissors</h1>
  </header>
  <div class="score-board">
    <div id="user-label" class="badge">user</div>
    <div id="computer-label" class="badge">comp</div>
    <span idea="user-score">0</span>:<span idea="computer-score">0</span>
  </div>

  <div class="result">
    <p>Paper cover rock. You win!</p>
  </div>

  <div class="choices">
    <div class="choice" id="r">
      <img src="images/rock.png" alt="rock">
    </div>
    <div class="choice" id="p">
      <img src="images/paper.png" alt="paper">
    </div>
    <div class="choice" id="s">
      <img src="images/scissors.png" alt="scissors">
    </div>
  </div>

  <p id="action-message">Make your move</p>






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

</html>

2个回答

除了你的错别字idea=/ id=...
你可以通过使用索引整数来大大缩小你的游戏逻辑和代码

整数游戏

  • data-*用户按钮的使用属性。属性应该包含数值0, 1, 2单击时,该值将代表玩家的选择。
  • AI 也应该玩数字: const AI = ~~(Math.random() * 3) // 0, 1, 2

现在你知道AI和玩家都使用整数(而不是奇怪的字母组合),您可以将存储移动名字到一个数组 const moves = ["Rock", "Paper", "Scissors"];(其中0岩石...等)

石头剪刀布逻辑

游戏有三种可能的回合分辨率PL 获胜,AI 获胜,Draw让我们以相同的顺序将这些“人类”转换为整数:

  • 0 = PL赢
  • 1 = 人工智能获胜
  • 2 = 抽奖

以下是计算这些的方法:

计算平局是最简单的。这是当两者AIPL整数相等时。让我们回来2

result = PL === AI ? 2

玩家获胜

要计算玩家获胜,只需将AI 选择增加 1 并取模 3如果这个操作的结果等于玩家的选择,那么玩家一定赢了!让我们回来0

人工智能获胜

否则,由于我们的游戏只有 3 种可能的状态,所以它不是平局,也不是​​玩家赢,而是必须是 AI 赢!让我们回来1

const result = PL===AI ? 2 : (AI+1)%3 === PL? 0 : 1; // Possible results: 0, 1, 2

拥有基于游戏结果索引的很酷的事情是,现在您还可以使用类似的消息数组messages = ["You won!", "AI won", "it's a draw!", ]通过结果索引获取所需的消息!. 还有奖金!您还可以增加score数组值,0作为玩家的索引和1AI!

const moves = ["Rock", "Paper", "Scissors"],
  messages  = ["You won!", "AI won", "It's a draw!"], // [PL, AI, draw]
  score     = [0, 0, 0],                              // [PL, AI, draw]
  EL = sel => document.querySelector(sel),
  EL_result  = EL("#result"),
  EL_PLScore = EL("#PLScore"),
  EL_AIScore = EL("#AIScore");

function game() {
  const PL = +this.dataset.playermove;  // Get dataset value as integer
  const AI = ~~(Math.random() * 3);     // All you need: 0, 1, 2
  const result = PL === AI ? 2 : (AI + 1) % 3 === PL ? 0 : 1; // 0=PLwins 1=AIwins 2=draw 

  score[result]++; // Increment PL or AI's score (Increments number of draws too ;) )
  EL_result.innerHTML = `You: ${moves[PL]}<br>AI: ${moves[AI]}<br>${messages[result]}`;
  EL_PLScore.textContent = score[0];
  EL_AIScore.textContent = score[1];
}

// EVENTS:
document.querySelectorAll("[data-playermove]")
  .forEach(el => el.addEventListener("click", game));
<button data-playermove="0">ROCK</button>
<button data-playermove="1">PAPER</button>
<button data-playermove="2">SCISSORS</button>

<br>

YOU | <span id="PLScore">0</span>:<span id="AIScore">0</span> | AI

<div id="result"></div>

另外,你没有解释你的意图,你只是把你的实现变成了文字。如果你想让人们了解你的实施背后的原因,你需要解释你的思考过程,即每个人都不清楚为什么(AI + 1) % 3 === PL人工智能获胜。
2021-04-24 09:05:59
+String并且~~(float)当然可以分别转换为和“铺平”一个数字,但为了提高可读性,我建议在这些情况下使用Number(String)Math.floor(float)
2021-04-30 09:05:59

错别字:idea<>id

改变这个:

<span idea="user-score">0</span>:<span idea="computer-score">0</span>

<span id="user-score">0</span>:<span id="computer-score">0</span>

let userScore = 0;
let computerScore = 0;
const userScore_span = document.getElementById("user-score");
const computerScore_span = document.getElementById("computer-score");
const scoreBoard_div = document.querySelector(".score-board");
const result_p = document.querySelector(".result > p");
const rock_div = document.getElementById('r');
const paper_div = document.getElementById('p');
const scissors_div = document.getElementById('s');

function getComputerChoice() {
  const choices = ['r', 'p', 's'];
  const randomNumber = (Math.floor(Math.random() * 3));
  return choices[randomNumber];
}

function convertToWord(letter) {
  if (letter === "r") return "Rock";
  if (letter === "p") return "Paper";
  return "Scissors";
}

function win(userChoice, computerChoice) {
  userScore++;
  userScore_span.innerHTML = userScore;
  computerScore_span.innerHTML = computerScore;
  const smallUserWord = "user".fontsize(3).sub();
  const smallCompWord = "comp".fontsize(3).sub();
  result_p.innerHTML = `${convertToWord(userChoice)}${smallUserWord} beats ${convertToWord(computerChoice)}${smallCompWord}. You win!`;
}

function lose(userChoice, computerChoice) {
  computerScore++;
  userScore_span.innerHTML = userScore;
  computerScore_span.innerHTML = computerScore;
  const smallUserWord = "user".fontsize(3).sub();
  const smallCompWord = "comp".fontsize(3).sub();
  result_p.innerHTML = `${convertToWord(userChoice)}${smallUserWord} loses to ${convertToWord(computerChoice)}${smallCompWord}. You lost!`;
}

function draw(userChoice, computerChoice) {
  const smallUserWord = "user".fontsize(3).sub();
  const smallCompWord = "comp".fontsize(3).sub();
  result_p.innerHTML = `${convertToWord(userChoice)}${smallUserWord} equals ${convertToWord(computerChoice)}${smallCompWord}. It's a draw`;
}

function game(userChoice) {
  const computerChoice = getComputerChoice();
  switch (userChoice + computerChoice) {
    case "rs":
    case "pr":
    case "sp":
      win(userChoice, computerChoice);
      break;
    case 'rp':
    case 'ps':
    case 'sr':
      lose(userChoice, computerChoice);
      break;
    case 'rr':
    case 'pp':
    case 'ss':
      draw(userChoice, computerChoice);
      break;
  }
}

function main() {
  rock_div.addEventListener('click', function() {
    game('r');
  })
  paper_div.addEventListener('click', function() {
    game('p');
  })
  scissors_div.addEventListener('click', function() {
    game('s');
  })
};

main();
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: #24272E;
  font-family: avenir;
}

header {
  background: white;
  padding: 20px;
}


/*header each one*/

header>h1 {
  color: #24272E;
  text-align: center;
}

.score-board {
  border: 3px solid white;
  border-radius: 4px;
  width: 200px;
  margin: 20px auto;
  /*20px (top/bottom) & center (left/right) */
  color: white;
  padding: 15px 20px;
  text-align: center;
  font-size: 46px;
  position: relative;
}

.badge {
  background: #E2584D;
  font-size: 14px;
  padding: 2px 10px;
}

#user-label {
  position: absolute;
  top: 30px;
  left: -25px;
}

#computer-label {
  position: absolute;
  top: 30px;
  right: -30px;
}

.result {
  font-size: 40px;
  color: white;
}

.result>p {
  text-align: center;
  font-weight: bold;
}

.choices {
  text-align: center;
  margin-top: 50px;
}

.choice {
  display: inline-block;
  border: 4px solid white;
  border-radius: 50%;
  padding: 10px;
  margin: 0 20px;
  transition: all 0.3s ease;
}

.choice:hover {
  cursor: pointer;
  background: darkblue;
}

img {
  height: 100px;
  width: 100px;
}

#action-message {
  text-align: center;
  color: white;
  font-weight: bold;
  font-size: 20px;
  margin-top: 20px
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Rock Paper Scissors</title>
  <meta name="description" content="DESCRIPTION">
  <link rel="stylesheet" href="styles.css">

</head>

<body>
  <header>
    <h1>Rock Paper Scissors</h1>
  </header>
  <div class="score-board">
    <div id="user-label" class="badge">user</div>
    <div id="computer-label" class="badge">comp</div>
    <span id="user-score">0</span>:<span id="computer-score">0</span>
  </div>

  <div class="result">
    <p>Paper cover rock. You win!</p>
  </div>

  <div class="choices">
    <div class="choice" id="r">
      <img src="images/rock.png" alt="rock">
    </div>
    <div class="choice" id="p">
      <img src="images/paper.png" alt="paper">
    </div>
    <div class="choice" id="s">
      <img src="images/scissors.png" alt="scissors">
    </div>
  </div>

  <p id="action-message">Make your move</p>






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

</html>