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