タイピングゲーム全文字対応の小話

日本語の面倒くささを体感した話。

日本語のローマ字入力を行う際、入力パターンが複数あるものがあります。

例えば

・「ん」を打つ際は

「xn」「n」「nn」「’n」

・「っく」を打つ際は

「kku」「ccu」「qqu」「xtuku」「xtucu」「xtuqu」「ltuku」「ltucu」「ltuqu」

などのように、複数パターンある打ち方に対応したゲームにするために考えたことを書いていきます。寿司打やe-typingなどはこの形式をとっていますね。(笑)。

固定ページにある僕のタイピングゲームもおそらくバグがないシステムになっています。

では実際に考えられる方法は?

方法として考えられるのは

・if分を用いて例外のタイプすべてに条件分岐をつけることで、入力タイプに応じて正誤判定を行い、文字列を入れ替える。

・ひらがなの打ち方をあらかじめ定めて置き、入力タイプに応じて正誤判定を行い、文字列を入れ替える。

の二パターンが考え当たります。

一つ目のほうは問題点として、

if分のネストがすごいのとelifの分岐がすごいことになることなど、限定的な打ち方すべてをコードで表現するのは骨が折れると考えられます。

pythonで書いてみます。

          #キーが押されたときの処理
             if event.type == pygame.KEYDOWN: 
          #正解 
                if chr(event.key) == word[0]: 
                     word = word[1:]
                     count_c += 1
          #z,jだけの特例処理
                elif((chr(event.key)=="j") and (word[0]=="z")):
                     word = word[1:]
                     count_c += 1
          #si,ci,se,ce
                elif((chr(event.key)=="c") and (word[0]=="s" and (word[1]=="i" or word[1]=="e"))):
                     word = word[1:]
                     count_c += 1
          #hu,fu
                elif((chr(event.key)=="f") and (word[0]=="h")):
                     word = word[1:]
                     count_c += 1
          #ka,ca,ku,cu,ko,co
                elif((chr(event.key)=="c") and (word[0]=="k")):
                     word = word[1:]
                     count_c += 1
          #ku,qo,ko,qo
                elif((chr(event.key)=="q") and (word[0]=="k")):
                     word = word[1:]
                     count_c += 1
          #間違い
                else :
                     count_m +=1

やってみてすぐ後悔できるくらいには分岐が多いですね。

上のコードでは

「じ」「せ」「ふ」「か」「く」「こ」

の対応をしています。

これらに小文字の処理が加わってくると…….

無理ですね。(; ・`д・´)

私のゲームは二つ目を使用しています。

*とあるタイピングサイトで、プレイヤーが入力した課題文問題にを設定できるものがあります。入力のさせ方を見るとおそらく、この作り方と同じ作り方をしているだろうと推測できます。

入力フォーム  漢字ーひらがな みたいな感じです。

python・辞書型だとこんな感じになります。

word_dict = {

“先物取引”:”さきものとりひき”,

“オプション取引”:”おぷしょんとりひき”,

“外国為替証拠金取引”:”がいこくかわせしょうこきんとりひき”}

↓以下、文字の対応表↓

"あ":["a"], "い":["i","yi"], "う":["u","wu","whu"], "え":["e"], "お":["o"],
"か":["ka","ca"], "き":["ki"], "く":["ku","cu","qu"], "け":["ke"], "こ":["ko","co"],
"さ":["sa"],"し":["si","ci","shi"],"す":["su"],"せ":["se","ce"],"そ":["so"],
"た":["ta"],"ち":["ti","chi"],"つ":["tu","tsu"],"て":["te"],"と":["to"],
"な":["na"],"に":["ni"],"ぬ":["nu"],"ね":["ne"],"の":["no"],
"は":["ha"],"ひ":["hi"],"ふ":["hu","fu"],"へ":["he"],"ほ":["ho"],
"ま":["ma"],"み":["mi"],"む":["mu"],"め":["me"],"も":["mo"],
"や":["ya"],"ゆ":["yu"],"よ":["yo"],
"ら":["ra"],"り":["ri"],"る":["ru"],"れ":["re"],"ろ":["ro"],
"わ":["wa"],"を":["wo"],"ん":["n","n'","xn"],
"が":["ga"],"ぎ":["gi"],"ぐ":["gu"],"げ":["ge"],"ご":["go"],
"ざ":["za"],"じ":["zi","ji"],"ず":["zu"],"ぜ":["ze"],"ぞ":["zo"],
"だ":["da"],"ぢ":["di"],"づ":["du"],"で":["de"],"ど":["do"],
"ば":["ba"],"び":["bi"],"ぶ":["bu"],"べ":["be"],"ぼ":["bo"],
"ぱ":["pa"],"ぴ":["pi"],"ぷ":["pu"],"ぺ":["pe"],"ぽ":["po"],
"きゃ":["kya","kilya","kixya"],"きぃ":["kyi","kili","kixi","kilyi","kixyi"],
"きゅ":["kyu","kilyu","kixyu"],"きぇ":["kye","kile","kixe","kilye","kixye"],
"きょ":["kyo","kilyo","kixyo"],
"ぎゃ":["gya","gilya","gixya"],"ぎぃ":["gyi","gili","gixi","gilyi","gixyi"],
"ぎゅ":["gyu","gilyu","gixyu"],"ぎぇ":["gye","gile","gixe","gilye","gixye"],
"ぎょ":["gyo","gilyo","gi"],
"しゃ":["sya","sha",],"しぃ":["syi","sili","sixi","silyi","sixyi"],
"しゅ":["syu","shu","silyu","sixyu"],"しぇ":["she","sye","sile","sixe","silye","sixye"],
"しょ":["syo","sho","silyo","sixyo"],
"じゃ":["ja","zya","jya","zilya","zixya","jilya","jixya"],
"じぃ":["zyi","jyi","zili","zixi","jili","jixi","zilyi","zixyi","jilyi","jixyi"],
"じゅ":["zyu","ju","jyu"],"じぇ":["zye","je","jye"],"じょ":["zyo","jo","jyo"],
"ちゃ":["tya","cha","cya"],"ちぃ":["tyi","cyi"],"ちゅ":["tyu","chu","cyu"],"ちぇ":["tye","che","cye"],
"ちょ":["tyo","cho","cyo"],
"にゃ":["nya"],"にぃ":["nyi"],"にゅ":["nyu"],"にぇ":["nye"],"にょ":["nyo"],
"ひゃ":["hya"],"ひぃ":["hyi"],"ひゅ":["hyu"],"ひぇ":["hye"],"ひょ":["hyo"],
"ふぁ":["fa","fwa"],"ふぃ":["fi","fwi","fyi"],"ふぅ":["fwu"],"ふぇ":["fe","fwe","fye"],"ふぉ":["fo","fwo"],
"くぁ":["qwa","qa","kwa"],"くぃ":["qwi","qi","qyi"],"くぅ":["qwu"],
"くぇ":["qwe","qe","qye"],"くぉ":["qwo","qo"],
"ぐぁ":["gya"],"ぐぃ":["gyi"],"ぐぅ":["gyu"],"ぐぇ":["gye"],"ぐぉ":["gyo"],
"すぁ":["swa"],"すぃ":["swi"],"すぅ":["swu"],"すぇ":["swe"],"すぉ":["swo"],
"てゃ":["tha"],"てぃ":["thi"],"てゅ":["thu"],"てぇ":["the"],"てょ":["tho"],
"とぁ":["twa"],"とぃ":["twi"],"とぅ":["twu"],"とぇ":["twe"],"とぉ":["two"],
"ぢゃ":["dya"],"ぢぃ":["dyi"],"ぢゅ":["dyu"],"ぢぇ":["dye"],"ぢょ":["dyo"],
"でゃ":["dha"],"でぃ":["dhi"],"でゅ":["dhu"],"でぇ":["dhe"],"でょ":["dho"],
"どぁ":["dwa"],"どぃ":["dwi"],"どぅ":["dwu"],"どぇ":["dwe"],"どぉ":["dwo"],
"びゃ":["bya"],"びぃ":["byi"],"びゅ":["byu"],"びぇ":["bye"],"びょ":["byo"],
"ぴゃ":["pya"],"ぴぃ":["pyi"],"ぴゅ":["pyu"],"ぴぇ":["pye"],"ぴょ":["pyo"],
"りょ":["ryo"],"ょ":["lyo","xyo"],
"ー":["-"]," ":[" "],
"っ":["xtu","ltu","xtsu","ltsu"],
"ぁ":["xa","la"],
"ぇ":["xe","le"],
"ゃ":["lya","xya"],"ゅ":["xyu","lyu"]

おそらく日本語の打ち方は上の表ですべてカバーできていると思います。

ローマ字に変換する文字列 = ”ひらがなにへんかんする”

上の文字列を打ち方の辞書に照らし合わせてローマ字に変換します。

”hiragananihenkansuru”

に変換されるとひとまずのもっとも簡単な課題クリアです。

次に ローマ字に変換する文字列 = ”ひらがなでひょうじする”

を変換する際、対応する文字をそのまま変換すると

”hiraganadehilyoujisuru”

に変換されます。

しかし、最も短い打ち方(一般的な打ち方)は

“hiraganadehyoujisuru”

であるため、辞書の参照の仕方に工夫を施す必要があります。

ひらがなを最短の打ち方に分解するコードはこんな感じになります。

def kana_divide(kana):                     #↓↓↓  ひらがな(kana)を分割しリスト化する関数(kana_divide)  ↓↓↓
     kana_separate = []                   
     ltu = ["a","i","u","e","o","n"]
     count = 1                             #小文字(string_small)の処理に使用
     judge = -1                            #「っ」の処理に使用

     for i in range(len(kana)):            #kanaの文字数分繰り返す
         if judge == i:                    #前回「っ」の処理をしていたら今回処理なし
             continue

         else:
             if i != 0 and kana[i-1] + kana[i] in string_dict:   #小文字の処理↓
                 b = kana_separate.pop(i-count)#ひとつ前の文字を削除
                 a = b + kana[i]   #ひとつ前の文字と合わせてリスト(kana_separate)に加える
                 kana_separate.append(a)
                 count += 1                #リストとiのずれを修正

             elif i != len(kana) - 1 and kana[i] == "っ" and string_dict[kana[i+1]][0][0] not in ltu:         #「っ」の処理↓
                 a = kana[i] + kana[i+1]   #次の文字と合わせてリスト(kana_separate)に加える
                 kana_separate.append(a)
                 judge = i+1               #次の処理を飛ばす判定に使用
                 count += 1                #リストとiずれを修正

             else :                        #通常の処理↓
                 a = kana[i]               #そのままリスト(kana_separate)に加える
                 kana_separate.append(a)

     return kana_separate                  #分割されたひらがなリスト(kana_separate)を返す

ここから切り分けたひらがなを辞書に照らし合わせてローマ字に変換していきます。

感想

どちらの方法をとっても面倒くさいですね。(´Д⊂ヽ

細部にこだわったところで、いちユーザーの入力方法は一つのパータンであることが多いので、プログラムの大変さに気が付いてもらえないでしょう。

プログラムを始めて、作る側の苦労がわかるようになりました。感謝を忘れないように生きていきたいですね。

しかし全ユーザーに(特殊な打ち方をするユーザーに)心地よくゲームを楽しんでもらうには対応は必要になってくるでしょう。

ユーザーありきを胸にとどめて頑張っていきます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です