use crate::hex::*;
#[cfg(feature = "bevy")]
use bevy_ecs::prelude::Component;
#[cfg(feature = "bevy")]
use bevy_reflect::Reflect;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::hash::Hash;
pub trait Edge: Into<EdgeAx> + From<EdgeAx> + Hash + Eq + Copy {
fn between<T>(a: &T, b: &T) -> Self
where
T: Hex,
{
if a.dist(b) > 1 {
panic!("Cannot have edge between non-neighbouring hexes.");
} else {
let (a_ax, b_ax): (HexAx, HexAx) = ((*a).into(), (*b).into());
EdgeAx::new(a_ax.q + b_ax.q, a_ax.r + b_ax.r).into()
}
}
}
#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash, Default)]
#[cfg_attr(feature = "bevy", derive(Reflect, Component))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EdgeAx {
pub q: isize,
pub r: isize,
}
impl EdgeAx {
pub fn new(q: isize, r: isize) -> Self {
EdgeAx { q, r }
}
}
impl Edge for EdgeAx {}
#[derive(PartialEq, Debug, Copy, Clone, Default)]
#[cfg_attr(feature = "bevy", derive(Reflect, Component))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct FEdgeAx {
pub q: f32,
pub r: f32,
}
impl FEdgeAx {
pub fn new(q: f32, r: f32) -> Self {
FEdgeAx { q, r }
}
}
#[cfg(test)]
mod test {
use std::collections::HashSet;
use super::*;
use crate::{
hex_range::*,
neighbours::{Edges, Hexes},
};
#[test]
fn edges_are_reversible_cases() {
for c in HexRange::sphere(&HexCb::new(0, 0, 0), 5).compute() {
check_edge_reversibility(c);
}
}
fn check_edge_reversibility(center: HexAx) {
for n in center.hexes() {
let e = EdgeAx::between(¢er, &n);
let hexes: HashSet<HexAx> = e.hexes().collect();
assert_eq!(hexes.len(), 2);
assert!(hexes.contains(¢er));
assert!(hexes.contains(&n));
}
}
#[test]
fn face_has_6_edges() {
assert_eq!(HexAx::new(0, 0).edges().count(), 6);
}
#[test]
fn sphere_r_1_has_30_edges() {
assert_eq!(
HexRange::sphere(&HexAx::new(0, 0), 1)
.compute::<HexAx>()
.iter()
.flat_map(|hf| hf.edges().into_iter())
.collect::<HashSet<EdgeAx>>()
.len(),
30
);
}
#[test]
fn sphere_r_2_has_72_edges() {
assert_eq!(
HexRange::sphere(&HexCb::new(0, 0, 0), 2)
.compute::<HexAx>()
.iter()
.flat_map(|hf| hf.edges().into_iter())
.collect::<HashSet<EdgeAx>>()
.len(),
72
);
}
#[test]
fn edge_neighbours_touch_4_hexes() {
let x = HexAx::new(1, 2);
for e in x.edges() {
let hs: HashSet<HexAx> = e
.edges()
.flat_map(|en| en.hexes().collect::<Vec<HexAx>>())
.collect();
assert_eq!(hs.len(), 4);
}
}
}