Banjo API
1.0.0-rc.2
Low-level C99 game development API
Loading...
Searching...
No Matches
random.c
Go to the documentation of this file.
1
16
17
#include <
banjo/log.h
>
18
#include <
banjo/main.h
>
19
#include <
banjo/random.h
>
20
#include <
banjo/time.h
>
21
#include <
string.h
>
22
23
// Helper: build a 64-bit value by combining two 32-bit draws.
24
// PCG32 generates 32-bit values, but you can combine them for larger ranges.
25
static
uint64_t
pcg32_u64
(
bj_pcg32
*g) {
26
uint64_t hi = (uint64_t)
bj_next_pcg32
(g);
27
uint64_t lo = (uint64_t)
bj_next_pcg32
(g);
28
return
(hi << 32) | lo;
29
}
30
31
int
main
(
int
argc,
char
* argv[]) {
32
(void)argc; (void)argv;
33
34
// Global API: bj_rand() works like C stdlib rand(). It uses hidden global
35
// state, so it's simple but not suitable when you need independent streams.
36
bj_info
(
"Before srand():"
);
37
for
(
size_t
i = 0; i < 5; ++i) {
38
bj_info
(
"\tbj_rand() -> %d"
,
bj_rand
());
39
}
40
41
// Seed the global generator. Use current time for non-deterministic results.
42
bj_srand
((
unsigned
)
bj_get_time
());
43
bj_info
(
"After srand():"
);
44
for
(
size_t
i = 0; i < 5; ++i) {
45
bj_info
(
"\tbj_rand() -> %d"
,
bj_rand
());
46
}
47
48
// PCG32 API: Each bj_pcg32 is an independent generator with its own state.
49
// This allows multiple random streams that don't interfere with each other.
50
bj_info
(
"PCG32:"
);
51
52
// Zero-initialised generators have a default seed. They produce the same
53
// sequence every run, which is useful for reproducible testing.
54
bj_pcg32
g0 = (
bj_pcg32
){0};
55
bj_info
(
"\tzero-init stream:"
);
56
for
(
size_t
i = 0; i < 3; ++i) {
57
bj_info
(
"\t\t%10u"
,
bj_next_pcg32
(&g0));
58
}
59
60
// Seed with current time for non-deterministic results. The sequence
61
// parameter (54) selects which stream to use. Same seed + different sequence
62
// = independent random numbers.
63
bj_pcg32
g1 = (
bj_pcg32
){0};
64
bj_seed_pcg32
(&g1, (uint64_t)
bj_get_time
(), 54u);
65
bj_info
(
"\tseeded with time, seq=54:"
);
66
for
(
size_t
i = 0; i < 3; ++i) {
67
bj_info
(
"\t\t%10u"
,
bj_next_pcg32
(&g1));
68
}
69
70
// Different sequence number creates an independent stream. Even with the
71
// same seed, seq=55 produces completely different numbers than seq=54.
72
// This is useful for having separate random streams per game entity.
73
bj_pcg32
g2 = (
bj_pcg32
){0};
74
bj_seed_pcg32
(&g2, (uint64_t)
bj_get_time
(), 55u);
75
bj_info
(
"\tseeded with time, seq=55 (independent):"
);
76
for
(
size_t
i = 0; i < 3; ++i) {
77
bj_info
(
"\t\t%10u"
,
bj_next_pcg32
(&g2));
78
}
79
80
// Query the range of values PCG32 can generate (0 to UINT32_MAX).
81
bj_info
(
"\tmin=%u max=%u"
,
bj_min_pcg32
(),
bj_max_pcg32
());
82
83
// Jump-ahead: bj_discard_pcg32() efficiently skips values without generating
84
// them. This is useful for synchronizing streams or implementing parallel
85
// random number generation.
86
bj_pcg32
gA = (
bj_pcg32
){0};
87
bj_pcg32
gB = (
bj_pcg32
){0};
88
bj_seed_pcg32
(&gA, 1234u, 999u);
89
bj_seed_pcg32
(&gB, 1234u, 999u);
90
for
(
size_t
i = 0; i < 10; ++i) (
void
)
bj_next_pcg32
(&gA);
// Manually advance gA
91
bj_discard_pcg32
(&gB, 10);
// Efficiently skip 10 values in gB
92
bj_info
(
"\tdiscard(10) aligns streams: %u vs %u"
,
bj_next_pcg32
(&gA),
bj_next_pcg32
(&gB));
93
94
// Building larger values: combine multiple 32-bit draws for wider ranges.
95
// This is how you'd generate uint64_t random numbers.
96
bj_pcg32
g64 = (
bj_pcg32
){0};
97
bj_seed_pcg32
(&g64, 0xCAFEBABEULL, 0xDEADULL);
98
uint64_t x =
pcg32_u64
(&g64);
99
bj_info
(
"\tu64 from two draws: 0x%016llx"
, (
unsigned
long
long
)x);
100
101
return
0;
102
}
main
int main(int argc, char *argv[])
Definition
audio_pcm.c:177
bj_info
#define bj_info(...)
Log a message using the BJ_LOG_INFO level.
Definition
log.h:141
bj_seed_pcg32
void bj_seed_pcg32(struct bj_pcg32 *generator, uint64_t seed, uint64_t seq)
Set the generator state from seed and sequence.
bj_min_pcg32
uint32_t bj_min_pcg32(void)
Smallest possible value returned by the generator.
bj_discard_pcg32
void bj_discard_pcg32(struct bj_pcg32 *generator, uint64_t z)
Advance the generator state by z steps.
bj_max_pcg32
uint32_t bj_max_pcg32(void)
Largest possible value returned by the generator.
bj_srand
void bj_srand(unsigned int seed)
Seed the standard PRNG.
bj_rand
int bj_rand(void)
Generate a pseudo-random integer in [0, BJ_RAND_MAX].
bj_next_pcg32
uint32_t bj_next_pcg32(struct bj_pcg32 *generator)
Advance the generator and return the next 32-bit value.
bj_pcg32
PCG32 generator state.
Definition
random.h:114
bj_get_time
uint64_t bj_get_time(void)
Get the current system time in seconds since the Unix epoch.
log.h
Logging utility functions.
main.h
Portable main() replacement with platform-aware entry shim.
pcg32_u64
static uint64_t pcg32_u64(bj_pcg32 *g)
Definition
random.c:25
random.h
Pseudo-random number generation API.
string.h
String utility functions.
time.h
Header file for time manipulation utilities.
examples
random.c
Generated on
for Banjo API by
1.14.0