您如何在Rust中生成随机骰子?
我知道我可以使用rand::random
,但是这要求我想生成一个整数类型的值。使用rand::random<u8>() % 6
会带来偏差。
答案 0 :(得分:4)
使用Rng::gen_range
作为一个一次性值:
Activity
在内部,这将创建一个Uniform
结构。如果您将获得多个随机数,请自己创建此结构:
use rand::{self, Rng}; // 0.6.4
fn main() {
let mut rng = rand::thread_rng();
let die = rng.gen_range(1, 7);
println!("The die was: {}", die);
}
use rand::{
self,
distributions::{Distribution, Uniform},
}; // 0.6.4
fn main() {
let mut rng = rand::thread_rng();
let die_range = Uniform::new_inclusive(1, 6);
let die = die_range.sample(&mut rng);
println!("{}", die);
}
进行了一些预计算,以找出如何在不引入偏差的情况下将随机值的整个范围映射到所需范围。它会转换并调整原始范围的大小,使其与随机数生成器的范围最匹配,丢弃所有超出此新范围的随机数,然后调整大小并转换回原始范围。
另请参阅:
答案 1 :(得分:3)
您正确地引入了偏见;每当您要从集合A映射到集合B而集合B的基数不是集合A的因数或倍数时,您都会有偏差。
对于您来说,42*6=252
。因此,您可以丢弃任何u8
值为252或更大的值(并再次调用random)。
然后可以使用模数运算符安全地映射您的输出。最后加1以实现标准的[1,6]骰子输出。
再次调用random似乎很不干净,但是在不引入偏差的情况下无法将一组256个值映射到一组6个值。
编辑:看来rand箱子中有一些东西要考虑到偏差:https://docs.rs/rand/latest/rand/distributions/uniform/struct.Uniform.html