Javascript - Math.random函数在for循环中调用时返回相同的结果

时间:2017-12-28 21:12:11

标签: javascript loops for-loop

我有function{computerPlay()}每次调用时都会生成一个新的随机数。它返回顶部声明的数组中的项。当我在console中测试它时,我的工作方式非常有用。但是,为了让我的游戏正常工作,我已将它放在for循环中,除非我刷新页面,否则它会保持返回相同的值。我无法在任何地方找到答案,这是我的第一个问题。我确定代码很草率所以请忽略它。这是代码。



  let playOptionsArray = ["Rock", "Paper", "Scissors"];
let totalTies = 0;
let playerPoints = 0;
let computerPoints = 0;
let round = 1;

//formats a player's entry so it will match playOptionsArray
  function firstLetterUppercase(string){
    let firstLetter = string.charAt(0);
    let firstLetterCapitalized = firstLetter.toUpperCase();
    let restOfResponse = string.slice(1);
    let formattedResponse = firstLetterCapitalized + restOfResponse;
    return formattedResponse;
  }

//compares player entry to ensure it matches an item on the playOptions array
  function checkPlayerResponse(response){
    if (response === "Rock" || response === "Paper" || response === "Scissors") {
      return response;
    } else {
      return alert("You must choose either 'Rock', 'Paper', or 'Scissor' as your play. Please try again.");
    }
  }

//generates a random option for the computer's play

  function computerPlay() {
    let computerSelection = playOptionsArray[Math.floor(Math.random()*(playOptionsArray.length))];
    return computerSelection;
  }

  let computerSelection = computerPlay();

  function getPlayerSelection() {
    let playerEntry = window.prompt("You are playing the computer in a game of Rock, Paper, Scissors. First player to five points wins. Choose either Rock, Paper, or Scissors as your play", "Rock");
    if (playerEntry != null) {
    let playerEntryLowercase = playerEntry.toLowerCase();
    playerSelection = firstLetterUppercase(playerEntryLowercase);
  } else {
    getPlayerSelection();
  }
    checkPlayerResponse(playerSelection);
    return playerSelection;
  }

  let playerSelection = getPlayerSelection;

//emulates a single round of rock paper scissor
  function singleRound(){
    if (playerSelection === "Rock" && computerSelection === "Scissors"){
      alert('You have won this round. The computer chose ' + computerSelection + '.');
      playerPoints++;
      round++;
    } else if (playerSelection === "Scissors" && computerSelection === "Paper"){
      alert('You have won this round. The computer chose ' + computerSelection + '.');
      playerPoints++;
      round++
    } else if (playerSelection === "Paper" && computerSelection === "Rock"){
      alert('You have won this round. The computer chose ' + computerSelection + '.');
      playerPoints++;
      round++
    } else if (playerSelection === computerSelection){
      alert('You have tied this round. The computer chose ' + computerSelection + '.');
      totalTies++;
    } else {
      alert('Something went wrong. Refresh the page.')
    }
  }

  function updateScore() {
    document.getElementById("player-points").innerHTML = playerPoints;
    document.getElementById("round").innerHTML = round;
    document.getElementById("computer-points").innerHTML = computerPoints;
    document.getElementById("total-ties").innerHTML = totalTies;
  }

//keeps track of player points and ends when a player gets 5 points
 function game() {
    for (round = 0; computerPoints < 5 && playerPoints < 5; round) {
      getPlayerSelection();
      computerPlay();
      singleRound();
      updateScore();
      }
  }

game();
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:1)

您的问题是两个众所周知的错误来源的组合:variable shadowingglobal state

在JavaScript中,每个函数都会创建一个新范围:

      Part_12  Part_13  Part_28  Part_34  Part_51
ID                                               
1202        0        0        0        0        0
9321        1        0        0        1        0
3832        2        0        0        1        0
1723        0        1        1        0        1

内部范围可以从外部访问内容(您仍然可以在函数内部看到var foo = 3; function() { var bar = 2; }; console.log(foo + bar); // ERROR, bar is local to the function ),但不能反过来。当您在内部作用域中声明与外部相同的名称时,会发生阴影:

foo

如果省略声明(即var,let,const),程序会搜索范围以找到它:

var foo = 3;
(function() {
  var foo = 2;
  console.log(foo); // 2
})();
console.log(foo); // 3 the outer foo isn't change by the inner.

如果您不以这种方式混合示波器,则无法解决此问题。解决问题的最简单方法是防止它发生。修改var foo = 3; (function() { foo = 2; // will reach up to the outer foo })(); console.log(foo); // 2 函数以获取两个参数:

singleRound

现在当你在循环中调用它时:

function singleRound(computerSelection, playerSelection) {
  // everything else the same
}

当您使用返回值时,您可以轻松地出错。

答案 1 :(得分:0)

returns['MORET']的返回值不会存储在循环中的任何位置。 (请注意,您的computerPlay也会发生这种情况)。尝试

&#13;
&#13;
playerSelection
&#13;
&#13;
&#13;

编辑:@ kavakava的回答提供了一些有关为何情况的见解。

答案 2 :(得分:0)

function computerPlay() {
    let computerSelection = playOptionsArray[
            Math.floor(Math.random()*(playOptionsArray.length))
         ]; // Line #1

     return computerSelection;
}

let computerSelection = computerPlay(); // Line: #2

这似乎是你的问题。它永远不会改变的原因是因为你从未改变它。删除第1行上的'let',你应该全部设置好。您在计算机播放中返回了var,而不是全局。