質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

6826閲覧

タイピングゲームの作成、乱数について

yowappu

総合スコア13

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/09/12 04:30

###前提・実現したいこと
Cでタイピングゲームのような物を作っているのですが、今のコードのままだとランダムに表示させた問題を正解したときに再度同じ問題が出てしまいます
既に使用した配列の中身を排除していく方法がわからず苦戦しています
どうすればいいでしょうか?

###発生している問題・エラーメッセージ
同じ問題が出てしまう

###該当のソースコード

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <time.h> 5 6int main() 7{ 8 //単語設定 9 char *word[] = {"banana","rinngo",......};//例です 10 char typing[256]; 11 12 int count; //ループ用変数 13 clock_t start,end; 14 15 srand((unsigned)time(NULL)); //乱数発生 16 17 for(count = 0; count < 10; count++){ //ループ処理 18 start = clock(); //時間計測スタート 19 20 int wordchange = rand () % 20; 21 22 while(*word != typing){ //比較処理 23 puts(*(word + wordchange)); 24 gets(typing); 25 26 if(strcmp(*(word + wordchange),typing) == 0){ 27 puts("\n\"right!\"\n"); //正解 28 break; 29 } 30 else{ 31 puts("\n\"Nooooo!!!!\"\n"); //不正解 32 } 33 } 34 } 35 end = clock(); //時間計測終了 36 printf("あなたは %d秒 でした。\n",end/CLOCKS_PER_SEC); //結果表示、CLOCKS_PER_SECで変換 37 38 39 40 return 0; 41}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

調べればやり方はいくつか出てくるのでしょうけど、考え方のひとつを紹介します。
まずword配列参照用の配列(idxとしておきます)を用意します。
word配列の要素数が20個なら同じく20個です。
初期値は、0~19です(idx[0]=0,idx[1]=1,...)
乱数の範囲は0~19で、最大値を1問ごとに減らしていきます。
word配列の参照は、idx配列を介して行います。
int wordchange = rand () % randmax;
word[idx[wordchange]]
1問終わるごとに、idx配列の対象要素を削除し後ろを詰めます。
例えば、乱数の結果、2だったとすると、idx配列を次のように組み直します。
idx[0]=0
idx[1]=1
idx[2]=3
idx[3]=4
...

それからstart = clock()はfor文の外に出さないと1問ごとの時間になってしまいますよ。

修正版コード

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <time.h> 5 6int main() 7{ 8 //単語設定 9 char *word[] = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"}; 10 char typing[256]; 11 clock_t start,end; 12 char idx[20]; 13 int i; 14 int randmax = 20; 15 int wordchange; 16 17 // idx配列の初期化 18 for(i = 0; i < 20; i++) idx[i] = i; 19 20 srand((unsigned)time(NULL)); //乱数発生 21 22 int count; //ループ用変数 23 24 //時間計測スタート 25 start = clock(); 26 for(count = 0; count < 10; count++){ //ループ処理 27 wordchange = rand () % randmax; 28 29 while(*word != typing){ //比較処理 30 puts(word[idx[wordchange]]); 31 gets(typing); 32 33 if(strcmp(word[idx[wordchange]],typing) == 0){ 34 puts("\n\"right!\"\n"); //正解 35 break; 36 } 37 else{ 38 puts("\n\"Nooooo!!!!\"\n"); //不正解 39 } 40 } 41 // idx配列を詰める 42 for(i = wordchange; i < 20; i++) idx[i] = idx[i + 1]; 43 randmax--; 44 } 45 end = clock(); //時間計測終了 46 printf("あなたは %d秒 でした。\n",end/CLOCKS_PER_SEC); //結果表示、CLOCKS_PER_SECで秒に変換 47 48 return 0; 49} 50 51

投稿2016/09/12 04:47

編集2016/09/12 06:25
ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yowappu

2016/09/12 05:37

素早い回答、ありがとうございます。 word配列参照用の配列を用意する、の部分なのですが }がついていませんとエラーメッセージが出てうまくいきません start = clock()の部分、ありがとうございます、さっそく直しました
ttyp03

2016/09/12 05:53

修正したコードを貼ってもらってもよいですか。
yowappu

2016/09/12 06:12

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main() { //単語設定 char *word[] = {"1","2"......}; char typing[256]; clock_t start,end; char idx[20]; idx[0]=0; idx[1]=1; idx[2]=2; idx[3]=3; idx[4]=4; idx[5]=5; idx[6]=6; idx[7]=7; idx[8]=8; idx[9]=9; idx[10]=10; idx[11]=11; idx[12]=12; idx[13]=13; idx[14]=14; idx[15]=15; idx[16]=16; idx[17]=17; idx[18]=18; idx[19]=19; srand((unsigned)time(NULL)); //乱数発生 int count; //ループ用変数 //時間計測スタート for(count = 0; count < 10; count++){ //ループ処理 start = clock(); int wordchange = rand () % RAND_MAX; while(*word != typing){ //比較処理 puts(word[idx[wordchange]]); gets(typing); if(strcmp(word[idx[wordchange]],typing) == 0){ puts("\n\"right!\"\n"); //正解 break; } else{ puts("\n\"Nooooo!!!!\"\n"); //不正解 } } } end = clock(); //時間計測終了 printf("あなたは %d秒 でした。\n",end/CLOCKS_PER_SEC); //結果表示、CLOCKS_PER_SECで秒に変換 return 0; } 修正をし、プログラム自体は動くようになったのですが、1問目を解いた後に強制終了するようになってしまいました。
ttyp03

2016/09/12 06:27

コードありがとうございます。 問題点を修正したコードを本文の方に貼っておきました。 参考にしてください。 直した箇所は以下です。 ・idx配列の初期化をループ化 ・RAND_MAXを変数化 ・変数wordchangeを関数先頭で宣言(ループの外で使うため) ・idx配列を詰める処理を追加 ・randmaxをデクリメントする処理を追加 ・計測スタートをループの外に移動
ttyp03

2016/09/12 06:29

それから先ほどのコードはとりあえず動く状態にしたので、本来なら20などハードコーディングせずに、マクロで定義したり、配列の要素数から求めるべきです。 今のコードの理解ができたら、そういったところも見直してみてください。
yowappu

2016/09/12 06:32

丁寧な回答たいへんありがとうございます 教えていただいたのにも関わらず配列を詰める処理などを考えていませんでした・・ 今回教えていただいたことを参考にしもっと勉強していきたいと思います。 ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問