[前へ]   [目次へ]   [次へ]

単語当てゲームLv2の改良(2)(C/C++)


今回は、「ヒント文字列の更新」機能の関数化を行っていきます。
まずは、前回終了時点のソースコードと関係図を再掲載します。
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
< 40>
< 41>
< 42>
< 43>
< 44>
< 45>
< 46>
< 47>
< 48>
< 49>
< 50>
< 51>
< 52>
< 53>
< 54>
< 55>
< 56>
< 57>
< 58>
< 59>
< 60>
< 61>
< 62>
< 63>
< 64>
< 65>
< 66>
< 67>
< 68>
< 69>
< 70>
< 71>
< 72>
< 73>
< 74>
< 75>
< 76>
< 77>
< 78>
< 79>
< 80>
< 81>
< 82>
< 83>
< 84>
< 85>
< 86>
< 87>
< 88>
< 89>
< 90>
< 91>
< 92>
< 93>
< 94>
< 95>
< 96>
< 97>
< 98>
< 99>
<100>
<101>
<102>
<103>
<104>
<105>
<106>
<107>
<108>
<109>
<110>
<111>
<112>
<113>
<114>
<115>
<116>
<117>
<118>
<119>
<120>
<121>
<122>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int SJISMultiCheck(unsigned char c){
   
if(((c>=0x81)&&(c<=0x9f))||((c>=0xe0)&&(c<=0xfc)))return 1;
   
else return 0;
}

int SelectQuestion(const char (*question)[2][64],size_t question_cnt,char *hint,size_t hint_cnt){
   
/********************************************
   乱数を使って問題を選択して表示する
   
   戻り値:0以上:選択された問題のID
           -1:失敗
   
   const char (*question)[2][64]:選択対象の問題セット。
   size_t question_cnt:questionの要素数
   char *hint:[出力]ヒント文字列を格納する領域
   size_t hint_cnt:hintの要素数
   ********************************************/
   
int i,sel_question;
   sel_question=rand()%question_cnt;
   
if(hint_cnt<=strlen(question[sel_question][1]))return -1;
   hint[0]=
'\0';
   puts(question[sel_question][0]);
   
for(i=0;question[sel_question][1][i]!='\0';){
      
if(SJISMultiCheck(question[sel_question][1][i])){
         strcat(hint,
"*");
         i+=2;
      }
      
else{
         strcat(hint,
"*");
         i++;
      }
   }
   
return sel_question;
}

int main(void){
   
//ソース上に直接書き込んだ問題
   
char question[10][2][64]={
      {
"「プログラム」を英語で書くと?","program"},
      {
"日本で一番高い山は?","富士山"},
      {
"3*5=","15"},
      {
"「library」をカタカナ読みすると?","ライブラリ"},
      {
"日本の都道府県の数は?","47"},
      {
"「檸檬」はなんて読む?","れもん"},
      {
"「万」の上の単位は?","億"},
      {
"「迎撃」はなんて読む?","げいげき"},
      {
"22+33*5=","187"},
      {
"「メモリ」を英語で書くと?","memory"}
   };
   
//選択された問題
   
int sel_question;
   
//入力された答え
   
char player_ans[80]="";
   
//ヒント文字列
   
char hint_str[80]="";
   
//ループカウンタ用一時変数
   
int i,j;
   
//正解文字列の長さ用一時変数
   
int ans_len;
   
//入力文字列の長さ用一時変数
   
int player_len;
   
   srand(time(NULL));
   
//機能「乱数を使って選択し表示します」
   
sel_question=SelectQuestion(question,10,hint_str,80);

   
while(1){
      
//機能「ヒント文字列の表示」
      
printf("ヒント:%s\n",hint_str);
      
      
//機能「その問題の答えをプレイヤーはキーボードから入力」
      
fgets(player_ans,79,stdin);
      
      
//機能「ヒント文字列の更新」
      
ans_len=strlen(question[sel_question][1]);
      player_len=strlen(player_ans);
      j=0;
      
for(i=0;(i<ans_len)&&(i<player_len);){
         
while(j<i){
            
if(SJISMultiCheck(question[sel_question][1][j]))j+=2;
            
else j++;
         }
         
if(i!=j){
            
if(SJISMultiCheck(player_ans[i]))i+=2;
            
else i++;
         }
         
else{
            
if(SJISMultiCheck(player_ans[i])){//日本語文字の場合
               
if((player_ans[i]==question[sel_question][1][i])&&
                  (player_ans[i+1]==question[sel_question][1][i+1])){
                  hint_str[i]=question[sel_question][1][i];
                  hint_str[i+1]=question[sel_question][1][i+1];
               }
               i+=2;
            }
            
else{//半角文字の場合
               
if(player_ans[i]==question[sel_question][1][i]){
                  hint_str[i]=question[sel_question][1][i];
               }
               i++;
            }
         }
      }
   
      
//機能「成否を判定します」
      
if(player_ans[0]!='\0')player_ans[strlen(player_ans)-1]='\0';
      
if(!strcmp(player_ans,question[sel_question][1]))break;
      puts(
"違います。もう一度入力してください。");
   }
   
   
//機能「クリア表示して終了」
   
puts("正解です。Enterを押すと終了します。");
   
   
//終了待ち
   
getchar();
   
return 0;

Lv2の関係図

さて、「ヒント文字列の更新」機能を関数化していきます。
この機能は文字通り「ヒント文字列」を更新するものなので、
関数名は HintUpdate としておきます。

? HintUpdate()

そしてこの機能がアクセスする要素は以下のようになっています。

●[入力]選択された問題
●[入力]入力された答え
●[入出力]ヒント文字列

まず、[入力]選択された問題 ですが、
これは問題セットから前回作成した SelectQuestion 関数が選択した問題ということになります。
なので単体の問題を受け取れるように const char[2][64] 型にします。
(注:引数型での配列指定は暗黙に該当する配列を渡せるポインタへ変形されることに注意します)

? HintUpdate(const char question[2][64])

続いて、[入力]入力された答え は、編集する必要もありませんし、
通常の文字列なので普通に const char* 型で受け取ります。

? HintUpdate(const char question[2][64],const char *player_ans)

最後に [入出力]ヒント文字列 ですが、これは条件に合わせて変更する文字列なので、
変更できるように char* 型で受け取ります。

? HintUpdate(const char question[2][64],const char *player_ans,char *hint_str)

今回は特に戻り値型に使うようなものが見つかりませんでした。
成功か失敗かを表す成否結果を返すようにしてもいいのですが、
今回はそこまでせず、戻り値なしということにします。

void HintUpdate(const char question[2][64],const char *player_ans,char *hint_str)

これで、新しく作る関数の仕様が完成しました。
続いて、中身を入れていきます。
まずは、今まで main 関数にあったコードを移動させてきます。

<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
void HintUpdate(const char question[2][64],const char *player_ans,char *hint_str){
   
/***********************************************
   ヒント文字列を入力された答えに合わせて更新する。
   
   const char question[2][64]:選択されている問題
   const char *player_ans:入力された答え
   char *hint_str:[入出力]更新するヒント文字列
   ***********************************************/
   
ans_len=strlen(question[sel_question][1]);
   player_len=strlen(player_ans);
   j=0;
   
for(i=0;(i<ans_len)&&(i<player_len);){
      
while(j<i){
         
if(SJISMultiCheck(question[sel_question][1][j]))j+=2;
         
else j++;
      }
      
if(i!=j){
         
if(SJISMultiCheck(player_ans[i]))i+=2;
         
else i++;
      }
      
else{
         
if(SJISMultiCheck(player_ans[i])){//日本語文字の場合
            
if((player_ans[i]==question[sel_question][1][i])&&
               (player_ans[i+1]==question[sel_question][1][i+1])){
               hint_str[i]=question[sel_question][1][i];
               hint_str[i+1]=question[sel_question][1][i+1];
            }
            i+=2;
         }
         
else{//半角文字の場合
            
if(player_ans[i]==question[sel_question][1][i]){
               hint_str[i]=question[sel_question][1][i];
            }
            i++;
         }
      }
   }

さて、前回同様このコードを関数として成り立つように修正していきます。
今回は引数名は同じなので、それ以外の変数を再定義します。

<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
void HintUpdate(const char question[2][64],const char *player_ans,char *hint_str){
   
/***********************************************
   ヒント文字列を入力された答えに合わせて更新する。
   
   const char question[2][64]:選択されている問題
   const char *player_ans:入力された答え
   char *hint_str:[入出力]更新するヒント文字列
   ***********************************************/
   
int i,j,ans_len,player_len;
   ans_len=strlen(question[sel_question][1]);
   player_len=strlen(player_ans);
   j=0;
   
for(i=0;(i<ans_len)&&(i<player_len);){
      
while(j<i){
         
if(SJISMultiCheck(question[sel_question][1][j]))j+=2;
         
else j++;
      }
      
if(i!=j){
         
if(SJISMultiCheck(player_ans[i]))i+=2;
         
else i++;
      }
      
else{
         
if(SJISMultiCheck(player_ans[i])){//日本語文字の場合
            
if((player_ans[i]==question[sel_question][1][i])&&
               (player_ans[i+1]==question[sel_question][1][i+1])){
               hint_str[i]=question[sel_question][1][i];
               hint_str[i+1]=question[sel_question][1][i+1];
            }
            i+=2;
         }
         
else{//半角文字の場合
            
if(player_ans[i]==question[sel_question][1][i]){
               hint_str[i]=question[sel_question][1][i];
            }
            i++;
         }
      }
   }

次に、 question ですが、問題の集合ではなく「選択した後の単体の問題」を引数として取ったので、
[sel_question] の部分が消えます。(この指定は main 関数で呼び出す時に行う形となります)

<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
void HintUpdate(const char question[2][64],const char *player_ans,char *hint_str){
   
/***********************************************
   ヒント文字列を入力された答えに合わせて更新する。
   
   const char question[2][64]:選択されている問題
   const char *player_ans:入力された答え
   char *hint_str:[入出力]更新するヒント文字列
   ***********************************************/
   
int i,j,ans_len,player_len;
   ans_len=strlen(question[1]);
   player_len=strlen(player_ans);
   j=0;
   
for(i=0;(i<ans_len)&&(i<player_len);){
      
while(j<i){
         
if(SJISMultiCheck(question[1][j]))j+=2;
         
else j++;
      }
      
if(i!=j){
         
if(SJISMultiCheck(player_ans[i]))i+=2;
         
else i++;
      }
      
else{
         
if(SJISMultiCheck(player_ans[i])){//日本語文字の場合
            
if((player_ans[i]==question[1][i])&&
               (player_ans[i+1]==question[1][i+1])){
               hint_str[i]=question[1][i];
               hint_str[i+1]=question[1][i+1];
            }
            i+=2;
         }
         
else{//半角文字の場合
            
if(player_ans[i]==question[1][i]){
               hint_str[i]=question[1][i];
            }
            i++;
         }
      }
   }

さて、これで機能は移植されましたが、 question[1] がたくさん出てきています。
これは正解文字列を表すので、 answer_str という名前のポインタを作ってそれを使ってみます。

<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
< 40>
< 41>
void HintUpdate(const char question[2][64],const char *player_ans,char *hint_str){
   
/***********************************************
   ヒント文字列を入力された答えに合わせて更新する。
   
   const char question[2][64]:選択されている問題
   const char *player_ans:入力された答え
   char *hint_str:[入出力]更新するヒント文字列
   ***********************************************/
   
int i,j,ans_len,player_len;
   
const char *answer_str;
   answer_str=question[1];
   ans_len=strlen(answer_str);
   player_len=strlen(player_ans);
   j=0;
   
for(i=0;(i<ans_len)&&(i<player_len);){
      
while(j<i){
         
if(SJISMultiCheck(answer_str[j]))j+=2;
         
else j++;
      }
      
if(i!=j){
         
if(SJISMultiCheck(player_ans[i]))i+=2;
         
else i++;
      }
      
else{
         
if(SJISMultiCheck(player_ans[i])){//日本語文字の場合
            
if((player_ans[i]==answer_str[i])&&
               (player_ans[i+1]==answer_str[i+1])){
               hint_str[i]=answer_str[i];
               hint_str[i+1]=answer_str[i+1];
            }
            i+=2;
         }
         
else{//半角文字の場合
            
if(player_ans[i]==answer_str[i]){
               hint_str[i]=answer_str[i];
            }
            i++;
         }
      }
   }

どうでしょうか。
question[1] を answer_str に置き換えただけですが、幾分読みやすくなったと思います。

ここまでの内容に加えて呼び出し元の変更も行った全ソースを以下に示します。

<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
< 40>
< 41>
< 42>
< 43>
< 44>
< 45>
< 46>
< 47>
< 48>
< 49>
< 50>
< 51>
< 52>
< 53>
< 54>
< 55>
< 56>
< 57>
< 58>
< 59>
< 60>
< 61>
< 62>
< 63>
< 64>
< 65>
< 66>
< 67>
< 68>
< 69>
< 70>
< 71>
< 72>
< 73>
< 74>
< 75>
< 76>
< 77>
< 78>
< 79>
< 80>
< 81>
< 82>
< 83>
< 84>
< 85>
< 86>
< 87>
< 88>
< 89>
< 90>
< 91>
< 92>
< 93>
< 94>
< 95>
< 96>
< 97>
< 98>
< 99>
<100>
<101>
<102>
<103>
<104>
<105>
<106>
<107>
<108>
<109>
<110>
<111>
<112>
<113>
<114>
<115>
<116>
<117>
<118>
<119>
<120>
<121>
<122>
<123>
<124>
<125>
<126>
<127>
<128>
<129>
<130>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int SJISMultiCheck(unsigned char c){
   
if(((c>=0x81)&&(c<=0x9f))||((c>=0xe0)&&(c<=0xfc)))return 1;
   
else return 0;
}

int SelectQuestion(const char (*question)[2][64],size_t question_cnt,char *hint,size_t hint_cnt){
   
/********************************************
   乱数を使って問題を選択して表示する
   
   戻り値:0以上:選択された問題のID
           -1:失敗
   
   const char (*question)[2][64]:選択対象の問題セット。
   size_t question_cnt:questionの要素数
   char *hint:[出力]ヒント文字列を格納する領域
   size_t hint_cnt:hintの要素数
   ********************************************/
   
int i,sel_question;
   sel_question=rand()%question_cnt;
   
if(hint_cnt<=strlen(question[sel_question][1]))return -1;
   hint[0]=
'\0';
   puts(question[sel_question][0]);
   
for(i=0;question[sel_question][1][i]!='\0';){
      
if(SJISMultiCheck(question[sel_question][1][i])){
         strcat(hint,
"*");
         i+=2;
      }
      
else{
         strcat(hint,
"*");
         i++;
      }
   }
   
return sel_question;
}

void HintUpdate(const char question[2][64],const char *player_ans,char *hint_str){
   
/***********************************************
   ヒント文字列を入力された答えに合わせて更新する。
   
   const char question[2][64]:選択されている問題
   const char *player_ans:入力された答え
   char *hint_str:[入出力]更新するヒント文字列
   ***********************************************/
   
int i,j,ans_len,player_len;
   
const char *answer_str;
   answer_str=question[1];
   ans_len=strlen(answer_str);
   player_len=strlen(player_ans);
   j=0;
   
for(i=0;(i<ans_len)&&(i<player_len);){
      
while(j<i){
         
if(SJISMultiCheck(answer_str[j]))j+=2;
         
else j++;
      }
      
if(i!=j){
         
if(SJISMultiCheck(player_ans[i]))i+=2;
         
else i++;
      }
      
else{
         
if(SJISMultiCheck(player_ans[i])){//日本語文字の場合
            
if((player_ans[i]==answer_str[i])&&
               (player_ans[i+1]==answer_str[i+1])){
               hint_str[i]=answer_str[i];
               hint_str[i+1]=answer_str[i+1];
            }
            i+=2;
         }
         
else{//半角文字の場合
            
if(player_ans[i]==answer_str[i]){
               hint_str[i]=answer_str[i];
            }
            i++;
         }
      }
   }
}

int main(void){
   
//ソース上に直接書き込んだ問題
   
char question[10][2][64]={
      {
"「プログラム」を英語で書くと?","program"},
      {
"日本で一番高い山は?","富士山"},
      {
"3*5=","15"},
      {
"「library」をカタカナ読みすると?","ライブラリ"},
      {
"日本の都道府県の数は?","47"},
      {
"「檸檬」はなんて読む?","れもん"},
      {
"「万」の上の単位は?","億"},
      {
"「迎撃」はなんて読む?","げいげき"},
      {
"22+33*5=","187"},
      {
"「メモリ」を英語で書くと?","memory"}
   };
   
//選択された問題
   
int sel_question;
   
//入力された答え
   
char player_ans[80]="";
   
//ヒント文字列
   
char hint_str[80]="";
   
   srand(time(NULL));
   
//機能「乱数を使って選択し表示します」
   
sel_question=SelectQuestion(question,10,hint_str,80);

   
while(1){
      
//機能「ヒント文字列の表示」
      
printf("ヒント:%s\n",hint_str);
      
      
//機能「その問題の答えをプレイヤーはキーボードから入力」
      
fgets(player_ans,79,stdin);
      
      
//機能「ヒント文字列の更新」
      
HintUpdate(question[sel_question],player_ans,hint_str);
   
      
//機能「成否を判定します」
      
if(player_ans[0]!='\0')player_ans[strlen(player_ans)-1]='\0';
      
if(!strcmp(player_ans,question[sel_question][1]))break;
      puts(
"違います。もう一度入力してください。");
   }
   
   
//機能「クリア表示して終了」
   
puts("正解です。Enterを押すと終了します。");
   
   
//終了待ち
   
getchar();
   
return 0;

これで main 関数の内容が93行から53行まで減少し、全体の形が分かりやすくなりました。
また、さりげなく main 関数で不要になった変数も消しておきました。

ところで、これまで何気にずっと放置していたことがあります。
それは player_ans に格納される改行文字のことです。

今は「成否を判定します」の機能で処理していますが、
「成否を判定します」機能では「入力された答え」に対しては「入力」であるので、
ここで改行文字を除去する処理をするのは関係図とは異なる挙動と言えます。

また、本来入力には改行文字はいらないので、
改行文字を除去する処理は本来、「その問題の答えをプレイヤーはキーボードから入力」機能で行うべきなのです。
ということで、改行文字を除去する処理を「その問題の答えをプレイヤーはキーボードから入力」機能に移動します。

<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
< 40>
< 41>
< 42>
< 43>
< 44>
< 45>
< 46>
< 47>
< 48>
< 49>
< 50>
< 51>
< 52>
< 53>
< 54>
< 55>
< 56>
< 57>
< 58>
< 59>
< 60>
< 61>
< 62>
< 63>
< 64>
< 65>
< 66>
< 67>
< 68>
< 69>
< 70>
< 71>
< 72>
< 73>
< 74>
< 75>
< 76>
< 77>
< 78>
< 79>
< 80>
< 81>
< 82>
< 83>
< 84>
< 85>
< 86>
< 87>
< 88>
< 89>
< 90>
< 91>
< 92>
< 93>
< 94>
< 95>
< 96>
< 97>
< 98>
< 99>
<100>
<101>
<102>
<103>
<104>
<105>
<106>
<107>
<108>
<109>
<110>
<111>
<112>
<113>
<114>
<115>
<116>
<117>
<118>
<119>
<120>
<121>
<122>
<123>
<124>
<125>
<126>
<127>
<128>
<129>
<130>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int SJISMultiCheck(unsigned char c){
   
if(((c>=0x81)&&(c<=0x9f))||((c>=0xe0)&&(c<=0xfc)))return 1;
   
else return 0;
}

int SelectQuestion(const char (*question)[2][64],size_t question_cnt,char *hint,size_t hint_cnt){
   
/********************************************
   乱数を使って問題を選択して表示する
   
   戻り値:0以上:選択された問題のID
           -1:失敗
   
   const char (*question)[2][64]:選択対象の問題セット。
   size_t question_cnt:questionの要素数
   char *hint:[出力]ヒント文字列を格納する領域
   size_t hint_cnt:hintの要素数
   ********************************************/
   
int i,sel_question;
   sel_question=rand()%question_cnt;
   
if(hint_cnt<=strlen(question[sel_question][1]))return -1;
   hint[0]=
'\0';
   puts(question[sel_question][0]);
   
for(i=0;question[sel_question][1][i]!='\0';){
      
if(SJISMultiCheck(question[sel_question][1][i])){
         strcat(hint,
"*");
         i+=2;
      }
      
else{
         strcat(hint,
"*");
         i++;
      }
   }
   
return sel_question;
}

void HintUpdate(const char question[2][64],const char *player_ans,char *hint_str){
   
/***********************************************
   ヒント文字列を入力された答えに合わせて更新する。
   
   const char question[2][64]:選択されている問題
   const char *player_ans:入力された答え
   char *hint_str:[入出力]更新するヒント文字列
   ***********************************************/
   
int i,j,ans_len,player_len;
   
const char *answer_str;
   answer_str=question[1];
   ans_len=strlen(answer_str);
   player_len=strlen(player_ans);
   j=0;
   
for(i=0;(i<ans_len)&&(i<player_len);){
      
while(j<i){
         
if(SJISMultiCheck(answer_str[j]))j+=2;
         
else j++;
      }
      
if(i!=j){
         
if(SJISMultiCheck(player_ans[i]))i+=2;
         
else i++;
      }
      
else{
         
if(SJISMultiCheck(player_ans[i])){//日本語文字の場合
            
if((player_ans[i]==answer_str[i])&&
               (player_ans[i+1]==answer_str[i+1])){
               hint_str[i]=answer_str[i];
               hint_str[i+1]=answer_str[i+1];
            }
            i+=2;
         }
         
else{//半角文字の場合
            
if(player_ans[i]==answer_str[i]){
               hint_str[i]=answer_str[i];
            }
            i++;
         }
      }
   }
}

int main(void){
   
//ソース上に直接書き込んだ問題
   
char question[10][2][64]={
      {
"「プログラム」を英語で書くと?","program"},
      {
"日本で一番高い山は?","富士山"},
      {
"3*5=","15"},
      {
"「library」をカタカナ読みすると?","ライブラリ"},
      {
"日本の都道府県の数は?","47"},
      {
"「檸檬」はなんて読む?","れもん"},
      {
"「万」の上の単位は?","億"},
      {
"「迎撃」はなんて読む?","げいげき"},
      {
"22+33*5=","187"},
      {
"「メモリ」を英語で書くと?","memory"}
   };
   
//選択された問題
   
int sel_question;
   
//入力された答え
   
char player_ans[80]="";
   
//ヒント文字列
   
char hint_str[80]="";
   
   srand(time(NULL));
   
//機能「乱数を使って選択し表示します」
   
sel_question=SelectQuestion(question,10,hint_str,80);

   
while(1){
      
//機能「ヒント文字列の表示」
      
printf("ヒント:%s\n",hint_str);
      
      
//機能「その問題の答えをプレイヤーはキーボードから入力」
      
fgets(player_ans,79,stdin);
      
if(player_ans[0]!='\0')player_ans[strlen(player_ans)-1]='\0';
      
      
//機能「ヒント文字列の更新」
      
HintUpdate(question[sel_question],player_ans,hint_str);
   
      
//機能「成否を判定します」
      
if(!strcmp(player_ans,question[sel_question][1]))break;
      puts(
"違います。もう一度入力してください。");
   }
   
   
//機能「クリア表示して終了」
   
puts("正解です。Enterを押すと終了します。");
   
   
//終了待ち
   
getchar();
   
return 0;

これで一応単語当てゲームLv2は完成ということにしたいと思います。
次回からはLv3編となり、ファイルからの読み込みについてやっていく予定です。

[前へ]   [目次へ]   [次へ]

プログラミング講座 総合目次

最終更新 2010/07/09