use std::hash::Hash;
#[cfg(feature = "bevy")]
use bevy_ecs::prelude::Component;
#[cfg(feature = "bevy")]
use bevy_reflect::Reflect;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub trait Node: Into<NodeAx> + From<NodeAx> + Hash + Eq + Copy {}
#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash, Default)]
#[cfg_attr(feature = "bevy", derive(Reflect, Component))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct NodeAx {
pub q: isize,
pub r: isize,
}
impl NodeAx {
pub fn new(q: isize, r: isize) -> Self {
NodeAx { q, r }
}
}
impl Node for NodeAx {}
#[derive(PartialEq, Debug, Copy, Clone, Default)]
#[cfg_attr(feature = "bevy", derive(Reflect, Component))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct FNodeAx {
pub q: f32,
pub r: f32,
}
impl FNodeAx {
pub fn new(q: f32, r: f32) -> Self {
FNodeAx { q, r }
}
}
impl From<&NodeAx> for FNodeAx {
fn from(value: &NodeAx) -> Self {
FNodeAx::new(value.q as f32, value.r as f32)
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::{edge::*, hex::*, hex_range::*, neighbours::*};
use std::collections::HashSet;
#[test]
fn neighbouring_edges_share_node_cases() {
for hex in HexRange::sphere(&HexAx::new(0, 0), 2).compute::<HexAx>() {
for e in hex.edges() {
verify_neighbouring_edge_share_node(&e);
}
}
}
fn verify_neighbouring_edge_share_node(e: &EdgeAx) {
let my_nodes = e.nodes().into_iter().collect::<HashSet<NodeAx>>();
for n in e.edges() {
assert_eq!(
my_nodes
.intersection(&n.nodes().collect::<HashSet<NodeAx>>())
.collect::<HashSet<&NodeAx>>()
.len(),
1
);
}
}
#[test]
fn hex_has_6_nodes_which_each_have_3_hexes_including_the_aforementioned_hex() {
for hex in HexRange::sphere(&HexAx::new(0, 0), 3).compute::<HexAx>() {
let nodes = hex.nodes();
assert_eq!(nodes.count(), 6);
for node in hex.nodes() {
let hexes: HashSet<HexAx> = node.hexes().collect();
assert_eq!(hexes.len(), 3);
assert!(hexes.contains(&hex));
}
}
}
#[test]
fn hex_nodes_each_touch_2_edges_that_touch_the_aforementioned_hex() {
for hex in HexRange::sphere(&HexAx::new(0, 0), 3).compute::<HexAx>() {
let hex_edges: HashSet<EdgeAx> = hex.edges().collect();
let nodes = hex.nodes();
for node in nodes {
let edges: HashSet<EdgeAx> = node.edges().collect();
assert_eq!(edges.len(), 3);
assert_eq!(
edges
.intersection(&hex_edges)
.collect::<HashSet<&EdgeAx>>()
.len(),
2
);
}
}
}
}