#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)]
pub struct Axial (pub i8, pub i8);

impl Into<Cube> for Axial {
  fn into(self) -> Cube {
    Cube(self.0, self.1, -self.0 - self.1)
  }
}

#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)]
pub struct Cube (pub i8, pub i8, pub i8);

impl Into<Axial> for Cube {
  fn into(self) -> Axial {
    Axial(self.0, self.1)
  }
}

#[cfg(test)]
mod test {
  use super::*;
  use crate::neighbours::*;
  use crate::distance::*;

  #[test]
  fn coords_of_cube_sum_to_0() {
    let x = Cube(0, 0, 0);

    // Compute the neighbours.
    let neighbours: Vec<Cube> = x.neighbours().collect();

    // There should be six of those.
    assert_eq!(neighbours.len(), 6);

    // They should all...
    for (i, y) in neighbours.iter().enumerate() {
      // ...sum to zero
      assert_eq!(y.0 + y.1 + y.2, 0);
      // ...be unequal to the origin
      assert_ne!(*y, x);
      // ...have distance 1 to the origin
      assert_eq!(y.dist(&x), 1);
      // ...and be unequal to all others
      for z in neighbours[i + 1..].iter() {
        assert_ne!(*y, *z);
      }
    }
  }
}
