use super::*;
#[derive(Clone, Copy, Debug)]
pub struct Sweeping {
pub crab: Crab,
pub owner: PlayerId,
pub launch: u64,
pub lands: u64,
pub claw_call: bool,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(super) struct Swept {
pub(super) crab: u32,
pub(super) owner: PlayerId,
pub(super) at: u64,
pub(super) points: i32,
}
pub const SWEEP_MEMORY: u64 = 64;
#[derive(Clone, Debug, Default)]
pub(super) struct Sweeps {
pub(super) in_air: Vec<Sweeping>,
pub(super) landed: Vec<Swept>,
}
impl Sweeps {
pub(super) fn launch(&mut self, flight: Sweeping) {
self.in_air.push(flight);
}
pub(super) fn forget_before(&mut self, tick: u64) {
self.landed.retain(|swept| swept.at + SWEEP_MEMORY > tick);
}
fn lookup(&self, crab: u32) -> Option<&Swept> {
self.landed.iter().find(|swept| swept.crab == crab)
}
pub(super) fn copy_from(&mut self, other: &Self) {
let Self { in_air, landed } = other;
refill(&mut self.in_air, in_air);
refill(&mut self.landed, landed);
}
}
impl Board {
pub(super) fn land_sweeps(&mut self) {
if self.sweeps.in_air.is_empty() {
return;
}
let tick = self.tick;
let last = self
.rules
.round_length
.is_some_and(|len| tick + 1 >= u64::from(len));
let mut i = 0;
while i < self.sweeps.in_air.len() {
if !last && self.sweeps.in_air[i].lands > tick {
i += 1;
continue;
}
let Sweeping {
crab,
owner,
claw_call,
..
} = self.sweeps.in_air.remove(i);
let claw_call = match self.rules.sweep_keeps_worth {
true => claw_call,
false => self.in_claw_call(),
};
self.bank_swept(owner, &crab, claw_call);
}
}
pub(super) fn bank_swept(&mut self, owner: PlayerId, crab: &Crab, claw_call: bool) {
let points = self.credit_bank_under(owner, crab, claw_call);
self.sweeps.landed.push(Swept {
crab: crab.id,
owner,
at: self.tick,
points,
});
}
pub fn sweeping(&self) -> &[Sweeping] {
&self.sweeps.in_air
}
pub fn swept_home(&self, crab: u32) -> Option<PlayerId> {
self.sweeps.lookup(crab).map(|swept| swept.owner)
}
pub fn swept_paid(&self, crab: u32) -> Option<i32> {
self.sweeps.lookup(crab).map(|swept| swept.points)
}
}