Change randomweightedarray to use u16 weights instead of u8 (#8934)

This commit is contained in:
FosterProgramming 2026-01-18 10:24:49 +01:00 committed by GitHub
parent 258cc08533
commit 8d059cf5c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 28 additions and 19 deletions

View File

@ -244,7 +244,7 @@ enum RandomTag
#define RandomWeighted(tag, ...) \
({ \
const u8 weights[] = { __VA_ARGS__ }; \
const u16 weights[] = { __VA_ARGS__ }; \
u32 sum, i; \
for (i = 0, sum = 0; i < ARRAY_COUNT(weights); i++) \
sum += weights[i]; \
@ -266,7 +266,7 @@ enum RandomTag
} \
else \
{ \
const u8 weights[] = { 100 - t, t }; \
const u16 weights[] = { 100 - t, t }; \
r = RandomWeightedArray(tag, 100, ARRAY_COUNT(weights), weights); \
} \
r; \
@ -279,12 +279,12 @@ enum RandomTag
u32 RandomUniform(enum RandomTag, u32 lo, u32 hi);
u32 RandomUniformExcept(enum RandomTag, u32 lo, u32 hi, bool32 (*reject)(u32));
u32 RandomWeightedArray(enum RandomTag, u32 sum, u32 n, const u8 *weights);
u32 RandomWeightedArray(enum RandomTag, u32 sum, u32 n, const u16 *weights);
const void *RandomElementArray(enum RandomTag, const void *array, size_t size, size_t count);
u32 RandomUniformDefault(enum RandomTag, u32 lo, u32 hi);
u32 RandomUniformExceptDefault(enum RandomTag, u32 lo, u32 hi, bool32 (*reject)(u32));
u32 RandomWeightedArrayDefault(enum RandomTag, u32 sum, u32 n, const u8 *weights);
u32 RandomWeightedArrayDefault(enum RandomTag, u32 sum, u32 n, const u16 *weights);
const void *RandomElementArrayDefault(enum RandomTag, const void *array, size_t size, size_t count);
u8 RandomWeightedIndex(u8 *weights, u8 length);
@ -295,8 +295,8 @@ u32 RandomBitIndex(enum RandomTag tag, u32 bits);
#if TESTING
u32 RandomUniformTrials(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32), void *caller);
u32 RandomUniformDefaultValue(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32), void *caller);
u32 RandomWeightedArrayTrials(enum RandomTag tag, u32 sum, u32 n, const u8 *weights, void *caller);
u32 RandomWeightedArrayDefaultValue(enum RandomTag tag, u32 n, const u8 *weights, void *caller);
u32 RandomWeightedArrayTrials(enum RandomTag tag, u32 sum, u32 n, const u16 *weights, void *caller);
u32 RandomWeightedArrayDefaultValue(enum RandomTag tag, u32 n, const u16 *weights, void *caller);
const void *RandomElementArrayTrials(enum RandomTag tag, const void *array, size_t size, size_t count, void *caller);
const void *RandomElementArrayDefaultValue(enum RandomTag tag, const void *array, size_t size, size_t count, void *caller);
#endif

View File

@ -17,7 +17,7 @@ struct TestRunner
bool32 (*checkProgress)(void *);
bool32 (*handleExitWithResult)(void *, enum TestResult);
u32 (*randomUniform)(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32), void *caller);
u32 (*randomWeightedArray)(enum RandomTag tag, u32 sum, u32 n, const u8 *weights, void *caller);
u32 (*randomWeightedArray)(enum RandomTag tag, u32 sum, u32 n, const u16 *weights, void *caller);
const void* (*randomElementArray)(enum RandomTag tag, const void *array, size_t size, size_t count, void *caller);
};

View File

@ -166,7 +166,7 @@ __attribute__((weak, alias("RandomUniformExceptDefault")))
u32 RandomUniformExcept(enum RandomTag, u32 lo, u32 hi, bool32 (*reject)(u32));
__attribute__((weak, alias("RandomWeightedArrayDefault")))
u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights);
u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u16 *weights);
__attribute__((weak, alias("RandomElementArrayDefault")))
const void *RandomElementArray(enum RandomTag tag, const void *array, size_t size, size_t count);
@ -191,16 +191,17 @@ u32 RandomUniformExceptDefault(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reje
LOOP_RANDOM_END;
}
u32 RandomWeightedArrayDefault(enum RandomTag tag, u32 sum, u32 n, const u8 *weights)
u32 RandomWeightedArrayDefault(enum RandomTag tag, u32 sum, u32 n, const u16 *weights)
{
assertf(n > 0);
s32 i, targetSum;
assertf(sum <= MAX_u16);
u32 i, targetSum;
targetSum = (sum * Random()) >> 16;
for (i = 0; i < n - 1; i++)
{
targetSum -= weights[i];
if (targetSum < 0)
if (targetSum < weights[i])
return i;
targetSum -= weights[i];
}
return n - 1;
}

View File

@ -1,4 +1,5 @@
#include "global.h"
#include "malloc.h"
#include "test/test.h"
#include "random.h"
@ -79,19 +80,26 @@ TEST("RandomUniformExcept generates lo..hi")
TEST("RandomWeighted generates 0..n-1")
{
u32 n, sum, i;
static const u8 ws[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
static const u16 ws[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
u16 *ws2 = Alloc(8 * sizeof(u16));
PARAMETRIZE { n = 1; }
PARAMETRIZE { n = 2; }
PARAMETRIZE { n = 3; }
PARAMETRIZE { n = 4; }
ASSUME(n <= ARRAY_COUNT(ws));
for (i = 0, sum = 0; i < n; i++)
{
ws2[i] = ws[i];
sum += ws[i];
}
for (i = 0; i < 1024; i++)
{
u32 r = RandomWeightedArrayDefault(RNG_NONE, sum, n, ws);
EXPECT(0 <= r && r < n);
r = RandomWeightedArrayDefault(RNG_NONE, sum, n, ws2);
EXPECT(0 <= r && r < n);
}
Free(ws2);
}
TEST("RandomElement generates an element")
@ -151,7 +159,7 @@ TEST("RandomUniformExcept generates uniform distribution")
TEST("RandomWeighted generates distribution in proportion to the weights")
{
u32 i, sum, error;
static const u8 ws[4] = { 1, 2, 2, 3 };
static const u16 ws[4] = { 1, 2, 2, 3 };
u16 distribution[ARRAY_COUNT(ws)];
for (i = 0, sum = 0; i < ARRAY_COUNT(ws); i++)

View File

@ -617,7 +617,7 @@ static u32 FunctionTest_RandomUniform(enum RandomTag tag, u32 lo, u32 hi, bool32
return RandomUniformDefaultValue(tag, lo, hi, reject, caller);
}
static u32 FunctionTest_RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights, void *caller)
static u32 FunctionTest_RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u16 *weights, void *caller)
{
//rigged
for (u32 i = 0; i < RIGGED_RNG_COUNT; i++)
@ -1030,7 +1030,7 @@ u32 RandomUniformExcept(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32
return RandomUniformExceptDefault(tag, lo, hi, reject);
}
u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights)
u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u16 *weights)
{
void *caller = __builtin_extract_return_addr(__builtin_return_address(0));
if (gTestRunnerState.test->runner->randomWeightedArray)
@ -1063,7 +1063,7 @@ u32 RandomUniformDefaultValue(enum RandomTag tag, u32 lo, u32 hi, bool32 (*rejec
return default_;
}
u32 RandomWeightedArrayDefaultValue(enum RandomTag tag, u32 n, const u8 *weights, void *caller)
u32 RandomWeightedArrayDefaultValue(enum RandomTag tag, u32 n, const u16 *weights, void *caller)
{
while (weights[n-1] == 0)
{

View File

@ -622,7 +622,7 @@ u32 RandomUniformTrials(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32
}
u32 RandomWeightedArrayTrials(enum RandomTag tag, u32 sum, u32 n, const u8 *weights, void *caller)
u32 RandomWeightedArrayTrials(enum RandomTag tag, u32 sum, u32 n, const u16 *weights, void *caller)
{
//Detect inconsistent sum
u32 weightSum = 0;
@ -727,7 +727,7 @@ static u32 BattleTest_RandomUniform(enum RandomTag tag, u32 lo, u32 hi, bool32 (
return RandomUniformDefaultValue(tag, lo, hi, reject, caller);
}
static u32 BattleTest_RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights, void *caller)
static u32 BattleTest_RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u16 *weights, void *caller)
{
//rigged
const struct BattlerTurn *turn = NULL;