• ベストアンサー

2回目以降の実行

くじ引きを行なうプログラムを考えています。 くじ箱には、特等(2枚)、1等(3枚)、2等(5枚)、3等(10枚)、4等(50枚)、 5等(80枚)、6等(150枚)が入っています。[合計300枚] 条件は、  (1)1度、引かれたくじは、箱の中に戻さない。  (2)一回実行したら、終了する。(1回の実行でくじを1度のみ引く。)  (3)くじの枚数は、構造体を使って管理する。 プログラムを下のように考えましたが、2回目以降に実行した場合ができません。 初期値を設定しているからなのですが、どうしたらよいのか分かりません。 2回目は、1回目に引いたくじを除いた299枚から選びたいのですが、 どう変えたらできるようになるのでしょうか?アドバイスお願いします。 #include<stdio.h> #include<stdlib.h> #include<time.h> struct kazu { int toku; int one; int two; int three; int four; int five; int six; }; main() { struct kazu k={2,3,5,10,50,80,150}; int S,a,i; srand(time(0)); /* 乱数の初期化 */ S=k.toku+k.one+k.two+k.three+k.four+k.five+k.six; a=rand()%S; /* 乱数発生 */ for(i=0;i<k.toku;i++) if(a==i){ printf("特等\n"); k.toku = k.toku-1; } for(i=k.toku;i<(k.toku+k.one);i++) if(a==i){ printf("1等\n"); k.one = k.one-1; } ・・・・・・・・・・省略・・・・・・・・・・・・・・ for(i=S-k.six;i<S;i++) if(a==i){ printf("6等\n"); k.six = k.six-1; } }

質問者が選んだベストアンサー

  • ベストアンサー
  • edomin
  • ベストアンサー率32% (327/1003)
回答No.1

「一回実行したら、終了する。」 プログラムを終了するのですか? 終了してしまったら、どのくじが引かれたか初期化されてしまいます。このままでは、毎回300枚のくじから始まってしまいます。 対策としては、くじを引いた結果をファイル等に書き出して再起動されたときにファイルを読みに行き、ファイルがなければ初期化、ファイルが有れば前回からの続きを構造体にセットすれば、希望どおりの結果になると思います・・・

noname#13767
質問者

お礼

ありがとうございます。ファイルに保存するように考えました。下のように加えたのですが、なんとなく汚いプログラムになってしまいました。もっと簡単にできないでしょうか? main() { struct kazu k; int S,a,i; FILE *fp; if((fp=fopen("kiroku.txt","r"))==NULL) { k.toku=2; k.one=3; k.two=5; k.three=10; k.four=50; k.five=80; k.six=150; printf("初回\n"); } else { fscanf(fp,"%d %d %d %d %d %d %d",&k.toku,&k.one,&k.two,&k.three,&k.four,&k.five,&k.six); } fclose(fp); srand(time(0)); /* 乱数の種の初期化 */ S=k.toku+k.one+k.two+k.three+k.four+k.five+k.six; a=rand()%S; /* 乱数発生 */ for(i=0;i<k.toku;i++) if(a==i) { printf("特等\n"); k.toku = k.toku-1; } ・・・・・省略・・・・・ for(i=S-k.six;i<S;i++) if(a==i) { printf("6等\n"); k.six = k.six-1; } /*ファイルへ書き込み*/ fp=fopen("kiroku.txt","w"); fprintf(fp,"%d %d %d %d %d %d %d",k.toku,k.one,k.two,k.three,k.four,k.five,k.six); fclose(fp); }

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • 12m24
  • ベストアンサー率23% (193/817)
回答No.2

 プログラムはお任せしますので、簡単なフローチャートを提案しておきます。 ○初期化 ↓ ●乱数 ↓ ●履歴にない? ↓ ●何等? ↓ ●表示 ↓ ●乱数の履歴の保存 ↓ ○(うんぬん)  上の流れのうち、黒丸で示した部分を「while(1)」などでずっとループさせ、ある条件が整ったときに「break」でループを抜け出すと良いと思います。こうすることで、見かけ上は何回でも抽選することが出来ます。  「if」文では、条件判断をしたらそのまま下にプログラムがいってしまうので、「while」「do~while」でプログラムを何回も同じところを通るようにするのがポイントです。  ちなみに、「while(1)」の使い方に注意しないと、いつまでたってもループから抜け出せなくなることがあります。お気を付けを。

noname#13767
質問者

お礼

アドバイスありがとうございます。 説明不足だったかもしれません。一回の実行で、一回だけ抽選されるプログラムを作っています。 再起動で、続きから2回目の抽選を行ないます。 再起動した時、初期化されないようにどうしたら良いか悩んでいました。 初心者なので、勉強になりました。

すると、全ての回答が全文表示されます。

関連するQ&A