1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
use glam::IVec2;
use map::Map;
use protocol::Direction;
use serde::Deserialize;
use std::{collections::HashMap, net::SocketAddr, ops::ControlFlow};
pub mod map;
pub mod protocol;
pub mod server;
#[derive(Deserialize, Clone)]
pub struct Config {
bind: SocketAddr,
tickrate: f32,
tickrate_speedup: f32,
tickrate_max: f32,
}
pub struct Game {
pub heads: HashMap<u32, (Direction, IVec2, String)>,
pub map: Map,
pub dead: Vec<u32>,
}
impl Game {
pub fn new(players: Vec<(u32, String)>) -> Self {
let mut map = Map::new(players.len() * 2, players.len() * 2);
let mut heads = HashMap::new();
for (i, (p, name)) in players.into_iter().enumerate() {
let pos = IVec2::ONE * i as i32 * 2;
map[pos] = Some(p);
heads.insert(p, (Direction::Up, pos, name));
}
Self {
heads,
map,
dead: Vec::new(),
}
}
pub fn tick(&mut self) -> ControlFlow<Option<u32>, ()> {
for (_player, (dir, head, _)) in &mut self.heads {
*head = (*head + dir.vector()).rem_euclid(self.map.size)
}
self.dead.clear();
let mut h = HashMap::<IVec2, Vec<u32>>::new();
for (player, (_, head, _)) in &self.heads {
h.entry(*head).or_default().push(*player);
if self.map[*head].is_some() {
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[*head] = Some(*player);
}
for d in &self.dead {
self.map.clear_player(*d);
self.heads.remove(&d);
}
if self.heads.len() <= 1 {
ControlFlow::Break(self.heads.keys().next().cloned())
} else {
ControlFlow::Continue(())
}
}
}
|