こんにちは朱夏です。
今回はJavaScriptの繰り返し(for文)を学習していきます。
同じ処理を5回繰り返したい。
だけど同じコードを5回も書くのは大変だな。
こんな時に使うのが繰り返し(for文)です。
今回はこの繰り返し(for文)を使って数当てゲームの回答回数の表示と、5回以内に正解しなかった場合、ゲーム終了になる様にしてみようと挑戦したのですが、予想通りに動く様にはなりませんでした。
失敗談も踏まえて、繰り返し(for文)について書いていきたいと思います。
それではやっていきましょう。
作成したコード
実行結果(失敗)
問題解決
あとがき
作成したコード
今回作成したコードは以下になります。
'use strict'; var hint = document.getElementById('hintbox'); var randomnumber = Math.floor(Math.random() * 100 + 1); document.getElementById('number').innerText = randomnumber + 'です'; for(var i = 1; i < 6; i++) { document.getElementById('buttonsubmit').addEventListener( 'click', () => { var inputnum = document.getElementById('exampleInputNum').value; document.getElementById('answer').innerText = inputnum; if(randomnumber == inputnum) { hint.insertAdjacentHTML("beforeend", i + '<p>正解です</p>'); } else if(randomnumber > inputnum) { hint.insertAdjacentHTML("beforeend", i + '<p>もっと大きいよ:回答' + inputnum + '</p>'); } else { hint.insertAdjacentHTML("beforeend", i + '<p>もっと小さいよ:回答' + inputnum + '</p>'); } }); }
前回作成したコードから、クリックイベント意向をfor文で括った感じです。
for文だけ見るとこんな感じです。
for(var i = 1; i < 6; i++) { ~ここに処理内容を書く~ }
for文は後ろの()内の情報を元に処理内容を繰り返します。
情報は”;”区切りで以下の意味を持っています。
- var i = 1 → 変数“i”の初期値を代入しています。
- i < 6 → 繰り返し条件。変数“i”が6未満だったら繰り返します。
- i++ → 繰り返す際の追加処理。“i = i + 1”と同じ動作をします。
今回のfor文の情報を翻訳すると以下のようになります。
なので、”i”が6以上になる前まで、1~5の5回、処理内容を繰り返すという意味になります。
処理内容の追記は、各表示させるテキストに回答回数“i”を追記する様にしました。
実行結果(失敗)
今回のコードを実行して、実際にテストプレイをやってみました。
結果はこんな感じです。
想定と違う動作をしている部分がいくつかありました。
- 1回実行しただけで5回分表示された
- 実行回数の表示が6になっている
この問題を解決していきたいと思います。
問題解決
最初に、エラーメッセージは発生していません。
このことを前提として問題を解決していきたいと思います。
結論を先に言ってしまうと、私のたどり着いた解決方法は「for文を使わない」でした。
その理由も含めて、まずは今回の問題を見ていきます。
今回発生した2つの問題で共通しているのは、「1回の動作で繰り返し処理が終わっている」事です。
特に2つ目の問題を見てみると、本来あり得ない「i=6」にカウントアップしているという状況が発生しています。
このことから、「ボタンをクリックする前に、繰り返し処理が終わっている」という仮説を立てました。
要するに、for文は「読み込まれた直後に出来ない処理はスキップして繰返しを終わらせてしまう」という仕様なのではないかということです。
試しにクリックイベントの内側を繰り返すようにfor文の位置を変えてみたところ、結果はこんな感じに変化しました。
この場合は「1回クリックしたら、処理を5回繰り返す」となるので想定通りの動きが出来ています。
その証拠に、実行回数が1~5までカウントアップしてそこで止まっています。
この問題を解決するべく、「クリックしたら処理を繰り返す」場合のfor文の使い方に関する情報をググってみたのですが、見つかりませんでした。
途中、ブロックスコープというものを発見したのですが、この情報は今の私のレベルではちょっと難しい様です。
というわけで、私が今回の解決方法として取った行動は、for文を使わない事でした。
では、どうやって回数制限を付けるのかというと、if文を使います。
コードをこんな感じで書き換えました。
'use strict'; var i = 0; var hint = document.getElementById('hintbox'); var randomnumber = Math.floor(Math.random() * 100 + 1); document.getElementById('buttonsubmit').addEventListener( 'click', () => { if(i == 4) { i++; var inputnum = document.getElementById('exampleInputNum').value; document.getElementById('answer').innerText = inputnum; if(randomnumber == inputnum) { hint.insertAdjacentHTML("beforeend", '<p class="mb-0">' + i + '回目</p>' + '<p>正解です</p>'); document.getElementById('number').innerText = '正解は' + randomnumber + 'です'; } else if(randomnumber > inputnum) { hint.insertAdjacentHTML("beforeend", '<p class="mb-0">' + i + '回目</p>' + '<p>もっと大きいよ:回答' + inputnum + '</p>'); } else { hint.insertAdjacentHTML("beforeend", '<p class="mb-0">' + i + '回目</p>' + '<p>もっと小さいよ:回答' + inputnum + '</p>'); } document.getElementById('number').innerText = '正解は' + randomnumber + 'です'; } else { i++; var inputnum = document.getElementById('exampleInputNum').value; document.getElementById('answer').innerText = inputnum; if(randomnumber == inputnum) { hint.insertAdjacentHTML("beforeend", '<p class="mb-0">' + i + '回目</p>' + '<p>正解です</p>'); document.getElementById('number').innerText = '正解は' + randomnumber + 'です'; } else if(randomnumber > inputnum) { hint.insertAdjacentHTML("beforeend", '<p class="mb-0">' + i + '回目</p>' + '<p>もっと大きいよ:回答' + inputnum + '</p>'); } else { hint.insertAdjacentHTML("beforeend", '<p class="mb-0">' + i + '回目</p>' + '<p>もっと小さいよ:回答' + inputnum + '</p>'); } } });
これで実装したかった機能は実装出来ました。
for文を使わなくても、というか使わない方法が正解だった気がします。
あとがき
というわけでfor文に振り回された話でした。
for文についてのまとめはこちら。
- 条件で決めた回数の処理を繰り返す
- 繰り返し処理は止まらない(重要)
- クリックイベントなどはスキップされる
こんな感じです。
そして解決策としてif文を使用しました。
最終的に5回目でゲームオーバーにする条件分岐を付ける必要があったので、これで良かった気がします。
とはいえ、コードを見てもらうと解る様に、同じ処理の塊を2回使っているのでちょっと見難いですね。
その辺は次回スッキリさせてみたいと思います。
今回はここまでです。
次回もよろしくお願いします。