manabrew_engine/player/
player_collection.rs1use crate::game::GameState;
2use crate::ids::{CardId, PlayerId};
3use crate::player::player_predicates;
4use forge_foundation::ZoneType;
5
6#[derive(Debug, Clone, Default, PartialEq, Eq)]
7pub struct PlayerCollection(pub Vec<PlayerId>);
8
9impl IntoIterator for PlayerCollection {
10 type Item = PlayerId;
11 type IntoIter = std::vec::IntoIter<PlayerId>;
12
13 fn into_iter(self) -> Self::IntoIter {
14 self.0.into_iter()
15 }
16}
17
18impl<'a> IntoIterator for &'a PlayerCollection {
19 type Item = &'a PlayerId;
20 type IntoIter = std::slice::Iter<'a, PlayerId>;
21
22 fn into_iter(self) -> Self::IntoIter {
23 self.0.iter()
24 }
25}
26
27impl PlayerCollection {
28 pub fn new(players: Vec<PlayerId>) -> Self {
29 Self(players)
30 }
31
32 pub fn alive(game: &GameState) -> Self {
33 Self(game.alive_players())
34 }
35
36 pub fn opponents_of(game: &GameState, player: PlayerId) -> Self {
37 Self(
38 game.player_order
39 .iter()
40 .copied()
41 .filter(|&pid| player_predicates::is_opponent_of(game, player, pid))
42 .collect(),
43 )
44 }
45
46 pub fn teammates_of(game: &GameState, player: PlayerId) -> Self {
47 Self(
48 game.player_order
49 .iter()
50 .copied()
51 .filter(|&pid| player_predicates::same_team(game, player, pid))
52 .collect(),
53 )
54 }
55
56 pub fn contains(&self, player: PlayerId) -> bool {
57 self.0.contains(&player)
58 }
59
60 pub fn cards_in(&self, game: &GameState, zone: ZoneType) -> Vec<CardId> {
61 self.0
62 .iter()
63 .flat_map(|&pid| game.cards_in_zone(zone, pid).iter().copied())
64 .collect()
65 }
66
67 pub fn cards_in_zones(
68 &self,
69 game: &GameState,
70 zones: impl IntoIterator<Item = ZoneType>,
71 ) -> Vec<CardId> {
72 zones
73 .into_iter()
74 .flat_map(|zone| self.cards_in(game, zone))
75 .collect()
76 }
77
78 pub fn creatures_in_play(&self, game: &GameState) -> Vec<CardId> {
79 self.cards_in(game, ZoneType::Battlefield)
80 .into_iter()
81 .filter(|&cid| game.card(cid).is_creature())
82 .collect()
83 }
84
85 pub fn filter<F>(&self, predicate: F) -> Self
86 where
87 F: Fn(PlayerId) -> bool,
88 {
89 Self(
90 self.0
91 .iter()
92 .copied()
93 .filter(|&pid| predicate(pid))
94 .collect(),
95 )
96 }
97
98 pub fn min<F>(&self, score: F) -> Option<PlayerId>
99 where
100 F: Fn(PlayerId) -> i32,
101 {
102 self.0.iter().copied().min_by_key(|&pid| score(pid))
103 }
104
105 pub fn max<F>(&self, score: F) -> Option<PlayerId>
106 where
107 F: Fn(PlayerId) -> i32,
108 {
109 self.0.iter().copied().max_by_key(|&pid| score(pid))
110 }
111
112 pub fn sum<F>(&self, score: F) -> i32
113 where
114 F: Fn(PlayerId) -> i32,
115 {
116 self.0.iter().copied().map(score).sum()
117 }
118}