11 use std::{collections::HashMap, iter}; |
11 use std::{collections::HashMap, iter}; |
12 |
12 |
13 pub const MAX_TEAMS_IN_ROOM: u8 = 8; |
13 pub const MAX_TEAMS_IN_ROOM: u8 = 8; |
14 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM; |
14 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM; |
15 |
15 |
16 fn client_teams_impl( |
|
17 teams: &[(ClientId, TeamInfo)], |
|
18 client_id: ClientId, |
|
19 ) -> impl Iterator<Item = &TeamInfo> + Clone { |
|
20 teams |
|
21 .iter() |
|
22 .filter(move |(id, _)| *id == client_id) |
|
23 .map(|(_, t)| t) |
|
24 } |
|
25 |
|
26 pub struct GameInfo { |
16 pub struct GameInfo { |
27 pub teams_in_game: u8, |
|
28 pub teams_at_start: Vec<(ClientId, TeamInfo)>, |
|
29 pub left_teams: Vec<String>, |
17 pub left_teams: Vec<String>, |
30 pub msg_log: Vec<String>, |
18 pub msg_log: Vec<String>, |
31 pub sync_msg: Option<String>, |
19 pub sync_msg: Option<String>, |
32 pub is_paused: bool, |
20 pub is_paused: bool, |
33 config: RoomConfig, |
21 config: RoomConfig, |
38 GameInfo { |
26 GameInfo { |
39 left_teams: Vec::new(), |
27 left_teams: Vec::new(), |
40 msg_log: Vec::new(), |
28 msg_log: Vec::new(), |
41 sync_msg: None, |
29 sync_msg: None, |
42 is_paused: false, |
30 is_paused: false, |
43 teams_in_game: teams.len() as u8, |
|
44 teams_at_start: teams, |
|
45 config, |
31 config, |
46 } |
32 } |
47 } |
|
48 |
|
49 pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone { |
|
50 client_teams_impl(&self.teams_at_start, client_id) |
|
51 } |
33 } |
52 } |
34 } |
53 |
35 |
54 #[derive(Serialize, Deserialize)] |
36 #[derive(Serialize, Deserialize)] |
55 pub struct RoomSave { |
37 pub struct RoomSave { |
142 &self.teams.last().unwrap().1 |
124 &self.teams.last().unwrap().1 |
143 } |
125 } |
144 |
126 |
145 pub fn remove_team(&mut self, team_name: &str) { |
127 pub fn remove_team(&mut self, team_name: &str) { |
146 if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) { |
128 if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) { |
147 self.teams.remove(index); |
|
148 |
|
149 if let Some(info) = &mut self.game_info { |
129 if let Some(info) = &mut self.game_info { |
150 info.left_teams.push(team_name.to_string()); |
130 info.left_teams.push(team_name.to_string()); |
151 info.teams_in_game -= 1; |
|
152 |
131 |
153 if let Some(m) = &info.sync_msg { |
132 if let Some(m) = &info.sync_msg { |
154 info.msg_log.push(m.clone()); |
133 info.msg_log.push(m.clone()); |
155 info.sync_msg = None |
134 info.sync_msg = None |
156 } |
135 } |
157 let remove_msg = |
136 let remove_msg = |
158 crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes())); |
137 crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes())); |
159 info.msg_log.push(remove_msg.clone()); |
138 info.msg_log.push(remove_msg.clone()); |
|
139 } else { |
|
140 self.teams.remove(index); |
160 } |
141 } |
161 } |
142 } |
162 } |
143 } |
163 |
144 |
164 pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> { |
145 pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> { |
165 let mut names = Vec::new(); |
146 let mut names = Vec::new(); |
166 let teams = match self.game_info { |
147 let teams = &mut self.teams; |
167 Some(ref mut info) => &mut info.teams_at_start, |
|
168 None => &mut self.teams, |
|
169 }; |
|
170 |
|
171 if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM { |
148 if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM { |
172 for (_, team) in teams.iter_mut() { |
149 for (_, team) in teams.iter_mut() { |
173 team.hedgehogs_number = n; |
150 team.hedgehogs_number = n; |
174 names.push(team.name.clone()) |
151 names.push(team.name.clone()) |
175 } |
152 } |
176 self.default_hedgehog_number = n; |
153 self.default_hedgehog_number = n; |
177 } |
154 } |
178 names |
155 names |
179 } |
156 } |
180 |
157 |
|
158 pub fn teams_in_game(&self) -> Option<u8> { |
|
159 self.game_info |
|
160 .as_ref() |
|
161 .map(|info| (self.teams.len() - info.left_teams.len()) as u8) |
|
162 } |
|
163 |
181 pub fn find_team_and_owner_mut<F>(&mut self, f: F) -> Option<(ClientId, &mut TeamInfo)> |
164 pub fn find_team_and_owner_mut<F>(&mut self, f: F) -> Option<(ClientId, &mut TeamInfo)> |
182 where |
165 where |
183 F: Fn(&TeamInfo) -> bool, |
166 F: Fn(&TeamInfo) -> bool, |
184 { |
167 { |
185 self.teams |
168 self.teams |
195 self.teams |
178 self.teams |
196 .iter() |
179 .iter() |
197 .find_map(|(_, t)| Some(t).filter(|t| f(&t))) |
180 .find_map(|(_, t)| Some(t).filter(|t| f(&t))) |
198 } |
181 } |
199 |
182 |
200 pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> { |
183 pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone { |
201 client_teams_impl(&self.teams, client_id) |
184 self.teams |
|
185 .iter() |
|
186 .filter(move |(id, _)| *id == client_id) |
|
187 .map(|(_, t)| t) |
202 } |
188 } |
203 |
189 |
204 pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> { |
190 pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> { |
205 self.teams |
191 self.teams |
206 .iter() |
192 .iter() |