Skip to content

Commit 25a49d9

Browse files
committed
Add RandomGenerator class
1 parent cbe32cc commit 25a49d9

File tree

9 files changed

+164
-1
lines changed

9 files changed

+164
-1
lines changed

src/engine/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ target_sources(scratchcpp
1919
internal/blocksectioncontainer.cpp
2020
internal/blocksectioncontainer.h
2121
internal/global.h
22+
internal/randomgenerator.h
23+
internal/randomgenerator.cpp
24+
internal/irandomgenerator.h
2225
)

src/engine/internal/engine.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ Engine::Engine() :
2727
m_defaultTimer(std::make_unique<Timer>()),
2828
m_timer(m_defaultTimer.get())
2929
{
30-
srand(time(NULL));
3130
}
3231

3332
void Engine::clear()
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
namespace libscratchcpp
6+
{
7+
8+
class IRandomGenerator
9+
{
10+
public:
11+
virtual ~IRandomGenerator() { }
12+
13+
virtual long randint(long start, long end) const = 0;
14+
virtual double randintDouble(double start, double end) const = 0;
15+
};
16+
17+
} // namespace libscratchcpp
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#include <random>
4+
5+
#include "randomgenerator.h"
6+
7+
using namespace libscratchcpp;
8+
9+
std::shared_ptr<RandomGenerator> RandomGenerator::m_instance = std::make_shared<RandomGenerator>();
10+
11+
RandomGenerator::RandomGenerator() :
12+
m_generator(std::make_unique<std::mt19937>(m_device()))
13+
{
14+
}
15+
16+
std::shared_ptr<RandomGenerator> RandomGenerator::instance()
17+
{
18+
return m_instance;
19+
}
20+
21+
long RandomGenerator::randint(long start, long end) const
22+
{
23+
if (start > end) {
24+
long tmp = start;
25+
start = end;
26+
end = tmp;
27+
}
28+
29+
std::uniform_int_distribution<long> distribution(start, end);
30+
return distribution(*m_generator);
31+
}
32+
33+
double RandomGenerator::randintDouble(double start, double end) const
34+
{
35+
if (start > end) {
36+
double tmp = start;
37+
start = end;
38+
end = tmp;
39+
}
40+
41+
std::uniform_real_distribution<double> distribution(start, end);
42+
return distribution(*m_generator);
43+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <memory>
6+
#include <random>
7+
8+
#include "irandomgenerator.h"
9+
10+
namespace libscratchcpp
11+
{
12+
13+
class RandomGenerator : public IRandomGenerator
14+
{
15+
public:
16+
RandomGenerator();
17+
RandomGenerator(const RandomGenerator &) = delete;
18+
19+
static std::shared_ptr<RandomGenerator> instance();
20+
21+
long randint(long start, long end) const override;
22+
double randintDouble(double start, double end) const override;
23+
24+
private:
25+
static std::shared_ptr<RandomGenerator> m_instance;
26+
std::random_device m_device;
27+
std::unique_ptr<std::mt19937> m_generator;
28+
};
29+
30+
} // namespace libscratchcpp

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ add_subdirectory(extensions)
3030
add_subdirectory(engine)
3131
add_subdirectory(clock)
3232
add_subdirectory(timer)
33+
add_subdirectory(randomgenerator)

test/mocks/randomgeneratormock.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
#include <engine/internal/irandomgenerator.h>
4+
#include <gmock/gmock.h>
5+
6+
using namespace libscratchcpp;
7+
8+
class RandomGeneratorMock : public IRandomGenerator
9+
{
10+
public:
11+
MOCK_METHOD(long, randint, (long, long), (const, override));
12+
MOCK_METHOD(double, randintDouble, (double, double), (const, override));
13+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
add_executable(
2+
randomgenerator_test
3+
randomgenerator_test.cpp
4+
)
5+
6+
target_link_libraries(
7+
randomgenerator_test
8+
GTest::gtest_main
9+
scratchcpp
10+
)
11+
12+
gtest_discover_tests(randomgenerator_test)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <engine/internal/randomgenerator.h>
2+
3+
#include "../common.h"
4+
5+
using namespace libscratchcpp;
6+
7+
TEST(RandomGeneratorTest, RandInt)
8+
{
9+
auto rng = RandomGenerator::instance();
10+
ASSERT_TRUE(rng);
11+
12+
long num;
13+
14+
for (int i = 0; i < 25; i++) {
15+
num = rng->randint(-2, 3);
16+
ASSERT_GE(num, -2);
17+
ASSERT_LE(num, 3);
18+
}
19+
20+
for (int i = 0; i < 25; i++) {
21+
num = rng->randint(5, -3);
22+
ASSERT_GE(num, -3);
23+
ASSERT_LE(num, 5);
24+
}
25+
}
26+
27+
TEST(RandomGeneratorTest, RandIntDouble)
28+
{
29+
auto rng = RandomGenerator::instance();
30+
ASSERT_TRUE(rng);
31+
32+
long num;
33+
34+
for (int i = 0; i < 1000; i++) {
35+
num = rng->randintDouble(-2.23, 3.875);
36+
ASSERT_GE(num, -2.23);
37+
ASSERT_LE(num, 3.875);
38+
}
39+
40+
for (int i = 0; i < 1000; i++) {
41+
num = rng->randintDouble(5.081, -2.903);
42+
ASSERT_GE(num, -2.903);
43+
ASSERT_LE(num, 5.081);
44+
}
45+
}

0 commit comments

Comments
 (0)