use std::ops::{Add, Div, Sub}; #[derive(Clone, Copy, Debug, PartialEq)] pub struct P2 { pub x: T, pub y: T, } impl P2 { pub fn new(x: T, y: T) -> Self { Self { x, y } } } impl> Add> for P2 { type Output = P2<::Output>; fn add(self, rhs: V2) -> Self::Output { P2::new(self.x + rhs.x, self.y + rhs.y) } } impl> Sub> for P2 { type Output = V2<::Output>; fn sub(self, rhs: P2) -> Self::Output { V2::new(self.x - rhs.x, self.y - rhs.y) } } impl> Sub> for P2 { type Output = P2<::Output>; fn sub(self, rhs: V2) -> Self::Output { P2::new(self.x - rhs.x, self.y - rhs.y) } } impl> Div for P2 { type Output = P2<::Output>; fn div(self, rhs: T) -> Self::Output { P2::new(self.x / rhs, self.y / rhs) } } #[derive(Clone, Copy, Debug)] pub struct V2 { pub x: T, pub y: T, } impl V2 { pub fn new(x: T, y: T) -> Self { Self { x, y } } } impl> Div for V2 { type Output = V2<::Output>; fn div(self, rhs: T) -> Self::Output { V2::new(self.x / rhs, self.y / rhs) } } #[derive(Clone)] pub struct Grid { pub dims: V2, elements: Vec, } impl Grid { pub fn from_fn(width: usize, height: usize, mut f: impl FnMut(usize, usize) -> T) -> Self { let mut elements = Vec::new(); for y in 0..height { for x in 0..width { elements.push(f(x, y)); } } Self { dims: V2::new(width, height), elements, } } pub fn get(&self, index: P2) -> Option<&T> { self.valid_index(index).map(|index| &self.elements[index]) } pub fn get_mut(&mut self, index: P2) -> Option<&mut T> { self.valid_index(index) .map(|index| &mut self.elements[index]) } fn valid_index(&self, index: P2) -> Option { if index.x >= 0 && (index.x as usize) < self.dims.x && index.y >= 0 && (index.y as usize) < self.dims.y { Some((index.y as usize) * self.dims.x + (index.x as usize)) } else { None } } }