rand() 若不調用 srand(time(NULL)) 每次產生相同序列;即使播種,毫秒級重複調用仍產生相同值。遊戲洗牌、佈雷等場景需短時間內獲取大量不重複隨機數。
適用於固定集合(如54張牌)初始化:
int card[54];
for (int i=0; i<54; i++) card[i] = i; // 初始有序
for (int i=0; i<54; i++) {
int r = rand() % 54;
swap(card[i], card[r]);
}
一次播種,全局打亂,避免重複調用rand()。
10×12雷區,將(row,col)合為線性索引:
int area = 10*12;
for (int i=0; i
單次rand()解決雙坐標,減少調用次數。
利用用戶按鍵間隔時間採集種子,構建環形緩衝區:
#define RAND_SIZE 100
static int32_t pool[RAND_SIZE];
static int idx = 0;
void feed_entropy(int32_t val) {
pool[idx++] = val;
idx %= RAND_SIZE;
}
int32_t draw_random(int32_t max) {
if (max <= 0) return 0;
return pool[--idx < 0 ? RAND_SIZE-1 : idx] % max;
}
前提:需用戶交互產生熵。適用於有輸入設備的嵌入式/手持設備。
編譯期內嵌大質量隨機數表(如rand_table[20][20]或二進制資源文件),運行時:
優勢:無運行時rand()開銷,無熵源依賴,序列可重現(利於回放/測試),極短時間內產出大量「看起來隨機」的數。
| 場景 | 推薦方案 | 關鍵點 |
|---|---|---|
| 固定集合洗牌 | 方案一 | 一次播種+Fisher-Yates洗牌 |
| 網格隨機佈點 | 方案二 | 二維降一維+單次rand |
| 有用戶交互設備 | 方案三 | 按鍵採集熵+環形池 |
| 無交互/極速/可重現 | 方案四 | 預置表+遍歷策略 |
減少rand()調用頻率,用算法結構替代熵源頻率。隨機數質量不僅取決於生成器,更取決於如何使用。