Create a gist now

Instantly share code, notes, and snippets.

初期Seedを計算
#include <iostream>
#include <iomanip>
using namespace std;
// 次の乱数を取得
uint32_t next(uint32_t s) {
return 0x41C64E6D * s + 0x00006073;
}
// 前の乱数を取得
// 注:
// S[n+1] = (0x41C64E6D * S[n] + 0x6073) % 0x100000000
// に対して
// S[n-1] = (0xEEB9EB65 * S[n] + 0x0A3561A1) % 0x100000000
// が成り立つことを利用
uint32_t prev(uint32_t s) {
return 0xEEB9EB65 * s + 0x0A3561A1;
}
// 実乱数を取得
uint16_t r(uint32_t s) {
return (uint16_t) (s >> 16);
}
// 800F~3000Fで実現可能な初期Seedであれば真
bool is_feasible_initial_seed(uint32_t s_0) {
int first_frame = 800;
int last_frame = 10000; // 約3分
// initial seed: 0xABCDEFGH
int min_AB = 1 * 1 + 0 + 10;
int max_AB = 12 * 31 + 59 + 59;
int min_CD = 0;
int max_CD = 23;
int min_EFGH = first_frame;
int max_EFGH = last_frame + 2099 - 2000;
int AB = s_0 >> 24;
int CD = (s_0 >> 16) % 0x100;
int EFGH = s_0 % 0x10000;
// 実現不可能な初期Seedを除外
if (
AB >= min_AB && AB <= max_AB
&& CD >= min_CD && CD <= max_CD
&& EFGH >= min_EFGH && EFGH <= max_EFGH
) {
return true;
}
return false;
}
void print_initial_seed_info(uint32_t s_n, int min_consumption) {
uint32_t s = s_n;
int n = 0;
// 最小消費数分だけ先に消費
for (int i = 0; i < min_consumption; i++) {
s = prev(s);
n++;
}
// 初期Seed候補の検索
while(true) {
s = prev(s);
n++;
// 実現可能な初期Seedがあれば情報を出力
if (is_feasible_initial_seed(s)) {
cout << setw(5) << dec << noshowbase << n;
cout << setw(12) << hex << uppercase << showbase << s_n;
cout << setw(12) << hex << uppercase << showbase << s << endl;
break;
}
}
}
int main(void) {
cout << setw(5) << "n";
cout << setw(12) << "S[n]";
cout << setw(12) << "S[0]" << endl;
int min_consumption = 3; // 徘徊ポケモンによる消費数分だけスキップ
print_initial_seed_info(0x97024D60, min_consumption);
print_initial_seed_info(0x015A9302, min_consumption);
print_initial_seed_info(0xD62B4730, min_consumption);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment