2017-12-28 11 views
1

私はfunction{computerPlay()}を呼び出して、呼び出すたびに新しい乱数を生成します。上に宣言された配列から項目を返します。それは私がconsoleでそれをテストするときにそれをどのようにしたいと思うか動作します。しかし、私のゲームが正常に動作するためには、私はそれをforループに入れて、ページを更新しない限り同じ値を返し続けます。私はどこでも答えを見つけることができず、これが私の最初の質問です。私はコードが不調だと確信しているので、無視してください。ここにコードがあります。Javascript - forループで呼び出されているときにMath.random関数が同じ結果を返します

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();

+9

必須の乱数漫画http://dilbert.com/strip/2001-10-25 – j08691

+1

'game'では' computerPlay'から返された値で何もしません。それは意図的なのでしょうか? – Andy

+7

あなたは 'computerPlay'を呼び出し続けますが、あなたのラウンドのスコアリングは一度だけ設定するグローバル変数' computerSelection'をチェックします(関数内のローカル 'computerSelection'はグローバルをシャドウします)。おめでとう!あなたは副作用が悪いことを学んだだけです。燃えた手が最高のものを教える。 –

答えて

0

computerPlayからあなたの戻り値は、ループ内の任意の場所に保存されていません。 (これはあなたのplayerSelectionでも起こっていることに注意してください)。

for (round = 0; computerPoints < 5 && playerPoints < 5; round) { 
 
    playerSelection = getPlayerSelection(); 
 
    computerSelection = computerPlay(); 
 
    singleRound(); 
 
    updateScore(); 
 
}

編集をお試しください:kavakavaの答え@これが事実である理由をいくつかの洞察を提供します。

+0

これは確かにうまくいくものですが、グローバルに更新するよりもエラーが起こりにくい方法がOPのように見えるかもしれません。 –

+0

@ JaredSmithループを修正することで実際にはより良い方法があると私は答えを書いた直後に気付きました。更新して、私の答えをもう一度チェックし、問題がまだ残っているかどうかを教えてください。ありがとう –

+0

グローバルな状態をチェックするのではなく、それらをパラメータとして取るように 'singleRound'を修正した' singleRound(computerPlay()、getPlayerSelection()) 'メソッドを返すと良いでしょう。 –

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

    return computerSelection; 
} 

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

これは問題のようです。変更していない理由は、変更していないからです。 1行目の 'let'を削除してください。あなたは、グローバルではなく、computerPlayでvarを返していました。

1

この問題は、よく知られている2つのエラー源の組み合わせ、つまりvariable shadowingglobal stateです。 JavaScriptで

は、各機能は、新しいスコープを作成します。

var foo = 3; 
function() { var bar = 2; }; 
console.log(foo + bar); // ERROR, bar is local to the function 

インナースコープは周りではなく、他の方法(あなたはまだ関数内fooを見ることができます)外部からのものにアクセスすることができます。シャドウイングは、あなたが外側と内側のスコープで同じ名前を宣言するときに何が起こるかです:

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、聞かせて、CONST)を省略した場合、プログラムはそれを見つけるためにスコープを通って上方に検索します。

このようにスコープを混ぜていない場合、この問題は発生しません。それを解決する最も簡単な方法は、起こらないようにすることです。今、あなたはループの中でそれを呼び出すとき

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

::2つのパラメータを取るためにあなたのsingleRound関数を変更し

singleRound(computerPlay(), getPlayerSelection()); 

あなたはあなたに簡単に間違って行くことができないの戻り値を使用する場合。

関連する問題