use crate::components::Cell;
use bevy::prelude::{Component, IVec2};
use std::ops::Deref;
const NEIGHBOR_COORDINATES: [IVec2; 8] = [
IVec2::new(-1, 0),
IVec2::new(-1, 1),
IVec2::new(0, 1),
IVec2::new(1, 1),
IVec2::new(1, 0),
IVec2::new(1, -1),
IVec2::new(0, -1),
IVec2::new(-1, -1),
];
#[derive(Debug, Clone, Component)]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
pub struct MooreCell2d {
pub coords: IVec2,
}
impl Deref for MooreCell2d {
type Target = IVec2;
fn deref(&self) -> &Self::Target {
&self.coords
}
}
impl Cell for MooreCell2d {
type Coordinates = IVec2;
#[inline]
fn coords(&self) -> &Self::Coordinates {
&self.coords
}
#[inline]
fn neighbor_coordinates(&self) -> impl ExactSizeIterator<Item = Self::Coordinates> + '_ {
NEIGHBOR_COORDINATES.map(|c| c + *self.coords()).into_iter()
}
}
impl MooreCell2d {
#[must_use]
#[inline]
pub const fn new(coords: IVec2) -> Self {
Self { coords }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn correct_coordinates() {
let cell = MooreCell2d {
coords: IVec2::new(10, 10),
};
let neighbors = cell.neighbor_coordinates().collect::<Vec<_>>();
assert_eq!(
neighbors,
vec![
IVec2::new(9, 10),
IVec2::new(9, 11),
IVec2::new(10, 11),
IVec2::new(11, 11),
IVec2::new(11, 10),
IVec2::new(11, 9),
IVec2::new(10, 9),
IVec2::new(9, 9),
]
);
}
#[test]
fn correct_coordinates_negative() {
let cell = MooreCell2d {
coords: IVec2::new(-10, 10),
};
let neighbors = cell.neighbor_coordinates().collect::<Vec<_>>();
assert_eq!(
neighbors,
vec![
IVec2::new(-11, 10),
IVec2::new(-11, 11),
IVec2::new(-10, 11),
IVec2::new(-9, 11),
IVec2::new(-9, 10),
IVec2::new(-9, 9),
IVec2::new(-10, 9),
IVec2::new(-11, 9),
]
);
}
#[test]
fn correct_coordinates_origin() {
let cell = MooreCell2d {
coords: IVec2::new(0, 0),
};
let neighbors = cell.neighbor_coordinates().collect::<Vec<_>>();
assert_eq!(
neighbors,
vec![
IVec2::new(-1, 0),
IVec2::new(-1, 1),
IVec2::new(0, 1),
IVec2::new(1, 1),
IVec2::new(1, 0),
IVec2::new(1, -1),
IVec2::new(0, -1),
IVec2::new(-1, -1),
]
);
}
}