1use std::collections::BTreeSet;
4
5use crate::player::PlayerId;
6
7#[derive(Clone, PartialEq, Eq, Default, Debug)]
21pub struct ActivePlayers(BTreeSet<PlayerId>);
22
23impl ActivePlayers {
24 #[must_use]
26 pub const fn none() -> Self {
27 Self(BTreeSet::new())
28 }
29
30 #[must_use]
32 pub fn one(player: PlayerId) -> Self {
33 let mut set = BTreeSet::new();
34 set.insert(player);
35 Self(set)
36 }
37
38 #[must_use]
42 pub fn all(num_players: u32) -> Self {
43 (0..num_players).map(PlayerId::new).collect()
44 }
45
46 #[must_use]
48 pub fn contains(&self, player: PlayerId) -> bool {
49 self.0.contains(&player)
50 }
51
52 #[must_use]
54 pub fn len(&self) -> usize {
55 self.0.len()
56 }
57
58 #[must_use]
60 pub fn is_empty(&self) -> bool {
61 self.0.is_empty()
62 }
63
64 pub fn iter(&self) -> impl Iterator<Item = PlayerId> + '_ {
66 self.0.iter().copied()
67 }
68}
69
70impl FromIterator<PlayerId> for ActivePlayers {
71 fn from_iter<I: IntoIterator<Item = PlayerId>>(iter: I) -> Self {
72 Self(iter.into_iter().collect())
73 }
74}
75
76impl<'a> IntoIterator for &'a ActivePlayers {
77 type Item = PlayerId;
78 type IntoIter = std::iter::Copied<std::collections::btree_set::Iter<'a, PlayerId>>;
79
80 fn into_iter(self) -> Self::IntoIter {
81 self.0.iter().copied()
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::ActivePlayers;
88 use crate::player::PlayerId;
89
90 #[test]
91 fn none_is_empty() {
92 let a = ActivePlayers::none();
93 assert!(a.is_empty());
94 assert_eq!(a.len(), 0);
95 }
96
97 #[test]
98 fn one_contains_only_that_player() {
99 let a = ActivePlayers::one(PlayerId::new(2));
100 assert_eq!(a.len(), 1);
101 assert!(a.contains(PlayerId::new(2)));
102 assert!(!a.contains(PlayerId::new(0)));
103 }
104
105 #[test]
106 fn all_covers_the_range_excluding_chance() {
107 let a = ActivePlayers::all(3);
108 assert_eq!(a.len(), 3);
109 assert!(a.contains(PlayerId::new(0)));
110 assert!(a.contains(PlayerId::new(2)));
111 assert!(!a.contains(PlayerId::CHANCE));
112 }
113
114 #[test]
115 fn iteration_is_ascending_and_deduplicated() {
116 let a: ActivePlayers = [PlayerId::new(2), PlayerId::new(0), PlayerId::new(2)]
117 .into_iter()
118 .collect();
119 let order: Vec<u32> = a.iter().map(PlayerId::index).collect();
120 assert_eq!(order, vec![0, 2]);
121 }
122}