From bd61781fdee7913ef6b9026c6bb5625251743bfa Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 14 Feb 2021 12:22:58 +0900 Subject: [PATCH] Math: Implement RandF, RandTableInit and RandTable These are used in Big Bang Age. --- src/hll/Math.c | 77 ++++++++++++++++++++++++++++++++++++++++---- test/Source/math.jaf | 11 ++++++- 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/hll/Math.c b/src/hll/Math.c index bbf5858..9df1ac4 100644 --- a/src/hll/Math.c +++ b/src/hll/Math.c @@ -23,6 +23,24 @@ #include "hll.h" +struct shuffle_table { + int id; + struct shuffle_table *next; + int *elems; + int size; + int i; +}; +static struct shuffle_table *shuffle_tables; + +static struct shuffle_table *find_shuffle_table(int id) +{ + for (struct shuffle_table *tbl = shuffle_tables; tbl; tbl = tbl->next) { + if (tbl->id == id) + return tbl; + } + return NULL; +} + static inline float deg2rad(float deg) { return deg * (M_PI / 180.0); @@ -73,9 +91,56 @@ static void Math_SwapF(float *a, float *b) } //void Math_SetRandMode(int mode); -//float Math_RandF(void); -//void Math_RandTableInit(int num, int size); -//int Math_RandTable(int num); + +static float Math_RandF(void) +{ + return rand() * (1.0 / (RAND_MAX + 1U)); +} + +static void shuffle_array(int *a, int len) +{ + for (int i = len - 1; i > 0; i--) { + int j = Math_RandF() * i; + int tmp = a[j]; + a[j] = a[i]; + a[i] = tmp; + } +} + +static void Math_RandTableInit(int num, int size) +{ + struct shuffle_table *tbl = find_shuffle_table(num); + if (tbl) { + free(tbl->elems); + } else { + tbl = xmalloc(sizeof(struct shuffle_table)); + tbl->id = num; + tbl->next = shuffle_tables; + shuffle_tables = tbl; + } + tbl->elems = xmalloc(size * sizeof(int)); + tbl->size = size; + tbl->i = 0; + for (int i = 0; i < size; i++) + tbl->elems[i] = i; + shuffle_array(tbl->elems, size); +} + +static int Math_RandTable(int num) +{ + struct shuffle_table *tbl = find_shuffle_table(num); + if (!tbl) { + WARNING("Invalid rand table id %d", num); + return 0; + } + if (tbl->i >= tbl->size) { + // reshuffle + shuffle_array(tbl->elems, tbl->size); + tbl->i = 0; + } + return tbl->elems[tbl->i++]; +} + //void Math_RandTable2Init(int num, struct page *array); //int Math_RandTable2(int num); @@ -91,9 +156,9 @@ HLL_LIBRARY(Math, HLL_EXPORT(SetSeed, srand), //HLL_EXPORT(SetRandMode, Math_SetRandMode), HLL_EXPORT(Rand, rand), - //HLL_EXPORT(RandF, Math_RandF), - //HLL_EXPORT(RandTableInit, Math_RandTableInit), - //HLL_EXPORT(RandTable, Math_RandTable), + HLL_EXPORT(RandF, Math_RandF), + HLL_EXPORT(RandTableInit, Math_RandTableInit), + HLL_EXPORT(RandTable, Math_RandTable), //HLL_EXPORT(RandTable2Init, Math_RandTable2Init), //HLL_EXPORT(RandTable2, Math_RandTable2), HLL_EXPORT(Min, Math_Min), diff --git a/test/Source/math.jaf b/test/Source/math.jaf index f938953..7db4057 100755 --- a/test/Source/math.jaf +++ b/test/Source/math.jaf @@ -2,8 +2,9 @@ void test_math(void) { - int ia, ib; + int i, ia, ib; float fa, fb; + array@int ar[10]; test_float("Math.Cos(40)", Math.Cos(40), 0.766044); test_float("Math.Sin(40)", Math.Sin(40), 0.642788); test_float("Math.Atan(40)", Math.Atan(40), 1.545802); @@ -29,4 +30,12 @@ void test_math(void) Math.SwapF(fa, fb); test_float("Math.SwapF(a, b), a", fa, 2.0); test_float("Math.SwapF(a, b), b", fb, 1.0); + + Math.RandTableInit(42, 10); + for (i = 0; i < 10; i++) { + ar[Math.RandTable(42)] = 1; + } + for (i = 0; i < 10; i++) { + test_equal(string(i) + " appears in random shuffle table", ar[i], 1); + } }