1use rand::distributions::Distribution;
8use rand::Rng;
9
10pub struct OpCnt<R: Rng, E> {
12 op: fn(&mut R, &mut E) -> bool,
14 cnt: u64,
15}
16impl<R: Rng, E> OpCnt<R, E> {
17 pub fn new(op: fn(&mut R, &mut E) -> bool, cnt: u64) -> Self {
18 Self { op, cnt }
19 }
20}
21pub fn rand_op<'a, R: Rng, E>(
22 rng: &mut R,
23 env: &mut E,
24 mut op_cnts: Vec<OpCnt<R, E>>,
25) {
26 let mut tot = 0;
27 for op_cnt in op_cnts.iter() {
28 tot += op_cnt.cnt;
29 }
30 while tot > 0 {
31 let mut id = rand::distributions::Uniform::new(0, tot).sample(rng);
32 for op_cnt in &mut op_cnts {
33 if id < op_cnt.cnt {
34 if (op_cnt.op)(rng, env) {
35 tot -= 1;
36 op_cnt.cnt -= 1;
37 }
38 break;
39 }
40 id -= op_cnt.cnt;
41 }
42 }
43 for op_cnt in &op_cnts {
44 assert_eq!(op_cnt.cnt, 0);
45 }
46}