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
use std::convert::TryInto; use crate::coords::{Axial, Cube}; pub trait Distance { /// Return the grid distance from `self` to `other`. fn dist(&self, other: &Self) -> u8; } // Implementations can be simplified once this lands in stable: // https://github.com/rust-lang/rust/issues/74913 impl Distance for Cube { /// ``` /// use bestagon::{coords::Cube, distance::Distance}; /// assert_eq!(Cube(0, 4, -4).dist(&Cube(1, 2, -3)), 2); /// assert_eq!(Cube(-3, 2, 1).dist(&Cube(3, -1, -2)), 6); /// assert_eq!(Cube(-4, 4, 0).dist(&Cube(4, -4, 0)), 8); /// ``` fn dist(&self, other: &Cube) -> u8 { // https://www.redblobgames.com/grids/hexagons/#distances-cube (((other.0 - self.0).abs() + (other.1 - self.1).abs() + (other.2 - self.2).abs()) / 2) .try_into().unwrap() } } impl Distance for Axial { /// ``` /// use bestagon::{coords::Axial, distance::Distance}; /// assert_eq!(Axial(0, 4).dist(&Axial(1, 2)), 2); /// assert_eq!(Axial(-3, 2).dist(&Axial(3, -1)), 6); /// ``` fn dist(&self, other: &Axial) -> u8 { // Simply convert to Cube and use that implementation. // Could be improved by manually calculating but this is easier. let self_c: Cube = (*self).into(); let other_c: Cube = (*other).into(); self_c.dist(&other_c) } }