use glam::IVec2; use protocol::Direction; use serde::Deserialize; use std::{collections::HashMap, net::SocketAddr, ops::ControlFlow}; pub mod protocol; pub mod server; #[derive(Deserialize)] pub struct Config { bind: SocketAddr, } pub struct Game { pub heads: HashMap, pub map: HashMap, pub size: IVec2, pub dead: Vec, } impl Game { pub fn new(players: Vec) -> Self { let mut map = HashMap::new(); let mut heads = HashMap::new(); let plen = players.len(); for (p, name) in players.into_iter().enumerate() { let pos = IVec2::ONE * p as i32 * 2; map.insert(pos, p as u32); heads.insert(p as u32, (Direction::Up, pos, name)); } Self { size: IVec2::ONE * plen as i32 * 2, heads, map, dead: Vec::new(), } } pub fn tick(&mut self) -> ControlFlow, ()> { for (_player, (dir, head, _)) in &mut self.heads { *head = (*head + dir.vector()).rem_euclid(self.size) } self.dead.clear(); let mut h = HashMap::>::new(); for (player, (_, head, _)) in &self.heads { h.entry(*head).or_default().push(*player); if self.map.contains_key(head) { self.dead.push(*player); } } for (_, hp) in h { if hp.len() > 1 { self.dead.extend(hp) } } for (player, (_, head, _)) in &mut self.heads { self.map.insert(*head, *player); } for d in &self.dead { self.map.retain(|_, p| *d != *p); self.heads.remove(&d); } if self.heads.len() <= 1 { ControlFlow::Break(self.heads.keys().next().cloned()) } else { ControlFlow::Continue(()) } } }