漢字にまつわる脳トレゲームはとても愉しいものです。今回はJavaScriptでブラウザで動く「間違い漢字探し」を実装してみましょう。このゲームは、簡単に作成できる割りに面白く、ルールを工夫することで、オリジナリティも演出できます。
10行で作る間違い漢字探しゲーム
それでは、HTML/JavaScriptで漢字探しゲームを作ってみましょう。100文字ある漢字の中で1文字だけ違う漢字が混ざっています。それを探すというゲームです。
次の10行のプログラムをテキストエディタにコピーして「find_kanji.html」という名前で保存しましょう。
<html><meta charset="utf-8"><body><p id="q" style="font-size:2em;"></p><script>
const qa = ["天夫", "酒洒", "鳥島", "活治", "豪濠", "季李", "兎免", "失矢", "語悟"];
const rnd = n => Math.floor(Math.random() * n);
var q = qa[rnd(qa.length)], r = rnd(100);
document.querySelector('#q').innerHTML = Array(100).fill(0).map((_, i) => {
const c = q.charAt(r != i ? 0 : 1) + ((i % 10 == 9) ? '<br>' : '')
return `<span id="c${i}" onclick="chk('${c}')">${c}</span>`; }).join('');
const chk = c => { document.querySelector('#c'+r).style.color = 'red';
alert((c == q.charAt(1))?'正解!':'失敗'); }
</script></body></html>
そして、ブラウザにファイルをドラッグ&ドロップしましょう。すると、プログラムが実行されて漢字間違い探しの画面が表示されます。一文字だけ違う漢字を見つけたら、クリックしてみましょう。正解かどうか判定し、漢字を赤色にして答えを教えてくれます。
なお、10行のプログラムの中に、10個の問題を収録しているので、ブラウザをリロードしてみると、異なる問題が表示されます。
10行のプログラムを確認しよう
さて、今回の10行のプログラムですが、ちょっと頑張って10行(1行は80字以内)にしています。プログラムを短くするために、三項演算子とアロー関数(無名関数)を利用しています。
そのため、プログラムは、ちょっと読みにくいものになってしまいました。プログラムに改行を入れて、コメントを付け加えると以下のようになります。
<html><meta charset="utf-8"><body>
<p id="q" style="font-size:2em;"></p>
<script>
// 似た漢字の問題データを配列にセット --- (*1)
const qa = ["天夫", "酒洒", "鳥島", "活治", "豪濠", "季李", "兎免", "失矢", "語悟"];
// 手軽に整数の乱数を求める関数を定義 --- (*2)
const rnd = n => Math.floor(Math.random() * n);
// 今回の問題を選択 --- (*3)
var q = qa[rnd(qa.length)]
// 回答の番号(0から99番目の文字)を決定 --- (*4)
var r = rnd(100);
// 問題データをHTMLで作成 --- (*5)
document.querySelector('#q').innerHTML = Array(100).fill(0).map((_, i) => {
// 漢字を選択し、10で割って余り9なら改行を入れる --- (*6)
const c = q.charAt(r != i ? 0 : 1) + ((i % 10 == 9) ? '<br>' : '')
// <span>タグを生成して返す
return `<span id="c${i}" onclick="chk('${c}')">${c}</span>`; }
).join(''); // 配列を結合して文字列にする
// クリックした漢字が正しいかを判定し、答えの漢字を赤くする --- (*7)
const chk = c => {
document.querySelector('#c'+r).style.color = 'red';
alert((c == q.charAt(1))?'正解!':'失敗');
}
</script></body></html>
プログラムを確認してみましょう。(*1)では似た漢字の問題データを配列にセットします。 (*2)では手軽に整数の乱数を利用できるように、rnd関数を定義します。JavaScriptで関数を定義する場合、一般的には下記のように書きます。
function 関数名(引数) { 関数の定義 }
しかし、アロー関数(無名関数の)を使う場合、下記のように定義できます。より簡潔に関数が定義できることが分かるでしょう。
関数名 = 引数 => 関数の定義
プログラムの(*3)の部分では、どの漢字を問題に使うのか問題を選択します。(*1)で定義した配列の中から1つを選択します。
(*4)ではどの場所の漢字を間違った漢字にするのか乱数で決めます。漢字は100文字の中から1文字選ぶので、ここで変数rの値(0から99番目)のどこを間違った感じにするのかランダムに選択します。
(*5)では、HTMLのDOM要素のidが「q」のものを探して、そこに漢字を100文字書き込むという処理を記述します。「Array(100).fill(0)」と書く事で、値が0の要素を100個持つ配列変数を作成できます。そして、map関数を使うことで、各要素の1つずつに対して引数に指定した無名関数の処理を実行します。
map関数の処理(*6)では、配列の要素番号iと(*4)で選んだ変数rを比較します。つまり、答えとなる漢字を表示するか否かをここで選びます。そして、10で割って余りが9ならば改行を挿入します。これによって、10文字毎に改行を入れることができます。
そして、漢字が正しいかどうかを判定するために、漢字を1文字ずつ<span>タグで囲います。それで、漢字がクリックされた時に、関数chkを実行して、正誤判定を行うようにします。
(*7)では、クリックされた漢字が正しいかどうかを判定し、答えの漢字を赤色に変更する関数chkを定義します。ここでも、アロー関数を使って、関数を定義します。
ゲームに制限時間を導入しよう
さて、上記のプログラムでも、一応形になっているのですが、100文字を1つずつゆっくり探していけば、簡単に答えを見つけることができます。そこで、ゲームに制限時間を導入してみましょう。
以下のプログラムを「find_kanji-time.html」という名前で保存しましょう。
<html><meta charset="utf-8"><body>
<h3 id="time">制限時間:10秒</h3>
<p id="q" style="font-size:2em;"></p>
<script>
// 似た漢字の問題データを配列にセット
const qa = ["天夫", "酒洒", "鳥島", "活治", "豪濠", "季李", "兎免", "失矢", "語悟"];
// 手軽に整数の乱数を求める関数を定義
const rnd = n => Math.floor(Math.random() * n);
// 今回の問題を選択
var q = qa[rnd(qa.length)]
// 回答の番号(0から99番目の文字)を決定
var r = rnd(100);
// 問題データをHTMLで作成
document.querySelector('#q').innerHTML = Array(100).fill(0).map((_, i) => {
const c = q.charAt(r != i ? 0 : 1) + ((i % 10 == 9) ? '<br>' : '')
return `<span id="c${i}" onclick="chk('${c}')">${c}</span>`; }
).join(''); // 配列を結合して文字列にする
// 制限時間を設定 --- (*1)
var time = 10;
var timer = setInterval(() => {
// 残り時間を表示 --- (*2)
time--;
document.querySelector('#time').innerHTML = '残り時間: ' + time + '秒';
if (time == 0) { chk(' '); } // 選んだ感じ無効で答えを表示 --- (*3)
}, 1000);
// クリックした漢字が正しいかを判定し、答えの漢字を赤くする
const chk = c => {
clearInterval(timer); // タイマーを停止 --- (*4)
document.querySelector('#c'+r).style.color = 'red';
document.querySelector('#time').innerHTML = (c == q.charAt(1))?'正解!':'失敗';
}
</script></body></html>
ブラウザにドラッグ&ドロップしましょう。すると、プログラムが実行されます。
プログラムを確認してみましょう。(*1)では制限時間に10秒を設定します。(*2)では残り時間を1ずつ減らして、画面に表示します。
(*3)では残り時間が0になったなら、無効な漢字を指定して、答え合わせを行う関数chkを呼び出します。
関数chkでは、(*4)でタイマーを停止して、答えの漢字を赤くます。そして、正解か間違いかを画面に表示ます。
まとめ
以上、今回は、有名な脳トレゲームの「間違い漢字探し」を作ってみました。コメントを省いたり、改行を詰めたりする必要はありましたが、10行のプログラムでゲームを完成させることができました。コメントを加えても24行です。簡単なゲームですが、乱数要素のおかげで、飽きずに繰り返し遊ぶことができます。
また、制限時間のルールを加える改造方法も紹介しました。ほかにも、時間の経過と共に文字が大きくなったり、選択候補が減っていったりと、アイデア次第で面白い改造ができることでしょう。ぜひ、オリジナルの脳トレゲームを作ってみてください。
自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。直近では、「実践力をアップする Pythonによるアルゴリズムの教科書(マイナビ出版)」「シゴトがはかどる Python自動処理の教科書(マイナビ出版)」「すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応(ソシム)」「マンガでざっくり学ぶPython(マイナビ出版)」など。