[Labyrinthe Noir]>[Top]>[こども工作教室]>

「九九しりとり」のソースと解説

保存ファイルの準備

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>九九しりとり</title> </head> <body> <h3>九九しりとり</h3> <hr>
</body> </html>

エディタ(メモ帳)とブラウザ(Internet Explorer)を使って基本のタグを書いたHTMLファイルを作成します。
まずはメモ帳を開き、左記のタグを記入して、デスクトップに「名前を付けて保存」します。ファイル名は「kuku.html」です。
保存が出来たら、アイコンがデスクトップに出てくるので、ダブルクリックして開きます。
画面の左右にメモ帳とブラウザそれぞれのウインドウを置いて作業しましょう。
メモ帳を閉じてしまった場合は、アイコンの上で右クリックしてショートカットメニューを表示させます。「プログラムから開く」の中から「NotePad」を選ぶと、メモ帳でファイルを開くことができます。

ゲームの説明

ゲームを作る前にゲームのルールを理解しておかなければいけません。

九九を使ってのしりとりなので、九九の答えの一桁を次の九九の段にして、1~9の数字を掛けて次の答えを出します。
例えばこういう感じです。

「9×2=18」「8×6=48」「8×4=32」「2×2=4」「4×5=20」

そして、上記のように下一桁が0になると、続けられないため負けになります。
また、同じ答えが出ても負けになるので、どの答えが出たのかメモを取っておく必要があります。

まずは、このルールを簡単に説明書きとして画面に表示しましょう。

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>九九しりとり</title> </head> <body> <h3>九九しりとり</h3> <hr> <p>ルール:九九の答えの一の位を使ってしりとりします。 一の位が0になったり、同じ答えを出すと負けです。</p> </body> </html>

4つのテーブル枠

画面上には4つの枠をテーブルタグで作ります。

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>九九しりとり</title> </head> <body> <h3>九九しりとり</h3> <hr> <p>ルール:九九の答えの一桁目を使ってしりとりします。 一桁目が0になったり、同じ答えを出すと負けです。</p> <table border="0" cellspacing="2" cellpadding="2"> <tr><th></th></tr> <tr><th></th></tr> <tr><th></th></tr> <tr><th></th></tr> </table> </body> </html>

1つ目は、九九の最初の段数を決める数字を表示します。これを親数と呼ぶことにします。
2つ目で、九九の段数(親数)に掛ける数字を決めます。これを子数と呼ぶことにしましょう。子数はプレイヤーが選ぶので、ボタンを並べることにします。
3つ目は、登場した答えを記録する表を置きます。
4つ目には、ゲームをリセットするためのボタンを置くことにします。

枠内のものが中央に来るようにタグは<th>を使っておきます。

親数と答えの表示

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>九九しりとり</title> </head> <body> <h3>九九しりとり</h3> <hr> <p>ルール:九九の答えの一桁目を使ってしりとりします。 一桁目が0になったり、同じ答えを出すと負けです。</p> <table border="0" cellspacing="2" cellpadding="2"> <tr><th><span id="oya"></span></th></tr> <tr><th></th></tr> <tr><th><span id="kotae"></span></th></tr> <tr><th></th></tr> </table> </body> </html>

親数の表示場所を<span>タグを使って作ります。ID名を「oya」にします。

答えのリストを表示する場所も<span>タグを使って、ID名「kotae」としてください。

子数の表示とリセットボタン

テーブル内に解答用のボタンを設置します。

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>九九しりとり</title> </head> <body> <h3>九九しりとり</h3> <hr> <p>ルール:九九の答えの一桁目を使ってしりとりします。 一桁目が0になったり、同じ答えを出すと負けです。</p> <table border="0" cellspacing="2" cellpadding="2"> <tr><th><span id="oya"></span></th></tr> <tr><th><form> <input type="button" value=" 1 " onClick="keisan(1)"> <input type="button" value=" 2 " onClick="keisan(2)"> <input type="button" value=" 3 " onClick="keisan(3)"> <input type="button" value=" 4 " onClick="keisan(4)"> <input type="button" value=" 5 " onClick="keisan(5)"> <input type="button" value=" 6 " onClick="keisan(6)"> <input type="button" value=" 7 " onClick="keisan(7)"> <input type="button" value=" 8 " onClick="keisan(8)"> <input type="button" value=" 9 " onClick="keisan(9)"> </form></th></tr> <tr><th><span id="kotae"></span></th></tr> <tr><th><form> <input type="button" value="リセット" onClick="kotae_reset()"> </form></th></tr> </table> </body> </html>

【子数の表示場所】

<form>とボタンを置きます。ボタンは9つ必要です。
ボタンを押すと次の答えを出すので、あらかじめ「onClick」で答えを呼び出す準備もしておきます。
ボタンが小さいと押しにくいので、表示(value)する数字の左右にスペースを入れてあります。

ユーザー関数keisanで、親数と子数を掛け算する必要があるということが判ります。

【リセットボタン】

このリセットボタンは、フォームのリセットではなく、答えの表示を元に戻すので、通常のボタンを使います。

フォームには<input type="reset">と表記するリセットボタンがあります。
このリセットボタンは、フォームの内容を最初の状態に戻すためのものです。
今回は、フォームには入力される項目はありませんので、リセットする部分がありません。名前はリセットボタンですが、リセット(やり直し)したいのは、答えの表なのでスクリプトを使って元に戻します。

このリセットボタンからスクリプトを呼び出すため、これにも「onClick」で呼び出すスクリプトを決めておきます。

ユーザー関数kotae_resetが初期状態の表を表示するためのスクリプトになります。

最初のスクリプト

それでは、スクリプトを作っていきます。
最初にやらなければいけないのが、問題と答えの初期化です。

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>九九しりとり</title> </head> <body> <h3>九九しりとり</h3> <hr> <p>ルール:九九の答えの一桁目を使ってしりとりします。 一桁目が0になったり、同じ答えを出すと負けです。</p> <table border="0" cellspacing="2" cellpadding="2"> <tr><th><span id="oya"></span></th></tr> <tr><th><form> <input type="button" value="1" onClick="keisan(1)"> <input type="button" value="2" onClick="keisan(2)"> <input type="button" value="3" onClick="keisan(3)"> <input type="button" value="4" onClick="keisan(4)"> <input type="button" value="5" onClick="keisan(5)"> <input type="button" value="6" onClick="keisan(6)"> <input type="button" value="7" onClick="keisan(7)"> <input type="button" value="8" onClick="keisan(8)"> <input type="button" value="9" onClick="keisan(9)"> </form></th></tr> <tr><th><span id="kotae"></span></th></tr> <tr><th><form> <input type="button" value="リセット" onClick="kotae_reset()"> </form></th></tr> </table> <script type="text/javascript"> kotae_reset(); function kotae_reset() { } </script> </body> </html>

ゲームなどでは、初期設定や状態を初期に戻すことは、遊びを繰り返すときに何度も必要になります。そのため、ユーザー関数にまとめておけば、どこからでも何度でも利用できます。
変更や初期化のないものはユーザー関数の外へ、初期化が必要なものは中へと分けるようにします。

親数の表示

コメントアウトで説明書きも入れながらスクリプトを記入します。
まずは、しりとりを始める最初の親数を決めます。

<script type="text/javascript">
kotae_reset();

function kotae_reset() {
	//親数の決定
	num_oya = Math.floor(Math.random() * 9) + 1;
	document.getElementById("oya").innerHTML = num_oya;
}

</script>

変数num_oyaに1~9の数字を入れます。毎回開始の親数を変えるために、random()という関数を使って乱数を発生させます。

乱数とは、計算毎に毎回違う数字を発生さて作る数値のことです。これをすることで、ゲームに決まったパターンの動きではなく、意外性のある動きを作ります。
乱数の仕組みを詳しく知りたい場合は、以下の手順を1つ作る毎にブラウザを再読込して答えを確認すると良いでしょう。

乱数はまず、random()で発生します。このとき、0~1の間にある小さな小数です。0や1にはなりません。その間の小数と考えてください。
そして、これに9を掛けることで0~9の間の数値になります。そのままでは利用できないため、小数を整数に直します。
floor()を使って小数点以下の細かな数値をなくして、0~8までの9つの数値にします。
これに1を足すと1~9の9つの数値から乱数が得られることになります。

乱数を発生させたら、次の行で「oya」に対して、変数num_oyaの数値を含む文字列を出力しています。

答えのリストを作成

<script type="text/javascript">
kotae_reset();

function kotae_reset() {
	//親数の決定
	num_oya = Math.floor(Math.random() * 9) + 1;
	document.getElementById("oya").innerHTML = num_oya;
	//リストの表示 
	kotae_list = new Array();
	for (n = 1; n < 91; n++) {
		kotae_list[n] = 0;
	}
	view_list();
}
</script>

配列変数kotae_listを利用して答えのリストを用意します。
九九の答えが出たときに、その答えを要素とする配列に印を入れることにします。
印が先に入っていたら、同じ答えを出したということになります。

配列の要素は1~90まで用意して、各要素の配列に「0」を入れておきます。

リストの配列が準備できたら、テーブルを組んで表示します。
表示部分は、使い回しが出来るように、別のユーザー関数にします。ここでは、ユーザー関数view_listへ処理を継続させるように記述しておきます。

答えのリストを表示

function view_list() {
	kotae_table = "<table border='2'>";
	for (n = 0; n < 9; n++) {
		kotae_table += "<tr>";
		for (m = 0; m < 10; m++) {
			r = m + 1 + n * 10;
			kotae_table += "<th>"+r+"</th>";
		}
		kotae_table += "</tr>";
	}
	kotae_table += "</table>";
	document.getElementById("kotae").innerHTML = kotae_table;
}

ユーザー関数view_listを作ります。
変数kotae_tableには、順次テーブル用のタグを入れていきます。
1~90までの10列*9行の表を作っています。
それを2つの行程に分けているのは、テーブルの行の処理と列の処理を区分けするためです。

テーブルの前後には<table>タグがあります。
行の前後には<tr>タグが必要ですので、変数nを使って行単位の処理をしています。
その行の中で列の処理をします。1つの行に1~10までの列を作ります。変数mを10回繰り返したら、次の変数nの処理に移ります。
変数rには変数mを一の位、変数nを10の位として、1~90までの数字が順番に計算されて答えとして入ります。

この表を出力すると単純な数字の並びが出てきます。
あとで、九九をした答えが出たときには、この表の答えの部分に印を付けていくことになります。

複雑なことをしているように見えますが、行毎に<tr>タグを入れるために、このような手順が必要になってしまうのです。

計算の実行

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list(); 
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
		alert("OUT!!");
	}
}

ユーザー関数keisanを作ります。
子数のボタンを押すと九九の計算を実行します。

ボタンから送られてくる数字を変数numで受け取ります。これが子数になります。

親数は変数num_oyaに入っていますので、親数と子数を掛けた答えを変数num_kotaeに入れます。

次に配列変数に答えの印を付けます。ここでは、答えの要素に対して1を足しています。これで「0」だった数値が「1」になりますので、数値が「1」ならば答えが一度出たことの印になります。
ルールでは2度答えが出ると負けになりますので、2度目にはまた1足されるので、数値が「2」になります。これで負けの判定もできます。

3行目で、ユーザー関数view_listを呼び出しています。
印を付けた表を画面に表示するためです。

4行目では、答えの要素が「1」よりも大きい場合に、「OUT!!」というメッセージを画面に表示します。
これで負けだということが判ります。

4行目で、答えが「2」の場合としないことには意味があります。「1」より大きいということは「3」や「4」の場合も考えているのです。
答えを間違ってもそこで強制的にゲームを終わらせることはせず、続けてゲームができるので同じ間違いを何度もやる可能性があります。
なので、間違いを何度繰り返しても良いようにしているのです。

答えリストの変更

function view_list() {
	kotae_table = "<table border='2'>";
	for (n = 0; n < 9; n++) {
		kotae_table += "<tr>";
		for (m = 0; m < 10; m++) {
			r = m + 1 + n * 10;
			if (kotae_list[r] > 1) {
				kotae_table += "<th bgcolor='#ff0000'><font color='#ffffff'>"+r+"</font></th>";
			} else if (kotae_list[r] == 1) {
				kotae_table += "<th bgcolor='#000000'><font color='#ffffff'>"+r+"</font></th>";
			} else {
				kotae_table += "<th>"+r+"</th>";
			}
		}
		kotae_table += "</tr>";
	}
	kotae_table += "</table>";
	document.getElementById("kotae").innerHTML = kotae_table;
}

ユーザー関数view_listに出た答えの数字に印を付けて表示するように変更を加えます。

数字の表示は「kotae_table += "<th>"+r+"</th>"」の部分で行っています。
答えが1回出たときには、数字を白黒反転させます。
2回目には、枠の背景を赤くします。

最初のif文では、答えの要素に「2」以上の数値が入っていたときに、背景を赤、文字を白にします。
ここも前項目と同じで、「2」では判断せずに「1」より大きいという判断をしています。

2つ目のif文には頭にelseも付けます。これは1つ目のif文が真でなかったときだけ判断されることになります。

元々あった枠の表示はelseの後に入れて、2つのif文がどちらも偽の場合に実行されることになります。

これで3つのパターンに処理が分岐されることになります。

答えの一の位を引き継ぐ

答えが出たら、その一の位を引き継いでしりとりにします。

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
		alert("OUT!!");
	} else {
		num_oya = num_kotae - Math.floor(num_kotae/10)*10;
		document.getElementById("oya").innerHTML = num_oya;
	}
}

そこでif文の続きとして、答えが2回目でなかったときの処理としてelseを使います。

その中に2行追加します。

1行目は、引き継ぐために変数num_oyaに一の位を取りだしています。
num_kotaeを10で割ることで一の位が小数点以下になります。floorを使って小数点以下をなくして、10を掛ければ一の位がなくなり十の位が残ったことになります。これを元の数字から引き算すると今度は一の位が残ります。

例えばこういうことが起こっています。
num_kotae=「18」→10で割ると「1.8」→floorで切り捨てると「1」→10倍すると「10」→元の「18」-「10」で「8」

2行目では、その新しい親数を表示しています。

親数が0になった場合

さて、ここでもう1つのルールを確認します。
答えの一の位が「0」になったら負けでした。これは親数が「0」になってはいけないからです。
親数が「0」の場合には、メッセージを表示させてゲームを終わらせましょう。

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
    	alert("OUT!!");
	} else {
		num_oya = num_kotae - Math.floor(num_kotae/10)*10;
		document.getElementById("oya").innerHTML = num_oya;
		if (num_oya == 0) {
			alert("OUT!!");
			kotae_list[num_kotae]++; 
			view_list();
		}
	}
} 

if文で変数num_oyaが0であることを確認します。
2行目で「OUT!!」のメッセージを表示させます。
続けて、答えの要素に1を足し、再度答えの表を表示して、答えを赤で表示します。

これでゲームとしては基本的なルールによる流れが完成したことになります。

ゲームを続けられるように改良する

このままでは「0」が出るとゲームを続けられなくなりました。
しかし、「0」が出ても1つ前の親数でゲームを継続できるように改良してみましょう。

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
    	alert("OUT!!");
	} else {
		r = num_kotae - Math.floor(num_kotae/10)*10;
		if (r == 0)	{
			alert("OUT!!"); 
			kotae_list[num_kotae]++; 
			view_list();
		} else {
			num_oya = r; 
			document.getElementById("oya").innerHTML = num_oya;
		}
	}
} 

一の位を変数num_oyaへ直接いれずに、一旦変数rに入れます。

次の変数num_oyaの表示は移動して、その次のif文が偽のときにだけ表示することにします。
これによって、OUTにならなかったときに親数を変更することになります。

また、最初の変更に合わせて、if文も変数num_oyaから変数rに変更します。

改良:大きさと色を付ける

親数の表示を大きくし、色を付けて見やすくしたいと思います。
また、どの計算を行ったか判るように表示をしたいと思います。

<table border="0" cellspacing="2" cellpadding="2">
<tr><th><h1><font color="#0000ff"><span id="oya"></span></font></h1></th></tr>
<tr><th><form>
<input type="button" value=" 1 " onClick="keisan(1)">
<input type="button" value=" 2 " onClick="keisan(2)">
<input type="button" value=" 3 " onClick="keisan(3)">
<input type="button" value=" 4 " onClick="keisan(4)">
<input type="button" value=" 5 " onClick="keisan(5)">
<input type="button" value=" 6 " onClick="keisan(6)">
<input type="button" value=" 7 " onClick="keisan(7)">
<input type="button" value=" 8 " onClick="keisan(8)">
<input type="button" value=" 9 " onClick="keisan(9)">
</form></th></tr>
<tr><th><span id="kotae"></span></th></tr>
<tr><th><form>
<input type="button" value="リセット" onClick="kotae_reset()">
</form></th></tr>
</table>

テーブルの1行目にある<span>タグで親数を表示しています。ここにタグを入れて、大きさと色を指定します。
<h1>で文字を最大に、<font>で青色を指定しています。もちろん、好きな大きさ、好きな色にしてもかまいません。

改良:計算式の表示(1)

親数の表示だけだったところを、計算式の表示に変更します。

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
		alert("OUT!!");
	} else {
		r = num_kotae - Math.floor(num_kotae/10)*10;
		if (r == 0)	{
			alert("OUT!!"); 
			kotae_list[num_kotae]++; 
			view_list();
		} else {
			view_text = num_oya + "×" + num + "=" + num_kotae;
			num_oya = r;
			document.getElementById("oya").innerHTML = view_text; 
		} 
	}
}

まず、表示用の変数view_textを用意して、そこに計算式を文字列にして入れます。

出力部分は変数num_oyaを変数view_textに入れ換えます。

これで子数を押した後、親数と子数を掛け算する式とその答えが画面に表示されるようになりました。

改良:計算式の表示(2)

もう1段階、表示の改良を進めましょう。
画面の式の表示は、1つ前の問題と答えということになります。そこから一の位を取って来て、次の親数にして、次の子数を選んでもらいます。
これを判りやすく表現するために、これも計算式にします。

(省略)

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
		alert("OUT!!");
	} else {
		r = num_kotae - Math.floor(num_kotae/10)*10;
		if (r == 0)	{
			alert("OUT!!"); 
			kotae_list[num_kotae]++; 
			view_list();
		} else {
			view_text = num_oya + "×" + num + "=" + num_kotae + "<br>";
			view_text += r + "×<font color='#ff0000'>?</font>=";
			num_oya = r;
			document.getElementById("oya").innerHTML = "<h1><font color='#0000ff'>" + view_text + "</font></h1>";
		} 
	}
} 

(省略)

先に作った計算式の後ろに改行のための<br>タグを入れます。
次の行に、問題文となる計算式を作って、変数view_textに付け加えます。

改良:計算式の表示(3)

上記の変更に合わせて、初期の表示も手直しします。

function kotae_reset() {
	//親数の決定
	num_oya = Math.floor(Math.random() * 9) + 1;
	document.getElementById("oya").innerHTML = num_oya + "×<font color='#ff0000'>?</font>=";
	//リストの表示
	kotae_list = new Array();
	for (n = 1; n < 91; n++) {
		kotae_list[n] = 0;
	}
	view_list();
}

こちらは問題文だけになります。とても判りやすくなりました。

【この時点の kuku.html を別枠で表示】

完成

九九しりとりはこれで完成です。
これなら一人でも遊べますし、複数でも交代でマウスを握って遊べます。
ウインドウを小さくして答えの表を見えなくすると更に難しくなります。

九九の学習として使う場合には、子数のボタンを押す前に声を出して九九の式と答えを言いましょう。

改良するとすれば、長く考えられないようにカウントダウンタイマーを取り付けたり、連続正解数の記録を表示するなど考えられます。

ルール改善版

オリジナル版のルールには5の段に問題点があります。5の段の答えには「0」か「5」しかありません。他の段に移動できないし、負けが見えています。これではゲーム性が損なわれるため、一の位が「0」の場合、十の位を取って継続するようにルールを変更します。

5の段の問題を改善

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
		alert("OUT!!");
	} else {
		r = num_kotae - Math.floor(num_kotae/10)*10;
		if (r == 0) {
			r = Math.floor(num_kotae/10);
			alert("OUT!!");
			kotae_list[num_kotae]++;
			view_list();
		} else {
			view_text = num_oya + "×" + num + "=" + num_kotae + "<br>";
			view_text += r + "×<font color='#ff0000'>?</font>=";
			num_oya = r;
			document.getElementById("oya").innerHTML = view_text;
		}
	}
}

青字抹消の部分を削除します。後ろから三行目の「}」も忘れずに削除してください。

新たに変数rが0の場合には、十の位を変数rに入れています。

ルールの説明文も「九九の答えの一の位を使ってしりとりします。一の位が0の場合は、十の位を使います。同じ答えを出すと負けです。」と変更しておきます。

得点表示の作成

連続して答えを出すと得点が得られるようにします。
ただし、間違ったときは得点を引きます。

<table border="0" cellspacing="2" cellpadding="2">
<tr><th><h1><font color="#0000ff"><span id="oya"></span></font></h1></th></tr>
<tr><th><form>
<input type="button" value=" 1 " onClick="keisan(1)">
<input type="button" value=" 2 " onClick="keisan(2)">
<input type="button" value=" 3 " onClick="keisan(3)">
<input type="button" value=" 4 " onClick="keisan(4)">
<input type="button" value=" 5 " onClick="keisan(5)">
<input type="button" value=" 6 " onClick="keisan(6)">
<input type="button" value=" 7 " onClick="keisan(7)">
<input type="button" value=" 8 " onClick="keisan(8)">
<input type="button" value=" 9 " onClick="keisan(9)">
</form></th></tr>
<tr><th>得点:<span id="score"></span>/36</th></tr>
<tr><th><span id="kotae"></span></th></tr>
<tr><th><form>
<input type="button" value="リセット" onClick="kotae_reset()">
</form></th></tr>
</table>

得点表示をするために、テーブルに一行加えて、「score」という表示場所を作ります。
満点で36点になるので、「/36」を表示しています。

答えの組合せは36通りしかありませんので、得点は最大で36になります。
間違った選択をすると得点は引かれますので、その場合は満点になりません。

得点の初期設定

function kotae_reset() {
	//スコアのカウント
	count = 0;
	document.getElementById("score").innerHTML = count;
	//親数の決定
	num_oya = Math.floor(Math.random() * 9) + 1;
	document.getElementById("oya").innerHTML = num_oya + "×<font color='#ff0000'>?</font>=";
	//リストの表示
	kotae_list = new Array();
	for (n = 1; n < 91; n++) {
		kotae_list[n] = 0;
	}
	view_list();
}

ユーザー関数kotae_resetに得点をカウントするための変数countを準備します。

得点の計算と出力

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
		alert("OUT!!");
		count--;
	} else {
		r = num_kotae - Math.floor(num_kotae/10)*10;
		if (r == 0) {
			r = Math.floor(num_kotae/10);
		}
		view_text = num_oya + "×" + num + "=" + num_kotae + "<br>";
		view_text += r + "×<font color='#ff0000'>?</font>=";
		num_oya = r;
		document.getElementById("oya").innerHTML = view_text;
		count++;
	}
	document.getElementById("score").innerHTML = count;
}

OUTの表示があった場合には、変数countから1を引いて、得点を減らします。

答えが被らなかったときは、変数countを1つ加算して得点を増やします。

最後に得点の表示をします。

詰み状態の確認

次の答えがない状態を詰み(チェックメイト)と言います。
詰み状態で無駄なクリックを続けても得点が減るばかりなので、子数を入力した後、次の問題が詰み状態かどうかを確認します。

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
		alert("OUT!!");
		count--;
	} else {
		r = num_kotae - Math.floor(num_kotae/10)*10;
		if (r == 0) {
			r = Math.floor(num_kotae/10);
		}
		view_text = num_oya + "×" + num + "=" + num_kotae + "<br>";
		view_text += r + "×<font color='#ff0000'>?</font>=";
		num_oya = r;
		document.getElementById("oya").innerHTML = view_text;
		count++;
		//詰み状態の確認
		m = 0;
		for (n = 1; n < 10; n++) {
			if (kotae_list[num_oya*n] == 0) {m++;}
		}
		if (m == 0) {alert("CHECKMATE");}
	}
	document.getElementById("score").innerHTML = count;
}

まず、親数に対して各子数を掛けて、配列変数kotae_listの答えの要素を調べます。「0」があればまだ答えが残っているいうことになりますので、その数を変数mに数えていきます。
変数mが最後に「0」ならば、残りは1つもないということです。

では、「詰み状態の確認」とコメントアウトした次から見て行きましょう。

1行目で、変数mを初期化しています。

2行目のfor文で変数nに子数を1から9まで入れて、3行目の式を繰り返し調べます。

3行目は、親数と子数を掛けた答えの要素を調べ、「0」ならば真です。真ならば、一度出た答えなので、変数mに1を加算します。

5行目で、変数mが「0」かどうか調べています。真ならば「CHECKMATE」とメッセージを表示します。

完全回答の確認

全部の答えを出した場合にもメッセージを表示することにしましょう。

function keisan(num) {
	num_kotae = num_oya * num;
	kotae_list[num_kotae]++;
	view_list();
	//答えの確認
	if (kotae_list[num_kotae] > 1) {
		alert("OUT!!");
		count--;
	} else {
		r = num_kotae - Math.floor(num_kotae/10)*10;
		if (r == 0) {
			r = Math.floor(num_kotae/10);
		}
		view_text = num_oya + "×" + num + "=" + num_kotae + "<br>";
		view_text += r + "×<font color='#ff0000'>?</font>=";
		num_oya = r;
		document.getElementById("oya").innerHTML = view_text;
		count++;
		if (count == 36) {
			//完全回答の確認
			alert("PERFECT!!!");
		} else {
			//詰み状態の確認
			m = 0;
			for (n = 1; n < 10; n++) {
				if (kotae_list[num_oya*n] == 0) {m++;}
			}
			if (m == 0) {alert("CHECKMATE");}
		}
	}
	document.getElementById("score").innerHTML = count;
}

答えは36通りですので、得点が最大の36点になったら完璧(パーフェクト)と言えます。

「完全回答の確認」のコメントアウトから下を見ていきます。

1行目でif文を使って、変数countが「36」か調べています。真ならば2行目を実行します。

2行目は、「PERFECT!!!」のメッセージを表示しています。

3行目のelseから、if文が偽の場合に詰み状態の確認を行うために、4行目から6行目を囲っています。

【この時点の kuku.html を別枠で表示】

戻る