Re: 複数の入力方式に対応させたい ( No.1 ) |
- 名前:管理人 日時:2019/01/26 00:25
真面目に対応しようとすると結構面倒くさいと思いますので、入力する文字列は1対1の方が良いかもしれません
まず以下のような構造体を定義します
// 文字変換データ
struct CONVDATA
{
// ローマ仮名に変換する前の文字列
char *BaseString ;
// 入力するアルファベットの文字列
char *InputChars[ 10 ] ;
} ;
そして上記の構造体で以下のようなテーブルを作成します
CONVDATA StringConvTable[] =
{
{ "ぁ", { "xa", "la" } },
{ "あ", { "a" } },
{ "ぃ", { "xi", "li" } },
{ "い", { "i" } },
{ "じ", { "zi", "ji" } },
{ "しぇ", { "sye", "she", "sixe", "shixe", "sile", "shile" } },
{ "じぇ", { "zye", "je", "jye", "zixe", "zile", "jixe", "jile" } },
{ "しゃ", { "sya", "sha", "sixya", "shixya", "silya", "shilya" } },
{ "じゃ", { "zya", "ja", "jya", "zixya", "jixya", "zilya", "jilya" } },
{ "しゅ", { "syu", "shu", "sixyu", "shixyu", "silyu", "shilyu" } },
{ "じゅ", { "zyu", "ju", "jyu", "zixyu", "jixyu", "zilyu", "jilyu" } },
{ "しょ", { "syo", "sho", "sixyo", "shixyo", "silyo", "shilyo" } },
{ "か", { "ka" } },
{ NULL, { NULL } },
};
沢山ありすぎるので端折っていますが、あ〜んまでの50音とがぎぐげご、ぱぴぷぺぽ、しゃしゅしょなどの
入力パターンを上記のようにすべてテーブルに書き込みます
次に実際に入力処理を行うための構造体を定義します
struct TYPINGDATA
{
// 入力すべき文字列を変換テーブルの対応するインデックスに置き換えたもの
int TableIndex[512] ;
// インデックスの数
int TableIndexNum ;
// 入力が完了したインデックスの数
int CompleteIndexNum ;
// 現在入力中の文字列
char TypingString[ 20 ] ;
// 入力が完了した文字列
char CompletionString[ 512 ] ;
} ;
そしてこれを
TYPINGDATA TypingData ;
のようにしてグローバル変数にしておきます
実際にタイピングをする際は、タイピングの準備として
int ConvertString( char *BaseString ) ;
のような、"じかんをはかる" などの入力すべき文字列の各文字を StringConvTable 配列の何番目の要素番号と
対応しているかを調べて TYPINGDATA の TableIndex 配列に代入する関数を作成します
( 画面に表示する "時間を計る" といった漢字の文字列は "じかんをはかる" といった『読み』の文字列とは別に用意します )
例えば "じ" は StringConvTable の要素 4 に対応しているので TableIndex[ 0 ] には 4 が代入されるような感じです
そしていざタイピングが始まったら最初の文字 "じ" をプレイヤーは入力するわけですが、"じ" に対応する
ローマ仮名の文字列は "zi" と "ji" なので、z と j 以外が入力されたら誤入力として判定して、
z または j が入力されたら成功入力として TYPINGDATA 構造体のメンバー変数 TypingString に入力された文字を追加します
2文字目が入力された場合は 1文字目の入力と合わせて CONVDATA 構造体のメンバー変数 InputChars と比較して
入力文字が正しいかどうかを判定します( ji や zi ではなく ja や jm などが入力されたら誤入力判定 )
無事 zi または ji と入力されて "じ" が完了したら、次の "か" の文字に対して同じように処理をする、という感じです
ただ、小さい『つ』("っ")はそれ単体では判定できず、続く1文字の子音を2連続で入力した場合のみ成功とする必要があったり
( 例: "たった" は "tatta"、"のっく" は "nokku" など、"っ" 単体では入力すべき文字列が確定しない )
『ん』は n を2回入力した場合や、1回だけでも次の文字が『な行』ではなければ問題なく入力が成功したことにする必要があるなど、
特別処理を行う必要があります
というわけで、真面目にローマ仮名入力をするのと同じ感覚でタイピングできるようにしようとするとかなり面倒なので、
十分に作業時間を確保できる場合にのみ挑戦されることをお勧めします (・・;
|
Re: 複数の入力方式に対応させたい ( No.2 ) |
- 名前:サイゲン 日時:2019/01/26 16:12
管理人様
方法案のご教授、ありがとうございます。
非常にややこしく、難しいんですね…
StringCovTableの書き方というか表現方法を初めて見たので、どうやってアクセスしたり要素番号を割り出すかがよくわからないです。
Convert String関数からのサンプルを教えてくださると、幸いです
|
Re: 複数の入力方式に対応させたい ( No.3 ) |
- 名前:管理人 日時:2019/01/26 23:34
> StringCovTableの書き方というか表現方法を初めて見たので、どうやってアクセスしたり要素番号を割り出すかがよくわからないです。
とりあえず ConvertString の中身を作成してみましたので、よろしければご覧ください
実行すると WinMain の ConvertString 呼び出しで渡した文字列 "あAかしょ" の各文字がテーブルの番号に変換された
1 13 12 11
が表示されます
#include "DxLib.h"
// 文字変換データ
struct CONVDATA
{
// ローマ仮名に変換する前の文字列
char *BaseString ;
// 入力するアルファベットの文字列
char *InputChars[ 10 ] ;
} ;
CONVDATA StringConvTable[] =
{
{ "ぁ", { "xa", "la" } },
{ "あ", { "a" } },
{ "ぃ", { "xi", "li" } },
{ "い", { "i" } },
{ "じ", { "zi", "ji" } },
{ "しぇ", { "sye", "she", "sixe", "shixe", "sile", "shile" } },
{ "じぇ", { "zye", "je", "jye", "zixe", "zile", "jixe", "jile" } },
{ "しゃ", { "sya", "sha", "sixya", "shixya", "silya", "shilya" } },
{ "じゃ", { "zya", "ja", "jya", "zixya", "jixya", "zilya", "jilya" } },
{ "しゅ", { "syu", "shu", "sixyu", "shixyu", "silyu", "shilyu" } },
{ "じゅ", { "zyu", "ju", "jyu", "zixyu", "jixyu", "zilyu", "jilyu" } },
{ "しょ", { "syo", "sho", "sixyo", "shixyo", "silyo", "shilyo" } },
{ "か", { "ka" } },
{ "A", { "a" } },
{ "B", { "b" } },
{ "C", { "c" } },
{ "D", { "d" } },
{ "E", { "e" } },
{ NULL, { NULL } },
} ;
struct TYPINGDATA
{
// 入力すべき文字列を変換テーブルの対応するインデックスに置き換えたもの
int TableIndex[512] ;
// インデックスの数
int TableIndexNum ;
// 入力が完了したインデックスの数
int CompleteIndexNum ;
// 現在入力中の文字列
char TypingString[ 20 ] ;
// 入力が完了した文字列
char CompletionString[ 512 ] ;
} ;
TYPINGDATA TypingData ;
int ConvertString( char *BaseString )
{
int CharAddr ;
int j ;
int k ;
// インデックスの数を初期化
TypingData.TableIndexNum = 0 ;
// 終端文字( 数値で0 )があるまで繰り返す
CharAddr = 0 ;
while( BaseString[ CharAddr ] != 0 )
{
// テーブルの BaseString に一致する文字を探す
// BaseString が NULL だったらテーブルの終端なのでループを抜ける
for( j = 0 ; StringConvTable[ j ].BaseString != NULL ; j ++ )
{
// テーブルの文字( "あ" や "い" など )の終端まで一致しているか調べる
for( k = 0 ; StringConvTable[ j ].BaseString[ k ] != 0 ; k ++ )
{
// 文字が違ったらループから抜ける
if( BaseString[ CharAddr + k ] != StringConvTable[ j ].BaseString[ k ] )
{
break ;
}
}
// テーブルの文字と一致していたらループを抜ける
if( StringConvTable[ j ].BaseString[ k ] == 0 )
{
break ;
}
}
// もしループを抜けた理由が『テーブルの終端に達してしまった』だったら
// テーブルに無い文字だったということなのでエラーとして -1 を返す
if( StringConvTable[ j ].BaseString == NULL )
{
return -1 ;
}
// 一致したテーブルのインデックスをセットする
TypingData.TableIndex[ TypingData.TableIndexNum ] = j ;
// インデックスの数を増やす
TypingData.TableIndexNum ++ ;
// 文字の位置をテーブルの文字のサイズ分だけ進める
CharAddr += k ;
}
// 成功したら 0 を返す
return 0 ;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
ConvertString( "あAかしょ" ) ;
DrawFormatString( 0, 0, GetColor( 255,255,255 ), "Num:%d Index: %d %d %d %d",
TypingData.TableIndexNum,
TypingData.TableIndex[ 0 ],
TypingData.TableIndex[ 1 ],
TypingData.TableIndex[ 2 ],
TypingData.TableIndex[ 3 ]
) ;
WaitKey() ;
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
|
Re: 複数の入力方式に対応させたい ( No.6 ) |
- 名前:サイゲン 日時:2019/01/27 04:30
管理人様
サンプルありがとうございます。
つまり、{"A",{"a"}}だとBase StringにあたるのがA、InputCharsにあたるのがa、という認識でよろしいでしょうか?
それで正誤判断するならば、例えば問題が時間ならばまず StringConvTables[TypeData.TableIndex[i]]のようにして一文字目を照合(時間だとz)して、その次にStringConvTables[TypeData.TableIndex[i]].InputChars[j]と
入力した文字を比較する感じでしょうか…?
いまいちソースが思いつかないです
|
Re: 複数の入力方式に対応させたい ( No.8 ) |
- 名前:管理人 日時:2019/01/27 23:19
> つまり、{"A",{"a"}}だとBase StringにあたるのがA、InputCharsにあたるのがa、という認識でよろしいでしょうか?
はい、その通りです
> それで正誤判断するならば、例えば問題が時間ならばまず StringConvTables[TypeData.TableIndex[i]]のようにして一文字目を照合(時間だとz)して、その次にStringConvTables[TypeData.TableIndex[i]].InputChars[j]と
> 入力した文字を比較する感じでしょうか…?
はい、そのような感じです
|
|