From 3f38846d6f654cb76d1ce1850195694c6bbba675 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 4 Oct 2024 23:24:17 +0200 Subject: [PATCH 1/8] Set version to 0.11.3 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82b1cbb9..a5f32b18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.14) -project(libscratchcpp VERSION 0.11.2 LANGUAGES C CXX) +project(libscratchcpp VERSION 0.11.3 LANGUAGES C CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_STANDARD 17) From c99bcdb9c447529abb6c859269d78f5182374871 Mon Sep 17 00:00:00 2001 From: aspizu Date: Sat, 5 Oct 2024 03:39:24 +0530 Subject: [PATCH 2/8] Implement method randintExcept for RandomGenerator. --- src/engine/internal/irandomgenerator.h | 1 + src/engine/internal/randomgenerator.cpp | 13 +++++++++++ src/engine/internal/randomgenerator.h | 1 + test/randomgenerator/randomgenerator_test.cpp | 22 +++++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/src/engine/internal/irandomgenerator.h b/src/engine/internal/irandomgenerator.h index c8d4a177..2228c933 100644 --- a/src/engine/internal/irandomgenerator.h +++ b/src/engine/internal/irandomgenerator.h @@ -12,6 +12,7 @@ class IRandomGenerator virtual long randint(long start, long end) const = 0; virtual double randintDouble(double start, double end) const = 0; + virtual long randintExcept(long start, long end, long except) const = 0; }; } // namespace libscratchcpp diff --git a/src/engine/internal/randomgenerator.cpp b/src/engine/internal/randomgenerator.cpp index 06e169e7..84cca982 100644 --- a/src/engine/internal/randomgenerator.cpp +++ b/src/engine/internal/randomgenerator.cpp @@ -41,3 +41,16 @@ double RandomGenerator::randintDouble(double start, double end) const std::uniform_real_distribution distribution(start, end); return distribution(*m_generator); } + +long RandomGenerator::randintExcept(long start, long end, long except) const +{ + if (start > end) { + std::swap(start, end); + } + std::uniform_int_distribution distribution(start, end); + long value = distribution(*m_generator); + if (value == except) { + return randintExcept(start, end, except); + } + return value; +} diff --git a/src/engine/internal/randomgenerator.h b/src/engine/internal/randomgenerator.h index 6cb72586..1358de37 100644 --- a/src/engine/internal/randomgenerator.h +++ b/src/engine/internal/randomgenerator.h @@ -20,6 +20,7 @@ class RandomGenerator : public IRandomGenerator long randint(long start, long end) const override; double randintDouble(double start, double end) const override; + long randintExcept(long start, long end, long except) const; private: static std::shared_ptr m_instance; diff --git a/test/randomgenerator/randomgenerator_test.cpp b/test/randomgenerator/randomgenerator_test.cpp index 45f220af..fe327c81 100644 --- a/test/randomgenerator/randomgenerator_test.cpp +++ b/test/randomgenerator/randomgenerator_test.cpp @@ -43,3 +43,25 @@ TEST(RandomGeneratorTest, RandIntDouble) ASSERT_LE(num, 5.081); } } + +TEST(RandomGeneratorTest, RandInt) +{ + auto rng = RandomGenerator::instance(); + ASSERT_TRUE(rng); + + long num; + + for (int i = 0; i < 25; i++) { + num = rng->randintExcept(-2, 3, 0); + ASSERT_GE(num, -2); + ASSERT_LE(num, 3); + ASSERT_NE(num, 0); + } + + for (int i = 0; i < 25; i++) { + num = rng->randintExcept(5, -3, 2); + ASSERT_GE(num, -3); + ASSERT_LE(num, 5); + ASSERT_NE(num, 2); + } +} From a92fe8f069fcef486a2302ddd9e5d56720f2a8b6 Mon Sep 17 00:00:00 2001 From: aspizu Date: Sat, 5 Oct 2024 03:47:05 +0530 Subject: [PATCH 3/8] Always select a different random backdrop. (Closes #521) --- src/blocks/looksblocks.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/blocks/looksblocks.cpp b/src/blocks/looksblocks.cpp index 5d2cf55a..da77cc3c 100644 --- a/src/blocks/looksblocks.cpp +++ b/src/blocks/looksblocks.cpp @@ -964,8 +964,9 @@ void LooksBlocks::randomBackdropImpl(VirtualMachine *vm) if (Stage *stage = vm->engine()->stage()) { std::size_t count = stage->costumes().size(); - if (count > 0) - stage->setCostumeIndex(rng->randint(0, count - 1)); + if (count > 0) { + stage->setCostumeIndex(rng->randintExcept(0, count - 1, stage->costumeIndex())); + } } } From d50ca4548ca75ee1270dfc027eac8a37447cf281 Mon Sep 17 00:00:00 2001 From: aspizu Date: Sat, 5 Oct 2024 03:56:44 +0530 Subject: [PATCH 4/8] Fix tests for randomBackdrop. --- test/blocks/looks_blocks_test.cpp | 2 +- test/mocks/randomgeneratormock.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/blocks/looks_blocks_test.cpp b/test/blocks/looks_blocks_test.cpp index 92c21532..ba2318bc 100644 --- a/test/blocks/looks_blocks_test.cpp +++ b/test/blocks/looks_blocks_test.cpp @@ -2507,7 +2507,7 @@ TEST_F(LooksBlocksTest, RandomBackdrop) stage.addCostume(std::make_shared("backdrop4", "b4", "svg")); - EXPECT_CALL(rng, randint(0, 3)).WillOnce(Return(2)); + EXPECT_CALL(rng, randintExcept(0, 3, 1)).WillOnce(Return(2)); EXPECT_CALL(m_engineMock, startBackdropScripts(stage.costumeAt(2)->broadcast(), &thread, false)); vm->reset(); vm->run(); diff --git a/test/mocks/randomgeneratormock.h b/test/mocks/randomgeneratormock.h index 42d6e999..6e07f881 100644 --- a/test/mocks/randomgeneratormock.h +++ b/test/mocks/randomgeneratormock.h @@ -10,4 +10,5 @@ class RandomGeneratorMock : public IRandomGenerator public: MOCK_METHOD(long, randint, (long, long), (const, override)); MOCK_METHOD(double, randintDouble, (double, double), (const, override)); + MOCK_METHOD(long, randintExcept, (long, long, long), (const, override)); }; From 5354253922f62296d91e4288789cfbcfd58f6009 Mon Sep 17 00:00:00 2001 From: aspizu Date: Sat, 5 Oct 2024 04:02:43 +0530 Subject: [PATCH 5/8] Only switch to a random backdrop if there are more than 1 backdrops. --- src/blocks/looksblocks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks/looksblocks.cpp b/src/blocks/looksblocks.cpp index da77cc3c..f142f34c 100644 --- a/src/blocks/looksblocks.cpp +++ b/src/blocks/looksblocks.cpp @@ -964,7 +964,7 @@ void LooksBlocks::randomBackdropImpl(VirtualMachine *vm) if (Stage *stage = vm->engine()->stage()) { std::size_t count = stage->costumes().size(); - if (count > 0) { + if (count > 1) { stage->setCostumeIndex(rng->randintExcept(0, count - 1, stage->costumeIndex())); } } From 67dd84ff993b4240d48da1f6f2681d65a74bdf03 Mon Sep 17 00:00:00 2001 From: aspizu Date: Sat, 5 Oct 2024 04:03:09 +0530 Subject: [PATCH 6/8] Fix test name for RandIntExcept. --- test/randomgenerator/randomgenerator_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/randomgenerator/randomgenerator_test.cpp b/test/randomgenerator/randomgenerator_test.cpp index fe327c81..1a7fedba 100644 --- a/test/randomgenerator/randomgenerator_test.cpp +++ b/test/randomgenerator/randomgenerator_test.cpp @@ -44,7 +44,7 @@ TEST(RandomGeneratorTest, RandIntDouble) } } -TEST(RandomGeneratorTest, RandInt) +TEST(RandomGeneratorTest, RandIntExcept) { auto rng = RandomGenerator::instance(); ASSERT_TRUE(rng); From ec949411a7bbc74ccb8952005063ba159fc167bb Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sat, 12 Oct 2024 19:46:16 +0200 Subject: [PATCH 7/8] Update random backdrop tests --- test/blocks/looks_blocks_test.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test/blocks/looks_blocks_test.cpp b/test/blocks/looks_blocks_test.cpp index ba2318bc..041c32b8 100644 --- a/test/blocks/looks_blocks_test.cpp +++ b/test/blocks/looks_blocks_test.cpp @@ -1992,7 +1992,7 @@ TEST_F(LooksBlocksTest, SwitchBackdropToImpl) LooksBlocks::rng = &rng; EXPECT_CALL(m_engineMock, startBackdropScripts(stage.costumeAt(3)->broadcast(), &thread, false)); - EXPECT_CALL(rng, randint(0, 5)).WillOnce(Return(3)); + EXPECT_CALL(rng, randintExcept(0, 5, 0)).WillOnce(Return(3)); stage.setCostumeIndex(0); vm->setBytecode(bytecode15); vm->run(); @@ -2001,7 +2001,7 @@ TEST_F(LooksBlocksTest, SwitchBackdropToImpl) ASSERT_EQ(stage.costumeIndex(), 3); EXPECT_CALL(m_engineMock, startBackdropScripts(stage.costumeAt(5)->broadcast(), &thread, false)); - EXPECT_CALL(rng, randint(0, 5)).WillOnce(Return(5)); + EXPECT_CALL(rng, randintExcept(0, 5, 3)).WillOnce(Return(5)); vm->reset(); vm->run(); @@ -2011,7 +2011,7 @@ TEST_F(LooksBlocksTest, SwitchBackdropToImpl) stage.addCostume(std::make_shared("random backdrop", "b7", "svg")); EXPECT_CALL(m_engineMock, startBackdropScripts(stage.costumeAt(6)->broadcast(), &thread, false)); - EXPECT_CALL(rng, randint).Times(0); + EXPECT_CALL(rng, randintExcept).Times(0); vm->reset(); vm->run(); @@ -2337,7 +2337,7 @@ TEST_F(LooksBlocksTest, SwitchBackdropToAndWaitImpl) LooksBlocks::rng = &rng; EXPECT_CALL(m_engineMock, startBackdropScripts(stage.costumeAt(3)->broadcast(), &thread, true)); - EXPECT_CALL(rng, randint(0, 5)).WillOnce(Return(3)); + EXPECT_CALL(rng, randintExcept(0, 5, 0)).WillOnce(Return(3)); stage.setCostumeIndex(0); vm->resolvePromise(); vm->setBytecode(bytecode15); @@ -2349,7 +2349,7 @@ TEST_F(LooksBlocksTest, SwitchBackdropToAndWaitImpl) ASSERT_EQ(stage.costumeIndex(), 3); EXPECT_CALL(m_engineMock, startBackdropScripts(stage.costumeAt(5)->broadcast(), &thread, true)); - EXPECT_CALL(rng, randint(0, 5)).WillOnce(Return(5)); + EXPECT_CALL(rng, randintExcept(0, 5, 3)).WillOnce(Return(5)); vm->reset(); vm->run(); vm->resolvePromise(); @@ -2361,7 +2361,7 @@ TEST_F(LooksBlocksTest, SwitchBackdropToAndWaitImpl) stage.addCostume(std::make_shared("random backdrop", "b7", "svg")); EXPECT_CALL(m_engineMock, startBackdropScripts(stage.costumeAt(6)->broadcast(), &thread, true)); - EXPECT_CALL(rng, randint).Times(0); + EXPECT_CALL(rng, randintExcept).Times(0); vm->reset(); vm->run(); vm->resolvePromise(); @@ -2488,7 +2488,7 @@ TEST_F(LooksBlocksTest, RandomBackdrop) RandomGeneratorMock rng; LooksBlocks::rng = &rng; - EXPECT_CALL(rng, randint).Times(0); + EXPECT_CALL(rng, randintExcept).Times(0); vm->run(); ASSERT_EQ(vm->registerCount(), 0); @@ -2496,8 +2496,9 @@ TEST_F(LooksBlocksTest, RandomBackdrop) stage.addCostume(std::make_shared("backdrop1", "b1", "svg")); stage.addCostume(std::make_shared("backdrop2", "b2", "svg")); stage.addCostume(std::make_shared("backdrop3", "b3", "svg")); + stage.setCostumeIndex(0); - EXPECT_CALL(rng, randint(0, 2)).WillOnce(Return(1)); + EXPECT_CALL(rng, randintExcept(0, 2, 0)).WillOnce(Return(1)); EXPECT_CALL(m_engineMock, startBackdropScripts(stage.costumeAt(1)->broadcast(), &thread, false)); vm->reset(); vm->run(); From f4f3fd0e15a22b58e3eabbcbd69c4da68484e318 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sat, 12 Oct 2024 20:34:32 +0200 Subject: [PATCH 8/8] RandomGenerator: Optimize randintExcept() --- src/engine/internal/randomgenerator.cpp | 23 ++++++++++--- test/randomgenerator/randomgenerator_test.cpp | 32 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/engine/internal/randomgenerator.cpp b/src/engine/internal/randomgenerator.cpp index 84cca982..e9e7c572 100644 --- a/src/engine/internal/randomgenerator.cpp +++ b/src/engine/internal/randomgenerator.cpp @@ -47,10 +47,23 @@ long RandomGenerator::randintExcept(long start, long end, long except) const if (start > end) { std::swap(start, end); } - std::uniform_int_distribution distribution(start, end); - long value = distribution(*m_generator); - if (value == except) { - return randintExcept(start, end, except); + + if (except < start || except > end) { + return randint(start, end); + } else if (start == end) { + return start; + } else if (end - start == 1) { + if (except == start) + return end; + else + return start; + } + + if (randint(0, 1) == 0) { + std::uniform_int_distribution distribution(start, except - 1); + return distribution(*m_generator); + } else { + std::uniform_int_distribution distribution(except + 1, end); + return distribution(*m_generator); } - return value; } diff --git a/test/randomgenerator/randomgenerator_test.cpp b/test/randomgenerator/randomgenerator_test.cpp index 1a7fedba..06b9dda0 100644 --- a/test/randomgenerator/randomgenerator_test.cpp +++ b/test/randomgenerator/randomgenerator_test.cpp @@ -64,4 +64,36 @@ TEST(RandomGeneratorTest, RandIntExcept) ASSERT_LE(num, 5); ASSERT_NE(num, 2); } + + for (int i = 0; i < 25; i++) { + num = rng->randintExcept(5, 8, 2); + ASSERT_GE(num, 5); + ASSERT_LE(num, 8); + } + + for (int i = 0; i < 25; i++) { + num = rng->randintExcept(5, 8, 10); + ASSERT_GE(num, 5); + ASSERT_LE(num, 8); + } + + for (int i = 0; i < 25; i++) { + num = rng->randintExcept(2, 2, 2); + ASSERT_EQ(num, 2); + } + + for (int i = 0; i < 25; i++) { + num = rng->randintExcept(2, 2, 5); + ASSERT_EQ(num, 2); + } + + for (int i = 0; i < 25; i++) { + num = rng->randintExcept(1, 2, 1); + ASSERT_EQ(num, 2); + } + + for (int i = 0; i < 25; i++) { + num = rng->randintExcept(1, 2, 2); + ASSERT_EQ(num, 1); + } }