ページ 1 / 1
文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月22日(火) 15:23
by 雨粒
初投稿です。よろしくお願いします。
現在タイピングゲームを作っているのですが、中途半端な知識しかないため、序盤で詰まってしまいました。
現在:特定の文字列(haro-)を問題文として、キーボード入力した文字と1文字ずつ正誤を判定し、その結果を出力しようとしています。
下記のように作ったのですが、実行すると入力に関係なく一気に×××××○と出力されてしまいます。
また、キーボード入力でなくクリックしただけでも出力されます。
色々間違っているところがあると思いますが、アドバイスよろしくお願いします。
コード:
#include "DxLib.h"
#include <string>
int Cr;
void Judge (char Seikai[30], int n){
char SeikaiA;
int i;
char Nyuryoku;
char Nyuryoku_end[30];
for(i=0; i<=n; i++)
{
SeikaiA = Seikai[i];
Nyuryoku = GetInputChar(TRUE); //文字入力バッファから1文字取得
while(Nyuryoku != 0 && Nyuryoku>=CTRL_CODE_CMP);
{
if(SeikaiA == Nyuryoku)
{
DrawString(10*i,10, "○", Cr);
Nyuryoku_end[i] = Nyuryoku;
}
else DrawString(10*i, 10, "×", Cr);
continue;
}
}
Nyuryoku_end[n+1]='\0';
DrawString(300,300,Nyuryoku_end, Cr);
return;
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
int n;
char Nyuryoku;
char Seikai[30];
char Nyuryoku_end[30]= {};
ChangeWindowMode (TRUE);
SetFontSize( 20 ) ; //フォントサイズ指定
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
Cr = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
DrawString( 250 , 240 - 32 , "キーを押すとスタートします", Cr ); // トップメッセージ
strcpy(Seikai, "haro-");//Seikaiへ抽出
n = strlen(Seikai);//文字数取得
WaitKey() ; // キーの入力待ち
ClearDrawScreen() ;
ClearInputCharBuf() ;
DrawString( 240, 50 , Seikai, Cr); //出題する文字列を描画
//ESCキーまたはエラー発生で強制終了
while( !ProcessMessage() && ( CheckHitKey( KEY_INPUT_ESCAPE) == 0))
{
Judge(Seikai, n);
}
WaitKey();
//↓終了処理
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
環境は、Windows Vista, Visual Studio2008です。(他に必要な情報ありますでしょうか?)
ちなみに、今は文字列固定ですが、最終的には問題文を入れたファイルを作り、そこからランダムに抽出して出題させようと思っています。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月22日(火) 17:49
by ふりかけ
Judge関数内のwhile文で正解するまで入力させるんだと思うんですけど
入力を受け付けて無いのではないですか?
while文の直前で入力させているので、それをwhile文の中に入れてwhileをdo-while文に書き換えるといいと思います。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月22日(火) 18:11
by non
DXLIBは、自分で何かプログラムを作ってみたことがないので、間違っているかもしれませんが、
mainにあるwhile以外で繰り返し処理はしない方がいいのではないでしょうか?
例えば、どのような結果を得たいのかは知りませんが、こんな考え方ではいけませんか?
コード:
void Judge (char Seikai[], int n){
char SeikaiA;
static int i=0;
char Nyuryoku;
static char Nyuryoku_end[30];
Nyuryoku = GetInputChar(TRUE); //文字入力バッファから1文字取得
if(Nyuryoku != 0 && Nyuryoku>=CTRL_CODE_CMP)
{
Nyuryoku_end[i]=Nyuryoku;
if(Seikai[i] == Nyuryoku)
{
DrawString(10*i,10, "○", Cr);
i++;
}
else
DrawString(10*i, 10, "×", Cr);
Nyuryoku_end[i]='\0';
DrawString(300,300,Nyuryoku_end, Cr);
if(i==n){
i=0;
ClearDrawScreen() ;
}
}
}
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月25日(金) 17:43
by 雨粒
ふりかけ様>>
返信が遅くなってしまって申し訳ありません。アドバイスありがとうございます。
ふりかけ さんが書きました:Judge関数内のwhile文で正解するまで入力させるんだと思うんですけど
>その通りです。
アドバイスいただいた通りに直してみました。
Judge関数のみですが、長くなってしまうのでコードは下記に置きます。
私の勘違いでコードが違っていたら申し訳ないので一応確認をお願いします。
結果ですが、1文字目のみ○が表示されるようになりました。
それと、Escapeキーでウインドウを消せるようになりました。
ただ、問題文の出力と同時に×××××○と表示が出てしまうことと(これは最初のコードでも同じです)
(WinMain関数で出題前にキー入力を促す(キー指定なし)ことに問題があるのでしょうか。)
2文字目以降に進めないということもあり、まだおかしなところがあるようです。
ともあれ、アドバイスありがとうございました。よろしかったらまたお願いします。
コード:
void Judge (char Seikai[30], int n){
char SeikaiA;
int i;
char Nyuryoku;
char Nyuryoku_end[30];
for(i=0; i<=n; i++)
{
SeikaiA = Seikai[i];
do{ //変更しました
Nyuryoku = GetInputChar(TRUE); //文字入力バッファから1文字取得 //変更しました
if(SeikaiA == Nyuryoku)
{
DrawString(10*i,10, "○", Cr);
Nyuryoku_end[i] = Nyuryoku;
}
else DrawString(10*i, 10, "×", Cr);
continue;
}while(Nyuryoku != 0 && Nyuryoku>=CTRL_CODE_CMP); //変更しました
}
Nyuryoku_end[n+1]='\0';
DrawString(300,300,Nyuryoku_end, Cr);
return;
}
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月25日(金) 17:55
by beatle
そのプログラムだと確かに「1文字目のみ○が表示されるように」なってしまいますね。
なんでかというと、Seikai[0]と全ての入力文字を比較しているからです。
do-while文の条件文がどんなときに真になるか考えてみてください。
Seikaiのi番目を取ってくる処理と、入力文字列のi番目を取ってくる処理を同時にする必要があります。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月25日(金) 21:45
by ふりかけ
Dxライブラリ知らないので的外れかもしれませんが
GetInputChar関数は入力を待ってくれるものではないのではないでしょうか
一気に×××××○と表示されるということでdo-while文に問題がありそうです
リファレンスを確認するか、単純にgetchar関数を使ってみては?
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月25日(金) 22:37
by non
私の案は、全くのスルーでしたか。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月25日(金) 23:54
by ISLe
GetInputCharはバッファから入力を取り出しますが、ProcessMessageを呼び出さないとバッファの更新は行われないと思います。
つまりJudge関数に入ってしまうと続きのキー入力を受け付けなくなるということです。
ただしJudge関数にProcessMessageを呼び出すコードを追加しようなんて安易に考えてはいけませんよ。
GetInputCharが0を返したらバッファが空だということですからメインループに戻るようにします。
そうしておかないと今後ゲームとして完成させるにあたりキー入力判定以外の処理を追加するのが死ぬほど難しくなります。
Judge関数はGetInputCharが0以外を返すなら判定の続きを行うように組む必要があります。
nonさんが書かれたコードのようにしなければならないということです。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月28日(月) 16:11
by 雨粒
この間の返信からまた間が開いてしまいました、すいません。
全くの私情ですが今家のパソコンを修理に出しているため、大学の授業の合間に使うことしかできません。
また、前回の返信をしてすぐにPC室の利用できる時間が終わってしまい間が開いてしまいました。
本当に申し訳ないです。
non様>>
上に書いたとおり、私情ではありますが返信が遅くなってしまいました。
不快な思いをさせてしまって本当に申し訳ありません。
頂いたコードで実行したところ自分がやりたかった結果が得られました。
本当にありがとうございます!
無駄に色々繰り返し処理をさせてしまっていたのですね(汗
すごくシンプルなコードになって少し拍子抜けです(苦笑)
勉強になりました。本当にありがとうございました。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月28日(月) 16:50
by 雨粒
beatle様>>
返信が遅くなってしまって申し訳ありません。
なるほど、確かにこれではSeikaiAの中身が変わっていませんね・・・
一度アドバイス頂いて修正したときに単純作業で該当部分だけ変更してしまったのでこんなことに(汗)
修正を加えるにしても他への影響考えて対処していかなければならないですね。
勉強になりました。
指摘頂いたことを参考にして修正を加えてみましたがやはりエラーになってしまいました。
ISLe様に指摘頂いたようにGetInputCharの仕様を勘違いしていたようです。
non様に頂いたコードで自分の意図する動きが出来ましたので、すべての返信を終えて最終的なコードを残したらこのトピックは解決とさせていただこうと思います。
本当にありがとうございました。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月28日(月) 17:03
by 雨粒
ふりかけ様>>
2度目のアドバイスありがとうございます。
意図する通りに動かなかった原因は私がGetInputCharの仕様を勘違いしていたことにあったようです(苦笑)
non様に頂いたアドバイスで意図した結果が得られたのでこのトピックは解決とさせて頂こうと思います。
本当にありがとうございました。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月28日(月) 17:09
by 雨粒
ISLe様>>
アドバイスありがとうございます。
なるほど、GetInputCharの仕様を勘違いしていたということですね。
自分の使いたい仕様のところだけ見てしまってちゃんと確認ができていませんでした・・・。
勉強になりました。本当にありがとうございました。
Re: 文字の正誤判定(タイピングゲームを作っています)
Posted: 2011年11月28日(月) 17:36
by 雨粒
頂いたアドバイスで自分の意図していたコードを作ることができました。
このコメントの末尾に残してこのトピックを解決とさせていただこうと思います。
今回は私情があったとは言え返信に間が空いてしまって不快な思いをさせてしまい申し訳ありませんでした。
最初に書いておくべきだったと反省しています。
また、仕様を間違えていたり、修正を加えるとき単純に部分的に修正をするだけで全体を見直してみることも怠っているなど
自分の甘さも自覚しました・・・。
最初は投稿することに迷いがありましたが、いろいろ勉強になり、投稿して良かったと思っています。
進めていくうちにまたここに頼りに来ることがあるかと思います。よろしければまたアドバイスいただけたら嬉しいです。
では、拙いですがこれで終了とさせていただきます。
今回は本当にありがとうございました。
コード:
#include "DxLib.h"
#include <string>
int Cr;
void Judge (char Seikai[], int n){
char SeikaiA;
static int i=0;
char Nyuryoku;
static char Nyuryoku_end[30];
Nyuryoku = GetInputChar(TRUE); //文字入力バッファから1文字取得
if(Nyuryoku != 0 && Nyuryoku>=CTRL_CODE_CMP)
{
Nyuryoku_end[i]=Nyuryoku;
if(Seikai[i] == Nyuryoku)
{
DrawString(10*i,10, "○", Cr);
i++;
}
else
DrawString(10*i, 10, "×", Cr);
Nyuryoku_end[i]='\0';
DrawString(300,300,Nyuryoku_end, Cr);
if(i==n){
i=0;
DrawString(300,300,Nyuryoku_end,Cr);
DrawString(300,200,"正解です",Cr);
return;
}
}
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
int n;
char Nyuryoku;
char Seikai[30];
char Nyuryoku_end[30]= {};
ChangeWindowMode (TRUE);
SetFontSize( 20 ) ; //フォントサイズ指定
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
Cr = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
DrawString( 250 , 240 - 32 , "キーを押すとスタートします", Cr ); // トップメッセージ
strcpy(Seikai, "haro-");//Seikaiへ抽出
n = strlen(Seikai);//文字数取得
WaitKey() ; // キーの入力待ち
ClearDrawScreen() ;
ClearInputCharBuf() ;
DrawString( 240, 50 , Seikai, Cr); //出題する文字列を描画
//ESCキーまたはエラー発生で強制終了
while( !ProcessMessage() && ( CheckHitKey( KEY_INPUT_ESCAPE) == 0))
{
Judge(Seikai, n);
}
WaitKey();
//↓終了処理
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}