2022年6月3日金曜日

連想ゲーム Rensole の開発メモ

単語の類似度を使った連想ゲーム Rensole (下) を作って、Zenn に紹介記事を書いてみました。 このページではもう少し真面目に開発のメモをまとめておきます。



Rensole では単語の類似度を頼りに隠された単語を探します。多言語対応が簡単なので、 英語日本語中国語 を作っています。 本当はひらがな版も作ろうとしたのですが、予測候補がひらがなだとわかりにくくて微妙だったので、漢字ありです。

Magnitude ですぐに作れるのがウリ

Rensole では 2つの基本語彙のベクトルを比較して類似度測定をしながら単語を探します。 実のところ fastText を Magnitude に変換すれば、すぐにできます。 Magnitude の中身は SQLite DB なので、そのまま sql.js-httpvfs に乗せるだけで実現できます。 基本語彙は約 5万語なので、25億回ほど類似度を事前計算すればもう少しコンパクトに実現もできました。 ただ何かに応用しようとしたときに作り直すのも微妙なので、Magnitude の DB をそのまま使っています。 ゲーム自体は fastText の単語ベクトルと基本語彙さえわかれば、どんな言語にも適用できます。

ゲームにするのは意外と難しい

作ってみると気付くことも多く、Wordle ではアルファベットのヒントを与えやすいですが、 Rensole では与えにくいことが問題になりました。 しかし何らかのヒントを与えないとあまりにも難しくて面白くないので、その解決に苦労しました。

まずはノーヒントで単語を予想するものをモックで作ったのですが、100手くらい普通に掛かることもあって面倒くさかったです。 類語のヒントを出せばそれなりに予想ができるようになったものの、意外と正答率が安定しません。 一瞬だけ Wordle 的なアルファベットのヒントを与えることを考えましたが、それじゃあ連想ゲーム感があまりなさそうだし。 類語のヒント量を 10 から 20 に増やしてもほとんどヒントになっていません。 類語として使えるのは 10 が限界に見えます。 さてどうしたものかとなりました。

そこで日本語版では、文字数→ひらがな/カタカナ/漢字→1文字だけヒント→履修学年のヒントを与えるように実験してみたら、十分解けてまあまあ良かったです。 1文字のヒントはあまりにも大きいのですが、ひらがな/カタカナ/漢字のヒントは 0.5文字くらいのヒントになっていることがうまく働いていると気付きました。 そしてそのヒントは、部分的な読み情報であること、どんな言語にも共通して利用できることに気付きました。

読み情報をヒントにしたら意外と面白かった

海外版は日本語版での実験を踏まえて作りました。 中国語は、文字数→ピンインからヒント→1文字だけヒント→ピンインから1文字ヒント…にしてみました。 中国には漢字配当表がないのでヒントもシンプルです。 日本語版と情報量はほぼ一緒なので、中国語はたぶん解けると思います。 ただ難易度調整はできてないので、解けなかったらごめんね。

英語は日本語や英語より文字数が多いことに注目します。 文字数→発音記号を1つヒント→1文字だけヒント→発音記号を1つヒント→もう1文字ヒントの順にしました。 発音記号は使いやすいライブラリがなかったので、cmudict-ipa という発音辞書を作りました。 発音そのものには CMUDict という素晴らしい辞書があるのですが、特殊な発音記号を使っているので一般的な IPA 形式に変換しました。 この辞書を使って、a-z 以外のアルファベットに対してヒントを出せば、知っている単語なら解けるとわかりました。 一番悩んだのは発音のヒント量です。特に英語が難しい。 文字数に応じてもう少しヒントを出したほうが良いかな? 私だと難しい単語はヒントがあってもなくても解けないので、どれくらいが良いのか何とも言えない。 要望があったら調整してみます。

英語や中国語でも発音のヒントを作ると、今度は日本語も同じようにローマ字のヒントを出しても良いかもと思い始めました。 日本語は中国語や英語と違って文字数が一意に定まらない欠点があり、ヒントになっていないケースも多いですが、 ひらがな/カタカナのヒントにはなりそうです。という訳でローマ字のヒントも付けました。 基本的にはサクサク解けるゲームにしたかったので、ヒントはいくらでも出すノリで作っています。

レベルを分けて誰でも遊べるようにした

ヒントの出し方が決まってゲームの方向性が決まったところで、細かな調整に入りました。 Wordle は基本的に解けるゲームですが、Rensole は難しい問題がたまにあります。 日本語の感触では、だいたいは解けるレベルに収まっていますが、解けない問題は絶望的に解けないです。 こればかりはどうしようもない。 1日1回の縛りは難しいので、すばやく諦めてもらう代わりに、気軽に答えを見られるようにしました。

何十回かプレイしてみると、日本語以外で難易度を上げると、ヒントをいくら出しても太刀打ちできない問題を感じました。 語彙数が増えすぎると、そもそも単語がわからないので、つまらない。 そしてサクサク解けると、毎回わからないことが増えるので、ゲーム性での粗が目立ちました。 ちなみに Wordle も知らない単語が出てくると、最後はブルートフォースアタックになるので同じ課題はあるのですが、 単語の意味がわからなくても解けるし、1日1回縛りだから粗が目立たないようになっています。

Rensole ではこの問題がさすがに気になったので、色々なレベルを用意して単語学習アプリとしても遊べるようにしました。 これで語彙数が少ないからプレイできない、面倒だからいいや、とはならないようにしたつもり。 ただ語彙数が少ないとヒントが雑になるので、簡単になっているかはわからない。

言語資源としても面白い

言語ごとに辞書のサイズと検索結果を比較してみると、割と面白いです。 中国語や英語の語彙数は思っているより少なくて、正規化すると 5万くらいしかありません。 一方の日本語は、正規化しても 8万語はあります。 ちなみに正規化も色々あって、表記ゆれを許容すると 8万語で、表記ゆれを許さないと 6万語になって、どの言語も同じくらいになります。 そういえば 日本人の語彙数は小6で 2万語、大人で 5万語 とわかっています。 これは正規化していない状態を指しているんじゃないかな。 英語のネイティブの語彙数は、色々なサイトを見ても 3万くらいしかないんですよね。

語彙数の違いは、少ない語彙数でのゲームに影響が大きいです。 英語は 1000語くらいでもゲームになりますが、日本語は 5000語くらい用意しないと、ゲームになりにくい感じです。 上位に助詞や感嘆詞が大量に入ってくるのが一番の原因に見えますが、表記ゆれが頻度の高い語彙でも重要ということでしょう。 たとえば「歩く」すら上位 1000語に入らないのは、なかなかすごいなと思いました。

最後に

何となく形にはなったのですが、これで良いのかどうかは怪しいところが多々あります。 プレイする人がいたら、その声を聞いて改善できたら良いなと思います。 作ってみた気付きとしては、言語系のゲームは最初から日中英も作ればグローバル展開できるかわかるので、一番最初にやるのが良さそうです。

0 件のコメント: