Commit 81b781d9 authored by salix5's avatar salix5 Committed by GitHub

update RNG and uniform distribution, part 2 (#2363)

Old version:
pheader.flag does not contain REPLAY_UNIFORM
RNG: mt19937
distribution: almost-uniform

New version
pheader.flag contains REPLAY_UNIFORM
RNG: mt19937
distribution: uniform

* add bounds checking

* update RNG in replay mode

* replace mtrandom with mt19937

* replace mtrandom with mt19937

* replace mtrandom with mt19937
parent 1c829da0
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#ifdef _WIN32 #ifdef _WIN32
#include <WinSock2.h> #include <WinSock2.h>
#define NOMINMAX
#include <windows.h> #include <windows.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
......
...@@ -79,6 +79,7 @@ void DeckBuilder::Initialize() { ...@@ -79,6 +79,7 @@ void DeckBuilder::Initialize() {
mainGame->btnSideReload->setVisible(false); mainGame->btnSideReload->setVisible(false);
filterList = &deckManager._lfList[mainGame->gameConf.use_lflist ? mainGame->gameConf.default_lflist : deckManager._lfList.size() - 1].content; filterList = &deckManager._lfList[mainGame->gameConf.use_lflist ? mainGame->gameConf.default_lflist : deckManager._lfList.size() - 1].content;
ClearSearch(); ClearSearch();
rnd.reset((unsigned int)time(nullptr));
mouse_pos.set(0, 0); mouse_pos.set(0, 0);
hovered_code = 0; hovered_code = 0;
hovered_pos = 0; hovered_pos = 0;
...@@ -167,7 +168,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -167,7 +168,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break; break;
} }
case BUTTON_SHUFFLE_DECK: { case BUTTON_SHUFFLE_DECK: {
std::random_shuffle(deckManager.current_deck.main.begin(), deckManager.current_deck.main.end()); rnd.shuffle_vector(deckManager.current_deck.main);
break; break;
} }
case BUTTON_SAVE_DECK: { case BUTTON_SAVE_DECK: {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "client_card.h" #include "client_card.h"
#include "../ocgcore/mtrandom.h"
namespace ygo { namespace ygo {
...@@ -76,6 +77,7 @@ public: ...@@ -76,6 +77,7 @@ public:
int prev_sel; int prev_sel;
bool is_modified; bool is_modified;
bool readonly; bool readonly;
mt19937 rnd;
const std::unordered_map<int, int>* filterList; const std::unordered_map<int, int>* filterList;
std::vector<code_pointer> results; std::vector<code_pointer> results;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#ifdef _WIN32 #ifdef _WIN32
#define NOMINMAX
#include <Windows.h> #include <Windows.h>
class FileSystem { class FileSystem {
......
...@@ -396,7 +396,6 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -396,7 +396,6 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
return; return;
duel_stage = DUEL_STAGE_DUELING; duel_stage = DUEL_STAGE_DUELING;
bool swapped = false; bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0]; pplayer[0] = players[0];
pplayer[1] = players[1]; pplayer[1] = players[1];
if((tp && dp->type == 1) || (!tp && dp->type == 0)) { if((tp && dp->type == 1) || (!tp && dp->type == 0)) {
...@@ -411,34 +410,30 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -411,34 +410,30 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
swapped = true; swapped = true;
} }
dp->state = CTOS_RESPONSE; dp->state = CTOS_RESPONSE;
std::random_device rd;
unsigned int seed = rd();
mt19937 rnd(seed);
unsigned int duel_seed = rnd.rand();
ReplayHeader rh; ReplayHeader rh;
rh.id = 0x31707279; rh.id = 0x31707279;
rh.version = PRO_VERSION; rh.version = PRO_VERSION;
rh.flag = 0; rh.flag = REPLAY_UNIFORM;
time_t seed = time(0);
rh.seed = seed; rh.seed = seed;
rh.start_time = (unsigned int)time(nullptr);
last_replay.BeginRecord(); last_replay.BeginRecord();
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
rnd.reset(seed);
last_replay.WriteData(players[0]->name, 40, false); last_replay.WriteData(players[0]->name, 40, false);
last_replay.WriteData(players[1]->name, 40, false); last_replay.WriteData(players[1]->name, 40, false);
if(!host_info.no_shuffle_deck) { if(!host_info.no_shuffle_deck) {
for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) { rnd.shuffle_vector(pdeck[0].main);
int swap = rnd.real() * (i + 1); rnd.shuffle_vector(pdeck[1].main);
std::swap(pdeck[0].main[i], pdeck[0].main[swap]);
}
for(size_t i = pdeck[1].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
std::swap(pdeck[1].main[i], pdeck[1].main[swap]);
}
} }
time_limit[0] = host_info.time_limit; time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit; time_limit[1] = host_info.time_limit;
set_script_reader((script_reader)DataManager::ScriptReaderEx); set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader); set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)SingleDuel::MessageHandler); set_message_handler((message_handler)SingleDuel::MessageHandler);
rnd.reset(seed); pduel = create_duel(duel_seed);
pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count); set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count); set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
int opt = (int)host_info.duel_rule << 16; int opt = (int)host_info.duel_rule << 16;
......
...@@ -33,9 +33,9 @@ int SingleMode::SinglePlayThread() { ...@@ -33,9 +33,9 @@ int SingleMode::SinglePlayThread() {
const int start_hand = 5; const int start_hand = 5;
const int draw_count = 1; const int draw_count = 1;
const int opt = 0; const int opt = 0;
mtrandom rnd; std::random_device rd;
time_t seed = time(0); unsigned int seed = rd();
rnd.reset(seed); mt19937 rnd(seed);
set_script_reader((script_reader)DataManager::ScriptReaderEx); set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader); set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler); set_message_handler((message_handler)MessageHandler);
...@@ -77,8 +77,9 @@ int SingleMode::SinglePlayThread() { ...@@ -77,8 +77,9 @@ int SingleMode::SinglePlayThread() {
ReplayHeader rh; ReplayHeader rh;
rh.id = 0x31707279; rh.id = 0x31707279;
rh.version = PRO_VERSION; rh.version = PRO_VERSION;
rh.flag = REPLAY_SINGLE_MODE; rh.flag = REPLAY_UNIFORM | REPLAY_SINGLE_MODE;
rh.seed = seed; rh.seed = seed;
rh.start_time = (unsigned int)time(nullptr);
mainGame->gMutex.lock(); mainGame->gMutex.lock();
mainGame->HideElement(mainGame->wSinglePlay); mainGame->HideElement(mainGame->wSinglePlay);
mainGame->ClearCardInfo(); mainGame->ClearCardInfo();
......
...@@ -356,7 +356,6 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -356,7 +356,6 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
return; return;
duel_stage = DUEL_STAGE_DUELING; duel_stage = DUEL_STAGE_DUELING;
bool swapped = false; bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0]; pplayer[0] = players[0];
pplayer[1] = players[1]; pplayer[1] = players[1];
pplayer[2] = players[2]; pplayer[2] = players[2];
...@@ -376,44 +375,34 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) { ...@@ -376,44 +375,34 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
cur_player[0] = players[0]; cur_player[0] = players[0];
cur_player[1] = players[3]; cur_player[1] = players[3];
dp->state = CTOS_RESPONSE; dp->state = CTOS_RESPONSE;
std::random_device rd;
unsigned int seed = rd();
mt19937 rnd(seed);
unsigned int duel_seed = rnd.rand();
ReplayHeader rh; ReplayHeader rh;
rh.id = 0x31707279; rh.id = 0x31707279;
rh.version = PRO_VERSION; rh.version = PRO_VERSION;
rh.flag = REPLAY_TAG; rh.flag = REPLAY_UNIFORM | REPLAY_TAG;
time_t seed = time(0);
rh.seed = seed; rh.seed = seed;
rh.start_time = (unsigned int)time(nullptr);
last_replay.BeginRecord(); last_replay.BeginRecord();
last_replay.WriteHeader(rh); last_replay.WriteHeader(rh);
rnd.reset(seed);
last_replay.WriteData(players[0]->name, 40, false); last_replay.WriteData(players[0]->name, 40, false);
last_replay.WriteData(players[1]->name, 40, false); last_replay.WriteData(players[1]->name, 40, false);
last_replay.WriteData(players[2]->name, 40, false); last_replay.WriteData(players[2]->name, 40, false);
last_replay.WriteData(players[3]->name, 40, false); last_replay.WriteData(players[3]->name, 40, false);
if(!host_info.no_shuffle_deck) { if(!host_info.no_shuffle_deck) {
for(size_t i = pdeck[0].main.size() - 1; i > 0; --i) { rnd.shuffle_vector(pdeck[0].main);
int swap = rnd.real() * (i + 1); rnd.shuffle_vector(pdeck[1].main);
std::swap(pdeck[0].main[i], pdeck[0].main[swap]); rnd.shuffle_vector(pdeck[2].main);
} rnd.shuffle_vector(pdeck[3].main);
for(size_t i = pdeck[1].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
std::swap(pdeck[1].main[i], pdeck[1].main[swap]);
}
for(size_t i = pdeck[2].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
std::swap(pdeck[2].main[i], pdeck[2].main[swap]);
}
for(size_t i = pdeck[3].main.size() - 1; i > 0; --i) {
int swap = rnd.real() * (i + 1);
std::swap(pdeck[3].main[i], pdeck[3].main[swap]);
}
} }
time_limit[0] = host_info.time_limit; time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit; time_limit[1] = host_info.time_limit;
set_script_reader((script_reader)DataManager::ScriptReaderEx); set_script_reader((script_reader)DataManager::ScriptReaderEx);
set_card_reader((card_reader)DataManager::CardReader); set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)TagDuel::MessageHandler); set_message_handler((message_handler)TagDuel::MessageHandler);
rnd.reset(seed); pduel = create_duel(duel_seed);
pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count); set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count); set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
int opt = (int)host_info.duel_rule << 16; int opt = (int)host_info.duel_rule << 16;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment