openpql_prelude/game/
player.rs1use super::{Add, AddAssign, Display, Into};
2
3pub type PlayerIdx = u8;
4
5#[derive(
6 Debug,
7 Clone,
8 Copy,
9 PartialEq,
10 Eq,
11 Default,
12 derive_more::From,
13 Into,
14 Display,
15 Add,
16 AddAssign,
17)]
18#[display("Player {_0}")]
19pub struct Player(PlayerIdx);
20
21impl Player {
22 pub fn iter(n: PlayerIdx) -> impl Iterator<Item = Self> {
23 (0..n).map(Self::from)
24 }
25
26 pub fn iter_opponents(self, n: PlayerIdx) -> impl Iterator<Item = Self> {
27 Self::iter(n).filter(move |&p| p != self)
28 }
29}
30
31impl From<usize> for Player {
32 #[cfg_attr(coverage_nightly, coverage(off))]
33 fn from(i: usize) -> Self {
34 debug_assert!(i < PlayerIdx::MAX.into());
35
36 Self(i.to_le_bytes()[0])
37 }
38}
39
40impl From<i32> for Player {
41 #[cfg_attr(coverage_nightly, coverage(off))]
42 fn from(i: i32) -> Self {
43 debug_assert!(i >= 0 && i < PlayerIdx::MAX.into());
44
45 Self(i.to_le_bytes()[0])
46 }
47}
48
49impl From<Player> for usize {
50 fn from(player: Player) -> Self {
51 player.0 as Self
52 }
53}
54
55#[cfg(test)]
56#[cfg_attr(coverage_nightly, coverage(off))]
57mod tests {
58 use super::*;
59 use crate::*;
60
61 impl Arbitrary for Player {
62 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
63 Self(PlayerIdx::arbitrary(g))
64 }
65 }
66
67 #[test]
68 fn test_conversion() {
69 for i in 0..10 {
70 let player = Player::from(i);
71 assert_eq!(player.0, i);
72 assert_eq!(usize::from(player), i as usize);
73 }
74 }
75
76 #[quickcheck]
77 fn test_iter(n: PlayerIdx) {
78 let n_players = n % 10;
79 let v: Vec<_> = Player::iter(n_players).collect();
80
81 assert_eq!(v, (0..n_players).map(Player::from).collect::<Vec<_>>());
82 }
83
84 #[quickcheck]
85 fn test_iter_opponents(n: PlayerIdx, player_idx: PlayerIdx) {
86 let n_players = n % 10;
87 if n_players == 0 {
88 return;
89 }
90
91 let player = Player::from(player_idx % n_players);
92 let opponents: Vec<_> = player.iter_opponents(n_players).collect();
93
94 assert!(!opponents.contains(&player));
95 assert_eq!(opponents.len(), (n_players - 1) as usize);
96
97 let expected: Vec<_> = (0..n_players)
98 .map(Player::from)
99 .filter(|&p| p != player)
100 .collect();
101 assert_eq!(opponents, expected);
102 }
103}