47086


JavaScriptの課題でfor文とif文を組み合わせたクイズアプリを製作しています。

処理の流れは以下のようなものを作りたいです。

  1. alertで１から５までの数値を当てるよう指示する（答えは2）
  2. okを押すとpromptで1から5までのどれかを入力するよう出てくる
  3. 外れると、間違っているので再度答えを入力するようにというpromptが出てくる
  4. 当たればalertで「おめでとう！」などのメッセージが現れゲームが終了する

for文についてどうしても理解が追いつかないのですが、for文は繰り返す回数が決まっている時に使うものですよね？この課題の場合確かに選択肢は5つしかないですが、2が当たるまでは無限に続くはずですよね？それをどうやってfor文で表せばいいのかさっぱりわかりません。  
またfor/for in/for ofのどれを使うべきなのかも不明です…

そして今のコードのままだと、何を入力しても `prompt ('Please guess 1 to 5!')` が表示される状況になっています。

いつもはメンターの方がいらっしゃるのですがその方がホリデーでいらっしゃらず、どなたかお力貸していただけると幸いです。よろしくお願いします。

下に自力で書いてみたコードがありますが全然違う気がしてるので都度指摘して頂けると助かります。

[code]

    // alertで'You got 5 guesses. Guess 1 to 5'と言うメッセージを表示させ、１から５までの数値を当てるよう指示する。
            alert ('You got 5 guesses. Guess 1 to 5');
    
    // 答えの数値を2で用意
            let correctAnswer = 2;
            let wrongAnswers = [1, 3, 4, 5]
    
    // promptで'What do you guess?'と言うメッセージとともに、記入欄を表示させる
            let result = prompt('What do you guess?');
            console.log(result);
    
    // forループで１から５までの数値で、答えの2が当たるまで推測を促すpromptを表示させる。
    // ヒント１：if文とも組み合わせて、推測が当たった場合はalertで'Good job! See what happens next :)'を表示。当たったらゲーム終了にする。
    // ヒント２：外れたらpromptで'Ops! Maybe, another try?'のメッセージとともに記入欄を表示。
    
            for (;;) {
                if (result === correctAnswer) {
                    alert ('Good job! See what happens next :)');
                    break;
                } else if (result === wrongAnswers) {
                    prompt ('Ops! Maybe, another try?');
                } else {
                    prompt ('Please guess 1 to 5!')
                }
            }
[/code]


CC BY-SA 4.0
2018-07-29T20:01:32.463
47083
2023-05-31T11:10:04.843
2023-05-24T13:30:55.180
3060
29490
question
javascript
for文とif文を組み合わせたクイズアプリ


まず、プログラミングのためにやることをきちんと箇条書きするのは良いことなのですが、いくつか気をつけたほうが良いでしょう。

  * 繰り返す範囲は明示する
  * 「主語」を省略しない

あなたの現在のコードにあうように詳細化するとこうなります。

[code]

    <1>alertで１から５までの数値を当てるよう指示する（答えは2）
    <2>okを押すとpromptで1から5までのどれかを入力するよう出てくる
    【繰り返しの範囲開始】
        <3><2>で入力した値が外れだと、間違っているので再度答えを入力するようにというpromptが出てくる
        <4><2>で入力した値が当たりだと、alertで「おめでとう！」などのメッセージが現れゲームが終了する
    【繰り返しの範囲終了】
    
[/code]

あなたのコードでは変数`result`の値が<2>の後、2度と書き換えられませんから、常に<2>の`prompt`で入力した値が正解かどうか判定しようとしています。

[code]

    <1>alertで１から５までの数値を当てるよう指示する（答えは2）
    <2>okを押すとpromptで1から5までのどれかを入力するよう出てくる
    【繰り返しの範囲開始】
        <3>最後に入力した値が外れだと、間違っているので再度答えを入力するようにというpromptが出てくる
        <4>最後に入力した値が当たりだと、alertで「おめでとう！」などのメッセージが現れゲームが終了する
    【繰り返しの範囲終了】
    
[/code]

`prompt`を呼び出すたびにその値で`result`を置き換えれば、`result`が「最後に入力した値」として使えるはずです。(なかなか微妙な変数名ですが、話が長くなりすぎるので、そこは置いておきます。)

* * *

さらにJavaScriptでの基本テクニックとしていくつかの問題点があります。

  * 文字列(`prompt`の戻り値)と数値(`2`)とを`===`(型変換のない厳密比較)で比較している

(結果は常に`false`になる。)

  * 配列のどれかに一致するかの判定に`===`を用いている

(これまた常に`false`です。日本語の「〜が〜である」的な文がいつでも`===`で表現できるわけではありません。)

「配列の中のどれかに一致」には、`indexOf`がよく使われます。使い方はコード参照。

`==`比較(文字列と数値の比較の時、自動的に数値型に変換してくれる)とか、文字列を数値型に変換する方法なんかも覚えておくと良いのですが、ここでは元の答えを全部文字列型で用意しておく、という形にしてみました。

[code]

    // alertで'You got 5 guesses. Guess 1 to 5'と言うメッセージを表示させ、１から５までの数値を当てるよう指示する。
    alert ('You got 5 guesses. Guess 1 to 5');
    
    // 答えの数値を2で用意
    //### `prompt`の結果は文字列なので答えも文字列で用意しておく。
    let correctAnswer = '2';
    let wrongAnswers = ['1', '3', '4', '5'];
    
    // promptで'What do you guess?'と言うメッセージとともに、記入欄を表示させる
    let result = prompt('What do you guess?');
    console.log(result);
    
    // forループで１から５までの数値で、答えの2が当たるまで推測を促すpromptを表示させる。
    // ヒント１：if文とも組み合わせて、推測が当たった場合はalertで'Good job! See what happens next :)'を表示。当たったらゲーム終了にする。
    // ヒント２：外れたらpromptで'Ops! Maybe, another try?'のメッセージとともに記入欄を表示。
    
    for (;;) {
        if( result === correctAnswer ) {
            alert('Good job! See what happens next :)');
            break;
        } else if( wrongAnswers.indexOf(result) >= 0 ) {
            //###`result`が常に「最後に入力した値」になるよう更新する
            result = prompt('Ops! Maybe, another try?');
        } else {
            //###`result`が常に「最後に入力した値」になるよう更新する
            result = prompt('Please guess 1 to 5!');
        }
    }
[/code]

* * *

なんでこれが`for`文の課題なのかとか、コメント中の「forループで１から５までの数値で、…」については、出題者の意図が全然理解できないので、出題者の思っている通りの回答になっているかどうかは全然自信がないのですが、あなたの現在の意図に沿った動きにはなっているのではないかと思います。


CC BY-SA 4.0
2018-07-30T00:04:08.997
47084
2018-07-30T00:11:34.827
2018-07-30T00:11:34.827
13972
13972
47083
answer


この課題は、JavaScriptの`for`を理解するための良い課題だと思います。初心者には「for文は繰り返す回数が決まっている時に使うもの」と思われがちですが、そうではありません。

[MDNのforの説明](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for)では、以下のようになっています。

> for 文はループを作ります。丸括弧で囲まれセミコロンで分けられた、3 つの省略可能な式と、その後にループ内で実行される文が構成されます。
>
> 構文  
>  for ([initialization]; [condition]; [final-expression]) statement

それで、`for(;;)`と式を全て省略すれば、`while(true)`と同じになるし、`for(; a >
0;)`と条件のみを記述すれば、`while(a > 0)`と同じになります。普通に考えているよりも`for`は弾力的に使うことができます。

`for`には初期化と条件の式を書くことができるので、次のようなコードにしてみたらどうでしょうか。

[code]

    alert ('You got 5 guesses. Guess 1 to 5');
    let correctAnswer = '2';
    let wrongAnswers = ['1', '3', '4', '5'];
    
    for (let result = prompt('What do you guess?'); result !== correctAnswer;) {
        if(result in wrongAnswers) {
            result = prompt('Ops! Maybe, another try?');
        } else {
            result = prompt('Please guess 1 to 5!');
        }
    }
    
    alert('Good job! See what happens next :)');
[/code]


CC BY-SA 4.0
2018-07-30T01:29:23.533
47086
2018-07-30T03:43:35.987
2018-07-30T03:43:35.987
15171
15171
47083
answer