乱数が同じ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Lawliet

乱数が同じ

#1

投稿記事 by Lawliet » 6年前

ヒットアンドブローのゲームを制作しています。
そこで正解の数字を乱数で生成しようと思ったのですが、
何度実行しても、数値が8469で変わりません
とりあえずすべてのコードを載せます。

いろいろ突っ込むところがあるかもしれませんがよろしくお願いします。

コード:

/*
	ヒットアンドブロー
*/
#define LONG 4 //桁数

#include <stdio.h>
#include<stdlib.h>

typedef struct {
	int hit;
	int blow;
} hitandblow;

void print_rule(void)
{
	printf("ヒットアンドブローのルール(製作中)\n");
}

int check_number(int n)
{
	int temp[LONG];
	int waru, del;
	int loopFLAG = 1;
	int i, j;

	//3桁以上かどうかの判断
	if( n >= 123){
		if(n >= 1023){//1023->4桁で最小の数
	
			//nを配列に格納
			for(i = 0, waru = 10, del = 1; i < LONG; i++, waru *= 10, del *= 10){
				temp[i] = (n % waru) / del;
			}
		}
		else{//3桁の場合の判断
			//nを文字列に格納
			for(i = 0, waru = 10, del = 1; i < (LONG - 1); i++, waru *= 10, del *= 10){
				temp[i] = (n % waru) / del;
			}
			temp[i] = 0;
		}
			//比較
		for(i = 0; i < LONG; i++){
			for(j = 1; j < LONG; j++){
				if((i != j) && (temp[i] == temp[j]))
					loopFLAG = 0;//loopFLAGを'偽'に
			}
		
			if(loopFLAG == 0)
				break;
		}
	
		return ( loopFLAG );
	}
	else{
		return 0;
	}
}

hitandblow check_hit_blow(int n1, int n2)
{
	hitandblow re = {0, 0};
	int waru, del;
	int i, j;
	int n1_ch[LONG], n2_ch[LONG];

	//===============================
	//文字列に格納
	//===============================

	//n1
	for(i = 0, waru = 10, del = 1; i < LONG; i++, waru *= 10, del *= 10){
		n1_ch[i] = (n1 % waru) / del;
	}
	//n2
	for(i = 0, waru = 10, del = 1; i < LONG; i++, waru *= 10, del *= 10){
		n2_ch[i] = (n2 % waru) / del;
	}
	//===============================
	//===============================

	//===============================
	//比較
	//===============================

	for(i = 0; i < LONG; i++){
		for(j = 0; j < LONG; j++){

			if(n1_ch[i] == n2_ch[j]){
				if(i == j){
					re.hit++;
				}
				else{
					re.blow++;
				}
			}

		}
	}

	return re;
}

int main(void)
{
	int answer;	//解答
	int right;	//正解
	hitandblow temp = {0, 0};
	unsigned count;

	printf( "===================================\n"
			"####################\n"
			"#ヒットアンドブロー#\n"
			"####################\n"
			"\n");
	print_rule();
	printf(	"===================================\n");


	do{
		//ここの9999をあとでLONGを使って再現する
		right = ((rand() % 9999) + 1);
	}while(check_number(right) == 0);
	//rightがcheck_numberを通ったら抜ける

	printf("正解は%dです\n",right);

	for(count = 1; temp.hit != LONG; count++){
		printf( "---------------\n"
				"第%d回戦\n"
				"---------------\n"
				"\n", count);

		//数字の入力
		do{
			printf("4桁の数を入力してください:");
			scanf("%d", &answer);
			
			if( !( (answer >= 123) && (answer <= 9999) )){
				//123->"0123"で4桁の最小数
				printf("\a警告:4桁で入力してください\n");
			}
			
			if( check_number(answer) == 0 ){
				printf("\a警告:全桁とも異なる数で入力してください\n");
			}


		}while( (check_number(answer) == 0) || !((answer >= 123) && (answer <= 9999)));


		//比較
		temp = check_hit_blow(right, answer);

		//結果
		printf("%dHIT %dBLOW\n", temp.hit, temp.blow);

	}

	printf( "===========\n"
			"= -正 解- =\n"
			"===========\n");

	return 0;
}

nil
記事: 428
登録日時: 8年前

Re: 乱数が同じ

#2

投稿記事 by nil » 6年前

標準関数のrandは擬似乱数です。
なので乱数の種を設定しなければなりません。
srandで検索をするといいと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: 乱数が同じ

#3

投稿記事 by softya(ソフト屋) » 6年前

乱数の種を時間などで初期化しないと、数学的な乱数はいつも同じ数値なります。これはコンピュータだと避けれない宿命です。
「srand」 と言うことで srand((unsigned) time(NULL));で初期化しています。
http://www9.plala.or.jp/sgwr-t/lib/srand.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Lawliet

Re: 乱数が同じ

#4

投稿記事 by Lawliet » 6年前

ありがとうございました。

しかし、私はこの前じゃんけんゲームを作り、
相手の手を乱数によって表したのですがその時は
グー、パー、チョキなどいろいろな値が出ましたがなぜ今回に限りこういうことが起こったのでしょうか?
(もちろんsrand()なんて使っていません)

アバター
みけCAT
記事: 6252
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 乱数が同じ

#5

投稿記事 by みけCAT » 6年前

ぱっと思いつくのは
  • JavaScriptやDXライブラリなどの自動で乱数が初期化される言語/処理系を使用している
  • xorshiftやメルセンヌツイスタなどを使用しているので、srandを使わなくても乱数を初期化できる
  • アクセス違反などでメモリが破壊され、値が書き変わっている
などでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: 乱数が同じ

#6

投稿記事 by softya(ソフト屋) » 6年前

この前のはsrandを私が確認し忘れたので、起動直後からの手は毎回同じ手が必ず出ていませんか? 確認してみてください。
rand()を呼び出す度に次の新しい乱数に切り替わりますが、種が同じ場合は毎回同じ乱数の並びになります。
種→乱数1回め→乱数2回め→ と変化していきます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Lawliet

Re: 乱数が同じ

#7

投稿記事 by Lawliet » 6年前

softya(ソフト屋) さんが書きました:この前のはsrandを私が確認し忘れたので、起動直後からの手は毎回同じ手が必ず出ていませんか? 確認してみてください。
rand()を呼び出す度に次の新しい乱数に切り替わりますが、種が同じ場合は毎回同じ乱数の並びになります。
種→乱数1回め→乱数2回め→ と変化していきます。
本当でした。
ありがとうございました。スッキリしました

閉鎖

“C言語何でも質問掲示板” へ戻る