JavaScript　覚えておくべき注意点！（８）　繰り返し処理について学ぶ　while文 do...while文 for文　ジャンケンゲームで連勝回数を表示する

##★　繰り返し処理とは何かを知りましょう
プログラミングの世界では、同じ命令を繰り返し実行したい場面がよくあります。
こうした処理を「繰り返し処理」または「ループ処理」「反復処理」と言います。

### 繰り返し処理とは
簡単に言えば１万人にメールを送信する処理です
特に、繰り返しを指示するプログラムが書ければ、コードがぐっと短くなり、読みやすくなります。

```javascript:kurikaeshi1.js
繰り返す (１万人になるまで) {
	① メールアドレスを送信先にセットする
	② メールを送信する
}
```
メールの送信先は毎回異なるので、繰り返し回数に応じて異なるメールアドレスを取得する処理も同時に行っております。

###繰り返し処理で辞書を引く

繰り返し処理で、辞書を引く手間を減らすことができます。
紙の国語辞典をイメージします。調べる言葉を決めたら、先ず辞書全体の真ん中あたりを開いてみます。辞書は５０音順に並んでいるので、調べたい言葉が開いたページの後ろにあるか前にあるか、判断することができます。ここで調べたい言葉がある、残りのページ全体の真ん中あたりを開きます。これを繰り返します。
このように、日常的な作業も、繰り返し処理で表現することができます。

```javascript:kurikaesi2.js
繰り返す (見つかるまで) {
	① 残されたページの真ん中を開く
	② 調べたい言葉の載っていない半分のページを、検索対象から外す
}
```
### 繰り返し処理の終わり方
繰り返し処理では、処理を一回行うたびに、継続する条件を確認して、条件を満たさなくなったら、処理を終了するように出来ております。

##★　条件に応じた繰り返しを書いてみる

###while文の書き方

```javascript:kurikaesi3.js
/* while文の書き方 */
while (year <= 2000) {
	行いたい処理
}

// プログラムのイメージ
while (汚れが消えるまで) {
	拭く;
}
```
whileの後の( )で指定した条件式が真であるかぎりブロック{ }内の処理を繰り返します。while文で繰り返し処理を終了するには、繰り返し処理が行われていく中で条件式が「偽：false」になる必要があります。

### 最低１回は繰り返す do...while文
```javascript:kurikaesi4.js
do {
	行いたい処理
} while (year <= 2000);
```

while文では、条件式が最初から「偽」だった場合、一度も繰り返し処理が実行されませんが、最低でも１回以上繰り返したいときには「do...while文」を使用します。do...while文では最初に一度{ }内の処理を実行した後に、さらに処理を繰り返すかどうか、条件式で判断します。

### 無限ループには要注意
whileでは条件式が偽にならなければ繰り返し処理が終了しません。
絶対に偽にならない条件式を指定してしまい、繰り返し処理が終了しない状態を「無限ループ」といいます。while文を使用するときは無限ループにならないように、繰り返し処理の中で条件が「偽：false」に変化するようにプログラムを記述する必要があります。


##★　例　オリンピックイヤーを表示してみる
###１．while文で繰り返し処理を書く
①年数を記憶する変数yearを定義して開始年2０００年を代入します。
②次に２００１以下を条件とするwhile文を書き、ブロック内でyearに２を加えます。

```javascript:kurikaesi5.js
var year = 2000; // ........①
while (year <= 2100) {
  year = year + 2; // ......②
}
```
###２．夏季と冬季の出し分け処理を書く
①夏季オリンピックは４の倍数、冬季オリンピックはそれ以外のときに開催されるので、if文で出し分けの処理を記述します。
if文の条件式「year % 4」はyearを4で割ったときの余り（剰余）を表わします。夏季オリンピックが開催される４の倍数の年なら値が０となり、if文の条件式としては偽と判定され、冬のオリンピックのときには真と判定されます。

```javascript:kurikaesi6.js
var year = 2000;
while (year <= 2100) {
  if (year % 4) {
    console.log(year + '：冬季オリンピック');
  } else {
    console.log(year + '：夏季オリンピック');
  } // ........................................①
  year = year + 2;
}
```
###３．プログラムの動作を確認する
ブラウザの設定内のその他のツール、デベロッパーツールのconsoleにプログラムをコピペし、enterをして動作確認をしてみましょう。

##★　回数の決まった繰り返しを書く
###for文の書き方
while文と比較して、回数の決まった繰り返し処理を書くのに便利なのがfor文です。
一般的なfor文では、カウント用変数（例文中の変数「var i = 1;」）を用意して、その値を繰り返し処理を行うごとに１ずつカウントアップ（例文中の「i++」）します。この「++」はインクリメント演算子と呼ばれます。

```javascript:kurikaesi7.js
for(var i = 1; i <= 100; i++) {
	行いたい処理
}
/* var i = 1 は、カウント用変数の初期化、
i <= 100 は繰り返し条件式、
i++ はカウントを増やす式 */
```
###１．for文で繰り返し処理を書く
さっそくfor文を試してみましょう。
単に100回こんにちはを表示するだけでは味気ないので、現在の繰り返し回数も合わせて表示します。

```javascript:kurikaesi8.js
for(var i = 1; i <= 100; i++) {
	console.log(i + '回目の「こんにちは」');
}
```

###２．プログラムを実行してみましょう


##★　ジャンケンゲームで連勝回数を表示しましょう
###完成をイメージする

###１．janken()に戻り値を設定する
前回、JavaScript　覚えておくべき注意点！（７）で作成したジャンケンゲームは関数「janken()」で呼び出すことで使用できましたが、janken()には戻り値が設定されていないので、そのまま利用しても勝負に勝ったのか負けたのか判断することができません。そこでまずはjanken()に勝敗が分かる戻り値を設定します。勝敗の結果を関数「getResult()」で所得し、その値をreturn値に設定します。①
またjanken()を実行している関数は繰り返し処理の中で書き直すので、一旦消しておきましょう。②

```javascript:kurikaesi9.js
function janken () {

 ...中略...

    var com = getComHand();
    alert(getResultMsg(com, hum));
    return getResult(com, hum); // ..................①
  }
}
janken(); // ........................................②
```

###２．while文で繰り返し処理を記述します
続いて、繰り返し処理を記述します。
まずは連勝数を記載するための変数「win」と、負けたかどうかを記憶するための変数「isLose」を宣言します。①
次に、while文で繰り返し処理を表わし、先に宣言した変数「isLose」が真にならない限り、繰り返し処理を続けるように条件式を書きます。②

```javascript:kurikaesi9.js
var win = 0;
var isLose = false; // ...............①
while (!isLose) {

} // .................................②
```

##３．勝敗に応じて条件分岐を記述する
そして最後に、繰り返し処理の中身を記述していきます。繰り返し処理では、まずjanken()を実行して ① 、
その結果に応じて条件分岐を行います。
あいこの場合は、 continue文でその後の処理をスキップして、次の繰り返しに移ります。②
勝の場合には、++演算子で変数winを１増やし、これまでの連勝数を表示して、次の繰り返しに移ります。③
それ以外は負けの場合になるので、連勝数を表示して、繰り返し処理が終了するよう「isLose」の変数値をtureに変更します。④

```javascript:kurikaesi10.js
while (!isLose) {
    var result = janken(); // .....................................①
    if (result === '結果はあいこでした。') {
        continue;
    } //...........................................................②
    if (result === '勝ちました。') {
        win++;
    alert('ただいま「' + win + '」勝でした。');
        continue;
    } // ..........................................................③
    alert('連勝はストップです。記録は「' + win + '」勝でした。');
    isLose = true;
} // ..............................................................④
```
##★　まとめ
```javascript:kurikaesi11.js
function janken () {
  /* 変数定義 ************************/
  // ジャンケンの手の番号を設定
  var GU    = 1;
  var CHOKI = 2;
  var PA    = 3;
  
  /* 関数定義 ************************/
  // 人間に手を入力してもらう機能
  function getHumHand() {
    var hum = prompt('半角数字で1~3の数字を入力してください。\n\n' + GU + ':グー\n' + CHOKI + ':チョキ\n' + PA + ':パー');
    hum = parseInt(hum, 10);
    if (hum !== GU && hum !== CHOKI && hum !== PA) {
      return undefined;
    } else {
      return hum;
    }
  }
  
  // コンピュータの手を決める
  function getComHand() {
    return Math.floor(Math.random() * 3) + 1;
  }
  
  // コンピュータの手の名前を取得
  function getHandName(num) {
    switch (num) {
      case GU:
      return 'グー';
      case CHOKI:
      return 'チョキ';
      case PA:
      return 'パー';
    }
  }
  
  // 結果の判定
  function getResult(com, hum) {
    if (hum === com) {
      return '結果はあいこでした。';
    } else if ((com === GU && hum === PA) || (com === CHOKI && hum === GU) || (com === PA && hum === CHOKI)) {
      return '勝ちました。';
    } else {
      return '負けました。';
    }
  }
  
  // 最終的な結果のメッセージ
  function getResultMsg(com, hum) {
    return getResult(com, hum) + 'コンピュータの出した手は「' + getHandName(com) + '」でした';
  }
  
  /* 実行する処理 ************************/
  var hum = getHumHand();
  if (!hum) {
    alert('入力値をうまく認識できませんでした。ブラウザを再読込すると、もう一度挑戦できます。');
  } else {
    var com = getComHand();
    alert(getResultMsg(com, hum));
    return getResult(com, hum);
  }
}
var win = 0;
var isLose = false;
while (!isLose) {
    var result = janken();
    if (result === '結果はあいこでした。') {
        continue;
    }
    if (result === '勝ちました。') {
        win++;
    alert('ただいま「' + win + '」勝でした。');
        continue;
    }
    alert('連勝はストップです。記録は「' + win + '」勝でした。');
    isLose = true;
}
janken();
```

ワンポイント　返し処理の中断（break文）

```javascript:kurikaesi12.js
// 返し処理の中断（break文）
while (汚れが消えていない) {
	拭く;
	if (効果が無い) {
	break; // ...................繰り返し処理を中断
	}
}
```
ワンポイント　繰り返しをスキップする（continue文）

```javascript:kurikaesi13.js
// 繰り返しをスキップする（continue文）
while (汚れが消えていない) {
	if (摩擦で熱い) {
		１０分間休む;
	continue; // ................while文の先頭にジャンプ
	}
	拭く;
}
```

参照: [いちばんやさしいJavaScriptの教本](https://https://book.co.jp/books/1116101117)