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

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

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

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

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

Q&A

4回答

2773閲覧

PICマイコンのC言語で重複しない乱数生成の方法をご教授願います。

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

0グッド

0クリップ

投稿2019/01/10 05:02

編集2019/01/10 05:04

PICでもぐらたたき風ゲームを作っているのですが、LED1~8まである中で、下記のプログラムだと乱数が重複して、同じLEDが2回3回連続して光ってしまうのですが、連続で同じLEDが光らないようにするにはどうすればいいでしょうか?

PIC C

1#include<16f887.h> 2#define RAND_MAX 7 3#include <stdlib.h> 4#use delay(clock=20000000) 5#fuses hs ,nowdt 6#byte porta=0x05 7#byte portb=0x06 8#byte portc=0x07 9#byte portd=0x08 10 11 12long ct,n,i,r; 13int _7seg(int data10) 14{ 15 int x,databcd,a1,b1,c1,d1,a2,b2,c2,d2; 16 databcd = data10+(data10/10)*6; 17 a1=(databcd&0x01)<<3; // 1桁 18 b1=(databcd&0x02)<<1; 19 c1=(databcd&0x04)>>1; 20 d1=(databcd&0x08)>>3; 21 22 a2=(databcd&0x10)<<3; // 2桁 23 b2=(databcd&0x20)<<1; 24 c2=(databcd&0x40)>>1; 25 d2=(databcd&0x80)>>3; 26 27 x=a1|b1|c1|d1|a2|b2|c2|d2; 28 return(x); 29 } 30 31int data; 32int const s[100] ={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 33 34void main(void) 35{ 36 37 int h; 38 39 40 set_tris_a(0); 41 set_tris_b(0xff); 42 set_tris_c(0); 43 set_tris_d(0); 44 PORTB=0; //カウンタ(7セグ) 45 PORTD=0; //LED 46 PORTC=0; //ボタン 47 ct=0; 48 n=0; 49 i=0; 50 h=0; 51 52 //t=0; 53 54 55while(1) 56{ 57 58 h = rand(); 59 i = s[h]; 60 portd=i; // モグラの頭 出る 61 62 63 while(ct<6000 ) // 入力を待ちながらボタン判定 64 { 65 if (portd == ~ portb ){ n++; // 押されたらカウント 66 portc=_7seg(n); 67 break; 68 } 69 ct++ ; 70 71 delay_us(1000); //光ってる時間 72 } 73 74 ct = 0; 75 76 portd=0; 77 delay_ms(1000); // シリンダー引っ込み待ち 78 79 // 次のモグラへ 80 81} 82 83} 84

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

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

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

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

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

guest

回答4

0

単純に連続しないようにするって話なら、
前回の値を覚えておいて、今回の乱数が同一値なら、再度乱数で選び直す、ってことをすればよろしい

投稿2019/01/10 05:22

y_waiwai

総合スコア87774

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

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

退会済みユーザー

退会済みユーザー

2019/01/11 01:35

下記のようにしてそのようにやってみたらカウントだけ進んでいき、LEDが点灯しませんでした。 while(1) { h = rand(); i = s[h]; if( i == ~z) portd=i; // LED点灯 else continue; ~ portd=0; i = z; delay_ms(500); // 待ち // 次のLEDへ }
y_waiwai

2019/01/11 01:43

> if( i == ~z) z ってなに?
退会済みユーザー

退会済みユーザー

2019/01/11 01:47

zは前回の値を記憶させた変数です
y_waiwai

2019/01/11 01:51

> i = s[h]; sというのも意味不明ですねー 各変数の内容をシリアルポートにでも出してPCで見れるようにしましょう。 コードだけを眺めて、あてずっぽでコード書いててもなんにもなりませんぜ
guest

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

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

0

簡単に対処するには、乱数の範囲を0~7ではなく0~6にしてはいかがでしょうか。
そして乱数を求めるたびに、乱数の位置の要素と末端の要素を入れ替える。
そうすることで前回の値が取得される事はなくなります。

c

1int const s[100] ={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 23int s[100] ={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //constを削除 4 56while(1) 7{ 8 h = rand(); 9 i = s[h]; 10 s[h] = s[RAND_MAX]; // 入れ替え処理 11 s[RAND_MAX] = i; // 入れ替え処理 12 portd=i; // モグラの頭 出る

但し、初回は一番右端は選ばれなくなってしまうのが問題…。
PICって使ったこと無いですが、乱数の範囲はRAND_MAXで決定するしかないのでしょうか?
通常の使い方ができるのなら、初回はrand()%8で、2回目以降はrand()%7するような作りにすれば対処できます。

投稿2019/01/10 05:31

ttyp03

総合スコア16998

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

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

退会済みユーザー

退会済みユーザー

2019/01/10 06:54

PICではRAND_MAXを使わないといけないらしいです… 上記で、エラー「Expecting a declaration」 クラスに直接処理を書いてはいけない、というエラーが起きてしまいました。
ttyp03

2019/01/10 06:58

RAND_MAX使わないといけないのですね。 であれば、初回は`rand()`、2回目以降は`rand()%7`でできるような気がします。 エラーについてはどこで出ているのでしょうか? constを外したらダメなんでしょうか?
退会済みユーザー

退会済みユーザー

2019/01/10 07:12

whileの閉じ括弧のところに出ているので、おそらくwhile文の中で入れ替え処理ができないのだと思われます。 初回をrand()、2回目をrand()%7の作りにするとしたらどのような形になりますか?
ttyp03

2019/01/10 07:14

入れ替え処理はたいしたことしていないので問題ないと思いますが。 何か入力ミスしていないでしょうか?セミコロンがないとか。
ttyp03

2019/01/10 07:20

>初回をrand()、2回目をrand()%7の作りにするとしたらどのような形になりますか? こんな感じでしょうか。 最初にループに入る前に求めて、ループ内では最後に乱数を求めるようにします。 h = rand(); while(1) { i = s[h]; s[h] = s[RAND_MAX]; // 入れ替え処理 s[RAND_MAX] = i; // 入れ替え処理 portd=i; // モグラの頭 出る ~ h = rand() % RAND_MAX; }
退会済みユーザー

退会済みユーザー

2019/01/11 00:06

打ち間違いはしてませんでした。 rand()とrand()%7の形にしたら Not enough RAM for all variables 全ての変数のRAMが足りないというエラーが起きました。 エラーの場所は同じくwhile文の閉じ括弧のところでした。
ttyp03

2019/01/11 00:38

メモリ不足?使えるメモリはそんなに少ないのでしょうか? とりあえずの対策としてs[100]をs[RAND_MAX+1]にしてみたらどうなりますか?
退会済みユーザー

退会済みユーザー

2019/01/11 01:45

今までのことを全て試してみたのですが、while文の中で入れ替え自体ができないみたいです…
ttyp03

2019/01/11 01:47

そんなことないと思いますが・・・。 s配列のconst外してますよね?
guest

0

乱数なので重複するのは当然です。
重複しないようにするのであれば、あらかじめ配列などに取りうる数字を入れておき、
配列のインデックスを乱数で決定していく、決定した要素は使わないようにする
といった処理をすれば良いかと。
もちろん、配列の内容をランダムに入れ替え、頭から取得するなどでも良いです。

投稿2019/01/10 05:14

t_obara

総合スコア5488

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問