タイピングゲーム

タイピングゲーム(2022-04-02)


なんとなくトップページがタイピングゲームにりました
仕事や勉強の合間の息抜きにどうぞ。



タイピングゲーム

  • FかJボタンを押すと始まります。
  • 問題文をクリックすると、GoogleとかBingとかで検索できます。
    (知らない単語が出てきても安心ですね)
  • 時間が経つと、次のボタンの位置を教えてくれます。
  • 誤入力せずに単語を打てたら1点です。
  • 問題文は一時間くらいで更新されます。
  • スマホだと、たぶん画面が小さすぎて無理です。


英単語を覚えたい方には、英語問題はSCOWLというスペルチェッカーリスト*1から抜粋していて、

  • 英語(かんたん)が、5文字以下の基本的な1000語から十問
  • 英語(むずかしい)は、上記1000以外の 5000語から二十問
  • 英語(めんどくさい)は上記を「含む」、18000語から三十問

となっています。

あと「タイピングゲーム~基礎」は小学校低学年で習う漢字だけが出てきます。
気分転換にどうぞ。


ここまで大それたものを作るつもりはなかったんですが、作っているうちに意地になってしまって、こうなりました。


余談ですが(というか、タイピングゲーム作ってみた理由の一つでもあるんですが)、
いまの学生って学校からノートPC(ChromeBookとか)を持たされると聞いて驚きました。

パソコン好きな子には本当に良かった話だと思いますが、嫌いな人には悲惨ですよね……会社から業務用携帯を持ち帰らせることだって国によっては規制される風潮にあるくらいなのに、つらい時代になりましたね…

作りたい人に向けて

HTML と JavaScriptって、Webブラウザですぐに動かせるという点では最も身近なプログラミング言語だと思います。

もし、例のページをWebブラウザの「ソースを表示」とかで見ようとしている人が居れば、大まかな部分について以下に初心者向け(?)に解説します。*2

基本の部分

メモ帳で以下を書いて、拡張子を「.txt」ではなく「.html」で保存します。

<html>

<head>
  <script>
     alert("こんにちは");
  </script>
</head>

<body>

<div id=ID>Hello world!</div>

</body>
</html>

注意点としてファイルを保存する時に文字コードを「UTF-8」にする必要があります。*3
メモ帳各種で「名前を付けて保存」を選べば、文字コードも選択して保存できると思います。

保存できたらファイルを開きましょう。Webブラウザで開かれると思います。

HTMLやJavaScriptの解説は他のサイトに譲ります。
ただ、「動いた!」という喜びだけを味わってください。

これはお好みで、ですが、
Webブラウザでデバッグする場合はChrome、FireFoxともに「Ctrl + Shift + I」(エルではなくアイです)を押せば開発ツールが起動できます。
それで「コンソール(またはConsole)」のタグを開きましょう。

ツールを使いこなす必要はありません。
ただ、Consoleを開きながら F5キーとかで再読み込みした時に、文法エラーがあれば何行目がダメなのか教えてもらえるようになります。
これでダメだった部分を修正して、上書き保存して、F5キーで再読み込みするのを繰り返せば、 それっぽく HTML/JavaScriptプログラミングができるわけです。

最初に動く処理

このスクリプトってスタート地点はどこなの? って話です。

<html>

<head>
  <script>
    document.addEventListener("DOMContentLoaded", function(){
      alert("読み込みが終わったらここが呼ばれます");
    },false)
    window.addEventListener('load', function(){
      alert("色々と読み込み順や方法に差はあるのですが、まずはお好みでどうぞ。");
    },false);
    alert("ここだとbody本文の前に呼ばれます");
  </script>
</head>

<body>
  <div id=ID1>Hello world!</div>
</body>
</html>

まずは DOMContentLoaded などで最初にやりたい処理を書き込みます。
私のタイピングゲームの場合は後述のイベントリスナー(EventListener)やタイマーをここに書くことになります。

キーボード入力を拾う

タイピングゲームなら、キーボード入力を拾う必要があるわけです。

<html>

<head>
  <script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function(){
      function f(e){
        var html = document.getElementById("ID1");
        html.innerHTML = e.key;
      }
      document.addEventListener("keydown", f, false);
    },false)
  </script>
</head>

<body>

<div id=ID1>Hello world!</div>

</body>
</html>

上の例では画面全体(document)に対してのキーボード入力(keydown)を拾っています。
これと同じ感じで特定のHTMLタグへのクリックや、チェックボックスに対しての入力を拾えば色々できます。

タイマーを動かす

開始時の3秒間カウントダウンや、2秒間入力が無かった時にヒントを出すとかは以下のようなタイマー処理を利用しています。

<html>

<head>
  <script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function(){
      function f(e){
        var html = document.getElementById("ID1");
        html.innerHTML = i;
        i++;
      }
      i=0;
      setInterval(f, 1000);
      
    },false)
  </script>
</head>

<body>
 <div id=ID1>Hello world!</div>
</body>
</html>

何か時間の経過で動かしたいものがあればキーボードや画面タップのような(いわゆるイベント・ハンドラ)処理とは別に、タイマーを設定する必要があります。

ここまで分かればもう、半分以上はできたようなものです、本当に。


あとは、

  1. 問題文("a"とか"b"とかの半角英字)を用意する
  2. キーボード入力と問題文が一致したら「クリア!」と表示する
  3. 問題文を長文にする
  4. 問題文を一問から三問に増やす
  5. 問題文を日本語化して、ローマ字変換表を用意する
    (私のタイピングゲームでは別ファイルに分けている部分です)
  6. ゲーム開始時にカウントダウンする
  7. キーボードを表示して、次のボタンを教えてあげる
  8. せっかくキーボード作るんなら、押せるように…
  9. 分からねぇ単語ばっかりだな…いっそWeb検索できるようにするか?

…のように少しずつ複雑にしていきました。

というより、こういうのがあると便利だろうなぁとか色々と足しているうちにこうなりました
当初の予定ではここまでやる気は無かったんです。


…たべものを10個、順にタイピングしていると気分転換になる反面、なんだか空腹になるかもしれません。

問題文用の単語リストについて

問題文にするネタは 日本語はMozc辞書から、英語は SCOWL(Spell Checker Oriented Word Lists)から抜粋しています。*4

注意点として、そのまま使うことはできません。抜粋する作業は必須です。
バカとかアホとか、それよりもっとキツイ単語もとうぜん辞書の中には含まれるので、何も考えずに一覧をそのまま入力情報として使ったりはしないようにしましょう。

あとはライセンス(著作権)の問題。
(上記2つは一応、メモ時点ではPublic Domainです)。
辞書に限らず文字でも画像でも音でも、他の人が作ったものを個人利用では無く公開する場所で利用する時にはライセンスを確認しましょう。

とはいえ、
Mozcについては別でメモしていますが、一般固有名詞(ID:1847)だけでも軽く20万行(!?)を超えます。
ここから抜粋していく作業は辞書や辞典を最初から順番に読むようなものなので、むしろ数日かけて自分が知っている単語を上げていった方が早いかもしれません。

SCOWL についてですが、
ダウンロードしてきた tar.gz ファイルに「final/」ってディレクトリがあって、そこに登場頻度レベルと英語圏(イギリス/アメリカ/カナダ/オーストラリア)別にされたリストが入っています。
そのまま使ったらダメな語は「misc/」ディレクトリに入っていますが、これだけを除外しても全然足りません。
MozcもSCOWLもスペルチェッカーとして使うならともかく、別用途で使うなら単語の採用・不採用の自己判断をしておきましょう。


ちなみに、「しりとり」をつくるコツは10問目、9問目、8問目…と最後から頭に向かって作るのがコツです。
「タイピングゲーム~30問」の11~25問目で必ず「ん」で終わるのは逆順に作っているからです。

大量のデータを目視しないといけない人へ

不運にものっぴきならない事情で数千~数万行をいちいち目視でチェックしなければならない人に向けて…

ファイルで一行ずつ表示しながら仕分けしていくためのPerlスクリプトの例です。

#!/usr/bin/perl -w 

use IO::Prompt;

my $in_file = "./input.txt";
my $file_pre = "";
my $file_suf = ".txt";
my $out_dir = "./sample";

my $count = 0;
open($IN, "< $in_file") or die "$! [$in_file]\n";
while(<$IN>){
  $count++;
  // if($count < 10){ next; } // 作業を中断した場合に、10行目から再開とか
  $line = $_;
  chomp($line);
  while(1){
    printf("%d:%s\n", $count, $line);
    my $key = prompt "[1/2/3で採用、除外候補はSPACE]>", -one_char => '';
    my $fname = "";
    if($key =~ /[ ]/){
      $fname =  $file_pre . "0" . $file_suf;
      printf(" -> 0へ[%s]\n", $fname);
    }
    elsif($key =~ /([123])/){
      $fname =  $file_pre . $1 . $file_suf;
      printf(" -> $1 %s\n", $fname);
    }
    if(length($fname) > 0){
      my $out_file =  $out_dir . "/" . $fname;
      open($OUT, ">> $out_file") or die "$! [$out_file]\n";
      printf($OUT "%s\n", $line);
      close($OUT);
      last;
    }
  }
}
close($IN);

重要なのは入力手順を可能な限り減らすこと、です。
上記では IO::Prompt の prompt関数を使っています(たぶん別途インストールが必要)。

もちろんPerl以外でも問題ありません。
Shellスクリプト(bash)だと read -n で一文字待ちにできるようですね。

# ためしに一文字待って、すぐに echo してみるコマンド例
read -n 1 TEST && echo "#$TEST#"

作業量が多くなってしまった場合に、キー入力待ちでいちいちEnterキーを数千回たたくと指がもげるので、一文字でも入力を減らす(片手でも仕分け作業ができる)ようにする必要があります。
それこそ辞書片手に仕分け作業する必要とかもあるでしょうし。

あと、上記の例のように作業を中断しても途中行から再開できるようにしたり、抽出条件をつけたり見やすく表示したり重複確認したりをスクリプト内で工夫して少しでも作業が楽になるようにしていかないと、疲れ目で目がもげます。
もげないようにがんばって下さい。

PukiWiki ユーザの方へ

なんでトップページでいきなりタイピングゲームが始まる仕様になっているのか? についてですが。

これは単純に「skin/pukiwiki.skin.php」の中で処理を分けているだけです。

<?php
if(strcmp($title, $defaultpage) == 0){
   // ここにトップページだけでやらせたい処理を書く
} else {
   // 通常の、トップページ以外の処理はこちら
   // echo $body; とか
}
?>

Wikiの中身って普段は「echo $body;」で書き込んでいますよね? ここをまるっと差し替えます。
あとは JavaScriptの処理は HTMLの head タグ内で書くので、そちらも pukiwiki.skin.phpの中から探して、追記 or 差し替えます。
問題文も「wiki/」ディレクトリではなくて一時間おきに別に用意したファイルから読み込ませて、更新しています。


ふらっと現れたタイピングゲームは、ふらっと消えるかもしれませんが、ひとまずこれにて。
みなさんの気分転換になれば幸いです。


*1 SCOWLのレベル40リストからあたり障りの無さそう単語を抜粋しています。あたり障る語というのはfu*kとかです。
*2 別にソースの難読化とかはしていません。それでも画像ファイルや外部ライブラリとか一切使っていない分、一般的なタイピングゲームよりは遥かにサイズは小さいと思います。
*3 htmlファイル内で文字コードも指定すればUTF8でもShiftJISでもどちらでも良いのですが、Web上で使われるのはUTF8が主流です。
*4 これらの作業は以前に「画面フィルターにメモ機能を付けた時」に経験したことがあったので、それを今回のタイピングゲームにも流用しました。