Last active
December 29, 2016 11:55
-
-
Save mizdra/b7b43daa143648ac6ed086e103282f18 to your computer and use it in GitHub Desktop.
初期Seedを計算
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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