【初心者向け】JavaScript入門④「forループ」 |『文系の人にもわかるプログラミング入門』より

#はじめに
[初めてのJavaScript(オライリー本)](https://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEJavaScript-%E3%82%B7%E3%82%A7%E3%83%AA%E3%83%BC-%E3%83%91%E3%83%AF%E3%83%BC%E3%82%BA/dp/4873113229)が筆者にとって少しとっつきにくかったです。そこで、本書のサポートページにあるコラム[『JavaScriptで学ぶ文系の人にもわかるプログラミング入門』](https://www.marlin-arms.com/jpn/column/js101/lesson03.html)から学び始めることにしました。その学習記録です。

# 学習すること
***[第6章 forループ(loop)](https://www.marlin-arms.com/jpn/column/js101/lesson06.html)***

>前の章で繰り返しのために使うWhileループを学びましたが、この章では別の種類の繰り返しであるForループについて説明します。

***目次***
* ①forループ
* ②条件の追加ー繰り下がりのない引き算
* ③成績を出すーカウンタの利用
* ④まとめ

# ①forループ

>だいぶ計算練習らしくなってきましたが、今度はいつまでも繰り返すのではなく、
たとえば利用者に何問やるか問題数を聞いてその数だけやるようにしてみましょう。Whileループを使ってもできますが、今度は「forループ」を使います。それから、これを機会に、足し算引き算をする部分を別の関数として外に出す（下請けに出す）ことにしましょう。

### プログラム6-1 example06-01.html 計算練習５

```html:example06-01.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>けいさん５</title>
<!--問題数を指定する-->
<script type="text/javascript">
function keisan(){
    var mondaiSu; //問題数
    var i; //iの初期化(=変数宣言)

    mondaiSu = prompt("なんかい　やりますか？",　20); //20はあらかじめ表示しておく値(ﾃﾞﾌｫﾙﾄ),

    for(i=1; i<= mondaiSu; i++)　{  　　　//既定の数まで問題を表示し続ける
        if(tashizanHikizan() == null)　{　//例外処理(tashizanHikizanの戻り値がnull）
            break;                       //ﾕｰｻﾞがｷｬﾝｾﾙを押した時、ループを強制的に抜ける
        }                     
    }
}
function tashizanHikizan()　{ //足し算か引き算を１回実行
    var no1,no2;　//　第１項、第２項
    var mondai,seikai, kotae; //問題,正解,答え
    var enzan; // "+","-"
    var kekka; // 正解(=1),不正解(=0),キャンセル(=null)
    
    no1 = randomInt(10);　//第１項に乱数を代入
    if(randomInt(2) == 1) { //足し算か引き算を判断？
        enzan = "　+　";
        no2 = randomInt(10);　//第２項に乱数を代入
        seikai = no1 + no2;   //第１項と第２項の足し算結果をseikaiに代入
    }
    else { 　//　引き算の場合
        enzan = "　-　";
        no2 = randomInt(no1); // 第２項に第１項が上限の乱数を代入？（計算結果をマイナスにしない為）
        seikai = no1 - no2;　 // 引き算の答えを代入
    }
    mondai = no1 + enzan + no2 + " =";　//「no1[+/-]no2=」
    kotae = prompt(mondai,""); //kotaeに何を代入してる？
    kekka =　1; //正解
    while(kotae != null && kotae != seikai) {　
        kekka = 0; //不正解
        kotae = prompt("ざんねんでした。もういちど:" + mondai,"")
    }
    if( kotae == null ) {
        return kekka; //キャンセル(=null)が戻り値として返される
    }
    else　{
        return kekka; //正解(=1),不正解（=0）が戻り値として返される
    }
}

function randomInt(i) { // 1以上i以下の整数を返す
    return( Math.floor(Math.random()*i) + 1　);
}
</script>
</head>
    
<body onload="keisan();">
<h1>けいさんれんしゅう</h1>
</body>
</html>
```
## 条件の追加ー繰り下がりのない引き算

>小学生になって初めての夏休みが終わり２学期になると、19までの数字を使った足し算、
引き算を練習します。ただし、「15-8」のように「繰り返し」がある引き算は難しいので、
まず第2項が10より小さくて繰り下がりのない引き算だけを勉強します。今度は、この時期の
ドリル用のプログラムを作ってみましょう。もう一度まとめると、次のような条件を満たす計算を
出題する必要があります。

1. 使う数字は、足し算、引き算とも19以下
2. 足し算の合計は19以下
3. 引き算の答えはマイナスになってはいけない
4. 繰り下がりのある引き算は出してはいけない
5. 引き算の第2項は9以下

>(1)-(3)については上で対策を立てましたが、(4)はどのように処理すればよいでしょうか？
「繰り下がりがないようにする」ということは、引き算の第１項（変数no1で表すほう）の1の位が、
第２項（変数no2で表すほう）の1の位より小さくてはいけない（大きいか同じでなければいけない）
ということになります。以上を考慮して作ったプログラムが次のものです。

### プログラム6-2 example06-02.html 計算練習６

```html:example06-02.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>けいさん６</title>
<!--繰り下がりのない引き算-->
<script type="text/javascript">
function keisan() {
    var mondaiSu; // 問題数
    var i;
    
    mondaiSu = prompt("なんかい  やりますか？", 20);
    for(i=1; i<= mondaiSu; i++) {
        if(tashizanHikizan() == null) {
            break;
        }
    }
}
    
function tashizanHikizan() { 　 //  足し算か引き算を１回実行
    var no1, no2;               //　第１項、第２項
    var mondai, seikai, kotae;  //　問題、正解、答え
    var enzan;    // "+"か"―"
    var kekka;　　 // 正解(1)か不正解か(0)
    
    no1 = randomInt(10);　　　 // 第１項に上限10までの乱数を代入
    if (randomInt(2) == 1) {  // 足し算の場合（randomInt(2)の戻り値が1なら足し算）
        enzan = " + ";        // 演算子(+)をenzanに代入
        no2 = randomInt(10);　// 第２項に乱数を代入
        seikai = no1 + no2;　 // 第１項と第２項を足した結果をseikaiに代入
    }
    else { 　　　　　　　　　　　// 引き算の場合（randomInt(2）の戻り値が2なら引き算）
        enzan = " - ";　　　　 // 演算子(-)をenzanに代入
        if (no1 > 10) {       // 第１項が10以上なら
            no2 = randomInt(no1-10); // randomInt(no1-10)
        }
        else {　  　　　　　　　// 第１項が10以上なら
            no2 = randomInt(no1);　// 第２項にrandomInt(no1)の戻り値を代入
        }
        seikai = no1 - no2;　// 引き算の結果をseikaiに代入
    }
    
    mondai = no1 + enzan + no2 + " =";　// 「第１項＋演算子＋第２項＋＝」
    kotae = prompt(mondai, "");
    kekka = 1; //正解
    while (kotae != null && kotae　!= seikai) {
        kekka = 0; //　不正解
        kotae = prompt("ざんねんでした。もういちど:" + mondai, "")
    }
    if ( kotae == null ) {
        return null;
    }
    else {
        return kekka;
    }
}
    
function randomInt(i) { // 1以上i以下の整数を返す
    return( Math.floor(Math.random()*i) + 1 );
}
</script>
</head>
    
<body onload="keisan();">
<h1>おつかれさまでした</h1>
</body>
</html>
```

# ③成績を出すーカウンタの利用

>この章のまとめとして、指定した数だけ問題をやって、最後に成績を知らせるようにしてみましょう。
今度は、関数keisan()のほうを少し変えます。また、ついでに問題を表示するときに、何問目かも
表示することにしてみましょう。

### プログラム6-3　example06-03.html　計算練習7
```html:example06-03.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>けいさん７</title>
<!--最後に成績を出す-->
<script type="text/javascript">
function keisan() {
    var mondaiSu; // 問題数
    var i;
    var seikaiNoKazu = 0; 　// カウンタ(正解数)
    var machigaiNoKazu = 0; // カウンタ(不正解数)
    var kekka; // 正解か不正解か。1なら正解、0なら不正解、nullならキャンセル
    
    mondaiSu = prompt("なんかい　やりますか？", 20);　//問題数の確認（初期値は20回）
    for (i=1; i<= mondaiSu; i++) {
        kekka = tashizanHikizan(i); // 正解(=1),不正解(=0),キャンセル(=null)
        if (kekka == null) {        // //ﾀﾞｲｱﾛｸﾞﾎﾞｯｸｽでｷｬﾝｾﾙを押されたらﾙｰﾌﾟを抜ける
            break;
        }
        else if (kekka == 1) {      // 正解したらseikaiNoKazuにカウント追加
            seikaiNoKazu++;
        }
        else {
            machigaiNoKazu++;       // 不正解だったらmachigaiNoKazuにカウント追加
        }
    }
    confirm("せいかい " + seikaiNoKazu + "もん。" +    // confirm関数―「ok」1。「ｷｬﾝｾﾙ」0が戻る。※alert関数でも可
            "まちがい " + machigaiNoKazu + "もん");　//正解・不正解の数を表示
}
    
// 足し算か引き算を１回実行
// 問題番号を受け取る
function tashizanHikizan(i) {
    var no1,no2;             // 第１項、第２項の変数を宣言
    var mondai,seikai,kotae; // 問題、正解、答え
    var enzan;               // 演算子("+"か"-")
    var kekka;　　　　　　　　 // 正解(1)か不正解(0)
    var saidaiKotae = 19;    // ??
    
    no1 = randomInt(saidaiKotae-1);　// saidaikotae-1までの乱数をno1に格納
    if(randomInt(2) == 1) {          // 足し算の場合
        enzan = " + ";
        no2 = randomInt(saidaiKotae-no1);  // saidaikotae-1までの乱数をno2に格納
        seikai = no1 + no2;  // 足した結果をseikaiに格納
    }
    else {                   // 引き算の場合
        enzan = " - ";
        if (no1 > 10) {　　　          // no1が10以上の場合
            no2 = randomInt(no1-10);  // no1から10を引いた上限までの乱数をno2に格納
        }
        else{　　　　　　　　　　　　　　 // no1が10以下の場合
            no2 =randomInt(no1);　　　 // 上限no1までの乱数をno2に格納
        }
        seikai = no1 - no2;           // 引き算の結果をseikaiに格納
    }
    mondai = no1 + enzan + no2 + " ="; 　//問題内容をmondaiに格納
    kotae = prompt("だい" + i + "もん:" + mondai,""); //何をしてる??
    kekka = 1;
    while (kotae != null && kotae != seikai) {
        kekka = 0;
        kotae = prompt("ざんねんでした。もういちど:" + mondai,"")
    }
    if ( kotae == null) {
        return null;
    }
    else {
        return kekka;
    }
}
    
function randomInt(i) {　             // 1以上i以下の整数を返す
    return(Math.floor(Math.random()*i) + 1);
}
    
</script>
</head>
    
<body onload="keisan();">
<h1>けいさんれんしゅう</h1>
</body>
</html>
```

# まとめ

>繰り返しの処理をする別種のループforループが登場しました。同時に、計算練習に付加した
いろいろな条件をプログラムに反映する例をいくつか紹介しました。できあがったプログラムを、
より使いやすく便利にできないか検討し、たえず改良する気持ちを忘れないようにしましょう。

## プログラミング一般

* カウンタ――何かの回数などを数える変数。特定の処理が行われるたびにその回数を数える役目をする
	* seikaiNoKazu（正解した数をカウント）
	* machigaiNoKazu（不正解の数をカウント）

## JavaScriptの構文

* for文
	`for(<初期設定>;<再実行の条件>;<再設定>){
		<処理部>
	}`

* ループを途中で抜けるーーbreak
* 演算子「++」と「--」ーー「i++」は「i=i+1」と、「i--」は「i=i-1」と同じ

## JavaScriptの関数（メソッド）
	* confirm()ーーダイアログボックスを使ってメッセージを表示。値を返す。
　　　　　　　　　　　　値を返す関数の値(1 or 0)は無視してもかまわない。

# 次回やること
[配列とグローバル変数](https://www.marlin-arms.com/jpn/column/js101/lesson07.html)

>変数， 演算子， 関数， 分岐（if ... else）， 繰り返し（while ...， for ...）など， 多くの概念が登場しましたが， まだとても重要なものがひとつ残っています。 ごくまれな例外を除いて， ほとんどすべてのプログラミング言語に備わっているのが「配列（array）」です。 この章では， この「配列」を使って， 「計算練習」をさらに発展させていきましょう。 

# おわり
今回はここまでです。

***筆者のメモ***
`変数=var(=variable)`