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

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

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

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

Q&A

解決済

3回答

2911閲覧

人狼作成:乱数で同じ数が出ないようにする

shimi43

総合スコア7

C

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

0グッド

0クリップ

投稿2019/07/28 13:23

編集2019/07/28 13:25

前提・実現したいこと

人狼のシステムをC言語(C++などではなくただのC)で作りたい。

発生している問題・エラーメッセージ

役職決めでランダムな1~4の値をrandを使って各一回ずつ出したいのですが、srandを使うと同じ数が出てしまい、srandなしでは毎回同じ値になってしまいます。

該当のソースコード

c言語

1#include<stdio.h> 2#include<stdlib.h> 3#include<time.h> 4 5void Jinrou4(); 6void shuffle(); 7 8int main() 9{ 10 int n; 11 int role; 12 puts("プレイする人数を入力してください。(4~8)");       /*ここは無視してください*/ 13 scanf("%d",&n); 14 if(n==4) 15 { 16 Jinrou4(); 17 }else 18 { 19 puts("入力された値が正しくありません"); 20 21 } 22} 23 24void Jinrou4(int argc, char **argv) 25{ 26 int player; 27 puts("役職を決めます。"); 28 29 for ( int player = 0; player <= 3; player++) 30 { 31 32 printf("あなたはplayer%dです。\n",player+1); 33 puts("Enterを押してください。"); 34 int values[] = { 1, 2, 3, 4 }; 35 int size = sizeof(values) / sizeof(int); 36 shuffle(values, size); 37 if (values[player]==1) 38 { 39 puts("あなたは人狼です\n"); 40 41 }else if(values[player]==2||3) 42 { 43 puts("あなたは市民です\n"); 44 45 }else if(values[player]==4) 46 { 47 puts("あなたは占い師です\n"); 48 49 } 50 printf("確認したらENTERを押してください"); 51 if(getchar()=='\n'){ 52 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); 53 } 54 55 } 56} 57 58void shuffle(int array[], int size) 59{ 60 srand((unsigned) time(NULL)); 61 int i = size; 62 while (i > 1) { 63 int j = rand() % i; 64 i--; 65 int t = array[i]; 66 array[i] = array[j]; 67 array[j] = t; 68 } 69}

試したこと

ネットで調べ、Jinrou4の関数にsrandを入れるなどしてみましたが上手くいきませんでした。

補足情報(FW/ツールのバージョンなど)

vscodeとコマンドプロンプトを使っています。
初めての質問なので至らない点はご容赦ください。

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

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

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

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

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

guest

回答3

0

C

1 for ( int player = 0; player <= 3; player++) 2 // ... 3 int values[] = { 1, 2, 3, 4 }; 4 int size = sizeof(values) / sizeof(int); 5 shuffle(values, size);

これでは、player毎に、valueの値が書き換えられるので、重複する可能性が大きいです。

C

1 int values[] = { 1, 2, 3, 4 }; 2 int size = sizeof(values) / sizeof(int); 3 shuffle(values, size);

を for() の前に出しましょう。

投稿2019/07/28 14:07

pepperleaf

総合スコア6383

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

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

shimi43

2019/07/29 12:17

回答ありがとうございます! 修正させていただきました。
guest

0

ベストアンサー

srandは一旦置いておいて、次の部分が明らかにおかしいので修正してみて下さい。
ともすればこちらが真の問題かもしれません。

C

else if(values[player]==2||3)

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

C

1else if(values[player]==2 || values[player]==3)

また、srandはmain関数の先頭の方で一度だけ呼び出すのが無難です。

投稿2019/07/28 13:29

編集2019/07/28 13:30
LouiS0616

総合スコア35660

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

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

shimi43

2019/07/28 13:33

回答ありがとうございます 確かに明らかにおかしいですね… ありがとうございます!
shimi43

2019/07/28 13:45

ご指摘いただいた点を直しましたがやはり上手くいきませんでした。 srandを使ってしまうとやはり一度使った値を使わないことは難しいのでしょうか?
LouiS0616

2019/07/28 13:47

valuesの生成及びシャッフルを、ループに突入する前に済ませてしまって下さい。
shimi43

2019/07/28 13:52

返信ありがとうございます。 そのようにしたところうまく作動しました。 ありがとうございますm(_ _)m
LouiS0616

2019/07/28 13:57

解決したようで何よりです。 ところで、なぜシャッフルをループ前にしなければならなかったのか、理由はお分かりでしょうか。
guest

0

srandを複数回呼び出さないでください。

投稿2019/07/28 13:29

編集2019/07/28 13:30
yumetodo

総合スコア5850

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

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

shimi43

2019/07/28 13:33

main関数の最初で呼び出すことにしてみます 回答ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問