Skip to content

Commit 1b46ea2

Browse files
committed
Use normal distribution for randomization
1 parent 79d52e1 commit 1b46ea2

File tree

5 files changed

+44
-21
lines changed

5 files changed

+44
-21
lines changed

app/app.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ int main(int, char **) {
6464

6565
set_priority_class(HIGH_PRIORITY_CLASS);
6666

67-
maniac::randomize(hit_objects, maniac::config.randomization_range);
67+
maniac::randomize(hit_objects, maniac::config.randomization_mean, maniac::config.randomization_stddev);
6868

6969
if (maniac::config.humanization_type == maniac::config::STATIC_HUMANIZATION) {
7070
maniac::humanize_static(hit_objects, maniac::config.humanization_modifier);
@@ -113,10 +113,10 @@ int main(int, char **) {
113113
ImGui::SameLine();
114114
help_marker("Advanced hit-time randomization based on hit density.");
115115

116-
ImGui::DragIntRange2("Randomization", &maniac::config.randomization_range.first,
117-
&maniac::config.randomization_range.second);
116+
ImGui::InputInt("Randomization Mean", &maniac::config.randomization_mean);
117+
ImGui::InputInt("Randomization Stddev", &maniac::config.randomization_stddev);
118118
ImGui::SameLine();
119-
help_marker("Adds a random hit-time offset between the first and last value, in milliseconds.");
119+
help_marker("Adds a random hit-time offset generated using a normal distribution with given mean and standard deviation.");
120120

121121
ImGui::InputInt("Compensation", &maniac::config.compensation_offset);
122122
ImGui::SameLine();

app/window.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ void window::start(const std::function<void()> &body) {
9595
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL,
9696
NULL, NULL, NULL, _T("maniac"), NULL};
9797
::RegisterClassEx(&wc);
98-
HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("maniac"), WS_OVERLAPPEDWINDOW, 100, 100, 500,
99-
300, NULL, NULL, wc.hInstance, NULL);
98+
HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("maniac"), WS_OVERLAPPEDWINDOW, 100, 100, 550,
99+
350, NULL, NULL, wc.hInstance, NULL);
100100

101101
// Initialize Direct3D
102102
if (!CreateDeviceD3D(hwnd)) {

lib/humanization.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
#include <maniac/common.h>
22
#include <maniac/maniac.h>
33

4-
void maniac::randomize(std::vector<osu::HitObject> &hit_objects, std::pair<int, int> range) {
5-
if (!range.first && !range.second)
6-
return;
4+
void maniac::randomize(std::vector<osu::HitObject> &hit_objects, int mean, int stddev) {
5+
if (stddev <= 0) {
6+
return;
7+
}
78

89
std::random_device rd;
9-
std::mt19937 gen(rd());
10+
std::mt19937 gen{rd()};
1011

11-
std::uniform_int_distribution<> distr(range.first, range.second);
12+
std::normal_distribution<> distr{static_cast<double>(mean), static_cast<double>(stddev)};
1213

1314
for (auto &hit_object : hit_objects) {
1415
// if it's a slider we want to randomize start and end, if it's not we ignore end anyway
15-
hit_object.start_time += distr(gen);
16-
hit_object.end_time += distr(gen);
16+
hit_object.start_time += std::round(distr(gen));
17+
hit_object.end_time += std::round(distr(gen));
1718
}
1819

19-
debug("randomized %d hit objects with a range of [%d, %d]", hit_objects.size(), range.first,
20-
range.second);
20+
debug("randomized %d hit objects with offsets along a normal distribution with mean %d and stddev %d",
21+
hit_objects.size(), mean, stddev);
2122
}
2223

2324
void maniac::humanize_static(std::vector<osu::HitObject> &hit_objects, int modifier) {
@@ -65,6 +66,11 @@ void maniac::humanize_dynamic(std::vector<osu::HitObject> &hit_objects, int modi
6566

6667
constexpr auto max_delta = 1000;
6768

69+
std::random_device rd;
70+
std::mt19937 gen(rd());
71+
72+
std::uniform_int_distribution<> distr(0, 1);
73+
6874
for (int i = 0; i < hit_objects.size(); i++) {
6975
auto &cur = hit_objects.at(i);
7076

lib/include/maniac/config.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77

88
namespace maniac {
99
struct config {
10+
static constexpr int VERSION = 2;
11+
1012
static constexpr auto STATIC_HUMANIZATION = 0;
1113
static constexpr auto DYNAMIC_HUMANIZATION = 1;
1214

1315
int tap_time = 20;
1416
bool mirror_mod = false;
1517
int compensation_offset = -15;
1618
int humanization_modifier = 0;
17-
std::pair<int, int> randomization_range = { 0, 0 };
19+
int randomization_mean = 0;
20+
int randomization_stddev = 0;
1821
int humanization_type = DYNAMIC_HUMANIZATION;
1922

2023
// TODO: This isn't configurable yet, use a non-shit config format
@@ -31,12 +34,23 @@ namespace maniac {
3134
return;
3235
}
3336

37+
int version = -1;
38+
39+
file.read(reinterpret_cast<char *>(&version), sizeof version);
40+
41+
if (version != VERSION) {
42+
// TODO: Use a non-shit config format
43+
debug("config has outdated version, ignoring");
44+
45+
return;
46+
}
47+
3448
file.read(reinterpret_cast<char *>(&tap_time), sizeof tap_time);
3549
file.read(reinterpret_cast<char *>(&mirror_mod), sizeof mirror_mod);
3650
file.read(reinterpret_cast<char *>(&compensation_offset), sizeof compensation_offset);
3751
file.read(reinterpret_cast<char *>(&humanization_modifier), sizeof humanization_modifier);
38-
file.read(reinterpret_cast<char *>(&randomization_range.first), sizeof randomization_range.first);
39-
file.read(reinterpret_cast<char *>(&randomization_range.second), sizeof randomization_range.second);
52+
file.read(reinterpret_cast<char *>(&randomization_mean), sizeof randomization_mean);
53+
file.read(reinterpret_cast<char *>(&randomization_stddev), sizeof randomization_stddev);
4054
file.read(reinterpret_cast<char *>(&humanization_type), sizeof humanization_type);
4155

4256
debug("loaded config from file");
@@ -51,12 +65,15 @@ namespace maniac {
5165
return;
5266
}
5367

68+
int version = VERSION;
69+
70+
file.write(reinterpret_cast<char *>(&version), sizeof version);
5471
file.write(reinterpret_cast<char *>(&tap_time), sizeof tap_time);
5572
file.write(reinterpret_cast<char *>(&mirror_mod), sizeof mirror_mod);
5673
file.write(reinterpret_cast<char *>(&compensation_offset), sizeof compensation_offset);
5774
file.write(reinterpret_cast<char *>(&humanization_modifier), sizeof humanization_modifier);
58-
file.write(reinterpret_cast<char *>(&randomization_range.first), sizeof randomization_range.first);
59-
file.write(reinterpret_cast<char *>(&randomization_range.second), sizeof randomization_range.second);
75+
file.write(reinterpret_cast<char *>(&randomization_mean), sizeof randomization_mean);
76+
file.write(reinterpret_cast<char *>(&randomization_stddev), sizeof randomization_stddev);
6077
file.write(reinterpret_cast<char *>(&humanization_type), sizeof humanization_type);
6178

6279
debug("wrote config to file");

lib/include/maniac/maniac.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace maniac {
4242

4343
void block_until_playing();
4444

45-
void randomize(std::vector<osu::HitObject> &hit_objects, std::pair<int, int> range);
45+
void randomize(std::vector<osu::HitObject> &hit_objects, int mean, int stddev);
4646
void humanize_static(std::vector<osu::HitObject> &hit_objects, int modifier);
4747
void humanize_dynamic(std::vector<osu::HitObject> &hit_objects, int modifier);
4848

0 commit comments

Comments
 (0)