マイコンでゲームをプログラミングする場合、生成される乱数列が固定されてしまいます。つまり、常に同じ乱数でゲームをすることになり、記憶すれば攻略することができてしまいます。
random関数の動作を確認する
まず、random関数の動作確認をします。次のプログラムを実行します。
void setup() {
Serial.begin(115200);
delay(100);
for(int i=0;i<10;i++){
int r=random();
Serial.printf("%5d\n",r);
}
}
void loop() {
}
実行させると、右図のように乱数が表示されます。何度もリセットボタンを押して、再起動しても同じ乱数が表示されます。
EEPROMを使う
ゲームのプログラミングを行うときに、パソコンのように内部時計が動作していると、起動時の時間から乱数列の初期化を行うことができます。
しかし、マイコンで、WiFi機能があるとインターネットに接続することもできますが、一般的には割高になってしまいます。
初期化する方法として、EEPROMにプログラムが実行された回数を記憶しておき、その数値で乱数の初期化をすることができます。
#include "EEPROM.h"
int addr = 0;
#define EEPROM_SIZE 64
void setup() {
Serial.begin(115200);
EEPROM.begin(EEPROM_SIZE);
delay(100);
byte cnt=EEPROM.read(addr);
Serial.printf("cnt: %2d\n", cnt);
// 乱数の初期化
srand(cnt);
// EEPROMのカウントアップ
cnt++;
EEPROM.write(addr, cnt);
EEPROM.commit();
for(int i=0;i<10;i++){
int r=random();
Serial.printf("%5d\n",r);
}
}
void loop() {
}
プログラムでは、EEPROMから読み出し、プラス1してEEPROMに書き込み直します。読みだした数値で乱数の初期化を行い、その後、10個の乱数を発生、表示しています。
実行結果が右図です。
先頭でEEPROMの数値cntを表示後、10個の乱数を表示させた結果です。
cntの値が変わると、乱数列が変わっていることが確認できます。
EEPROMを使った乱数の初期化(アレンジ)
プログラムの起動回数cntを使った乱数の初期化ですが、起動回数が同じであれば、同じ乱数になってしまいます。
これを回避する一例として、ハイスコアを別のEEPROMのアドレスに記憶しておき、起動回数cntと組み合わせて、乱数の初期化を行うことや、スイッチの押された回数を記憶して、起動回数cntと組み合わせるなどのアレンジをすると、同じ起動回数でも乱数列を変えることができます。


0 件のコメント:
コメントを投稿