なでしこv3ブラウザ版で，音と画像を使った数当てゲーム拡張版を作ってみた

# 数当てゲームの拡張版

以前作った，マルチメディアプラグイン試作バージョン[plugin_media.js](https://oza-jv.github.io/plugin_media.js)を使って，「なでしこv3」ブラウザ版で，手元にある[音](https://qiita.com/oza-jv/items/2552bee6774e325b2889)と[画像](https://qiita.com/oza-jv/items/5af02e70528b274b3b74)を手軽に扱えるようになったので，それを使って数当てゲームをバージョンアップしてみました。これをやりたかったのだ，うん（自己満足）。

[日本語プログラミング言語「なでしこ」 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nadesiko)には間に合いませんでしたし，snowdrops89さんの[数当てゲーム](https://qiita.com/snowdrops89/items/91fbf8e0fb557a2681c6)（ホントはこのサイコロを使ってみたかった…）や，[和時計](https://qiita.com/snowdrops89/items/7b7258ad7699e097e19f)，てぃふと@うぇいくさんの[リバーシ](https://nadesi.com/v3/storage/id.php?357)には遠く及びませんが，子どもたち向けに音や画像の扱い方を教えたり，数当てゲームのエラー処理などを考えさせるならこのくらいが丁度良いかな？と考えながら，自分でも作ってみました。

この記事は、なでしこのv3ブラウザ版で実行できるようにしています。

完成版は[こちら](https://oza-jv.github.io/kazuate-v3.html)。

## 完成したプログラム

うーん，大作になってしまった感が…。初期設定は次のようにしています。

- 冒頭の**#1**～**#4**で，あらかじめ画面のレイアウトを決めておきます。
- **#5**と**#6**で，ゲームの難易度を決めています。
- **#7**では，**#2**で決めた`#img1`にクジラの絵を貼り付けています。これにより，画面のレイアウトが崩れるのを防いでいます。
- **#8**では**#1**の`#audio1`に，あらかじめ音を読み込ませています。これにより，初回に音がなかなか出てこない！というタイムラグを防いでいます。

```kazuate-v3.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>なでしこ３　数当てゲームv3</title>
</head>

<body>
<!-- ここに画面レイアウトをあらかじめ作っておく -->
<h2>なでしこ３　数当てゲームv3</h2>
<hr />
<audio id="audio1"></audio>			<!-- #1 音を再生するための要素 -->
<img id="img1" width="160"></img>	<!-- #2 絵（クジラ）を，画面の上部に表示するための要素 -->
<div id="div1"></div>				<!-- #3 説明とボタン類を表示するための要素 -->
<div id="div2"></div>				<!-- #4 メッセージを表示するための要素 -->

<!-- なでしこ3のエンジンを取り込み -->
<script type="text/javascript" src="https://nadesi.com/v3/cdn.php?v=3.1.8&f=release/wnako3.js&run"></script>
<!-- プラグインを取り込み -->
<script type="text/javascript" src="https://oza-jv.github.io/plugin_media.js"></script>

<!-- なでしこのプログラム -->
<script type="なでしこ">
// 初期設定 -- HTML内でなでしこを使うときは必ず実行する
結果領域＝「#div1」。
結果領域へDOM親要素設定。結果領域に「」をHTML設定。

// ここから，なでしこのプログラムを書いていきます
// 定数の定義
音ID＝「audio1」。
絵ID＝「img1」。
正解絵＝「./img/kujira.png」。
残念絵＝「./img/kujira-bk.png」。
正解音＝「./audio/se_maoudamashii_chime13.mp3」。
残念音＝「./audio/se_maoudamashii_onepoint32.mp3」。


// 初期値設定
サイコロ面＝１０。		// #5 数を当てる範囲。「６」ならば１～６までの範囲。
回答可能数＝５。		// #6 ユーザーが答えられる回数。
サイコロ＝（サイコロ面の乱数）＋１。
正解済＝０。
回答数＝１。

// 画面設定
絵IDに正解絵を絵読込。			// #7 あらかじめ読み込んでおくことで，レイアウトが崩れるのを防止。
音IDに残念音を音読込。			// #8 あらかじめ読み込んでおくことで，再生時のタイムラグを減らす。
「コンピュータがサイコロを振りました。」と書く。
「１から｛サイコロ面｝のどれかです。」と書く。
「その数を｛回答可能数｝回以内に当ててみよう！」と書く。
入力エディタ＝「」のエディタ作成。
回答ボタン＝「答える」のボタン作成。
改行作成。
改行作成。

// 以降の表示はdiv2にする。
結果領域＝「#div2」。
結果領域へDOM親要素設定。結果領域に「」をHTML設定。

// メインの処理
回答ボタンをクリックした時には
　　答え＝入力エディタのテキスト取得。

　　もし、答え＝空ならば
　　　　「答えを入力してね」と書く。					// #9 何も入力していないときの処理
　　違えばもし、（答え＜１）または（答え＞サイコロ面）ならば
　　　　「１から｛サイコロ面｝の間で答えてね」と書く。	// #10 範囲外の値のときの処理
　　違えば												// #11 正誤を判定する処理
　　　　「｛回答数｝回目の予想は…｛答え｝ですね…？」と書く。

　　　　// 正解・不正解の判定処理
　　　　もし、答え＝サイコロならば
　　　　　　「正解！」と書く。
　　　　　　絵IDに正解絵を絵読込。
　　　　　　音IDに正解音を音読込。音IDを音再生。
　　　　　　正解済＝１。							// #12 正解したら「正解済」フラグを立てる。
　　　　違えば
　　　　　　絵IDに残念絵を絵読込。
　　　　　　音IDに残念音を音読込。音IDを音再生。

　　　　　　もし、答え＞サイコロならば				// #13 不正解時はヒントを表示
　　　　　　　　「残念。もっと小さいよ」と書く。
　　　　　　違えば
　　　　　　　　「残念。もっと大きいよ」と書く。
　　　　　　ここまで。
　　　　ここまで。

　　　　回答数＝回答数＋１。
　　　　もし、（回答数＞回答可能数）または（正解済＝１）ならば	// #13 もう答えられないなら
　　　　　　「正解は｛サイコロ｝でした。」と書く。
　　　　　　入力エディタの「disabled」にオンをDOM属性設定。		// #14 入力できないようにする
　　　　　　回答ボタンの「disabled」にオンをDOM属性設定。		// #15 ボタンを押せないようにする
　　　　ここまで。

　　ここまで。
　　入力エディタに、空をテキスト設定。				// #16 入力ボックスの文字を消す
ここまで。
</script>
</body></html>
```

## メインの処理

ユーザーが答えを入力して「答える」ボタンをクリックしたら，判定処理に進みます。何もエラー処理等をしていなければ，基本的な構造は次のようになっています。

```
回答ボタンをクリックした時には
　　　　答え＝入力エディタのテキスト取得。

　　　　もし、答え＝サイコロならば
　　　　　　「正解！」と書く。
　　　　違えば
　　　　　　「残念」と書く。
　　　　ここまで。
ここまで。
```

これで話が済めばよいのですが，もちろんそうはいかないわけで。
不正解のときにヒントを表示するあたりの[説明は別に](https://qiita.com/oza-jv/items/442f4a2c99880d0ba34a)まとめています。それで次のようになりました。

```
正解済＝０。

回答ボタンをクリックした時には
　　答え＝入力エディタのテキスト取得。

　　// ★１（入力値のチェック処理）

　　もし、答え＝サイコロならば
　　　　「正解！」と書く。
　　　　正解済＝１。
　　違えば
　　　　もし、答え＞サイコロならば
　　　　　　「残念。もっと小さいよ」と書く。
　　　　違えば
　　　　　　「残念。もっと大きいよ」と書く。
　　　　ここまで。
　　ここまで。

　　// ★２（もう答えられないときの処理）

ここまで。
```

## 入力値のチェック処理

上の★１の位置に，テキストボックスへの入力値を確かめる処理を追加します。

- 空欄のまま「答える」ボタンを押したら，叱る。 → **#9**の処理。
- 数の範囲外だったら，叱る。→ **#10**の処理。
- 正しい数値ならば，正誤判定処理に進む。→ **#11**の処理。

厳密には，入力値が整数かどうかをチェックしたほうがよさそうですが，それは置いておいて。

```
もし、答え＝空ならば
　　「答えを入力してね」と書く。					// #9 何も入力していないときの処理
違えばもし、（答え＜１）または（答え＞サイコロ面）ならば
　　「１から｛サイコロ面｝の間で答えてね」と書く。	// #10 範囲外の値のときの処理
違えば												// #11 正誤を判定する処理
　　// 正解・不正解の判定処理
　　// ★２（もう答えられないときの処理）
ここまで。
```

## もう答えられないときの処理

上の★２の位置に，もう答えられないときの処理を追加します。

- `回答可能数`を超えたら，もう答えられない。
- `正解済`フラグが立っている（＝１）なら，もう答えられない。

これを**#13**で判定しています。
もう答えられないときは，正解を表示して，テキストボックスに入力できないようにして（**#14**）、答えるボタンを押せないようにしています（**#15**）。

## 遊んでいると気づく不便の解消

遊んでいると、テキストボックスに前回入力した値が残っているのがイヤになってきました…。そこで**#16**の位置に、毎回テキストボックスを空にする処理を追加しました。

## 音と画像を表示して、よりゲームっぽく！

最後に，各処理に絵と音の処理を追加しました。絵や音が入ると，ゲームっぽくなって面白いですね！

画像は2枚用意していますが，サイズを同じにしておいたほうが，レイアウトが崩れなくてよいと思います。

今回はクジラの絵を，なでしこv1の「画像ネガポジ」命令を使って加工しています。v1のときは画像処理の命令がいっぱいあって面白かったです。v3にも実装してほしいな。
![kujira-bk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942750/e134f634-9b43-05d7-c587-c64143134b77.png)

というわけで，完成したプログラムが[こちら](https://oza-jv.github.io/kazuate-v3.html)。スマホでもChromeBookでも遊べます。
> ![キャプチャ.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942750/2572cbe0-66be-b4d8-5506-f335f194cd08.gif)
※音素材はフリー音楽素材/魔王魂様から，画像はなでしこv1に同梱のものからお借りしています。

## 最後に

日本語プログラム言語「なでしこ」の強みは，プログラムの可読性と「書きやすさ」にあると思います。もちろん，作り込んでいけばプログラムは複雑になりますから，もっと美しい処理があるだろ？と突っ込まれることもたくさんあると思います。

でも，中学生や高校生のように，学校の授業で初めてプログラムに触れるという方にとっては，今回の試行錯誤のように，決して美しい処理にならなくても，一つずつやりたいことを実装していけばいいと思うんです。そうすると，決して美しい処理にはならないけど，そんなときこそ，日本語で書きやすく読みやすい「なでしこ」の強みを生かせると思うんです（と，なでしこ愛を語ってみる…）。

もっと「なでしこ」が発展して，さらに分かりやすくなって普及するといいなと思いました。