use crate::core::{PALACE_NAMES, PalaceName};
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PalaceRelationKind {
Opposite,
Triad,
Adjacent,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct PalaceRelation {
source: PalaceName,
target: PalaceName,
kind: PalaceRelationKind,
}
impl PalaceRelation {
pub const fn new(source: PalaceName, target: PalaceName, kind: PalaceRelationKind) -> Self {
Self {
source,
target,
kind,
}
}
pub const fn source(&self) -> PalaceName {
self.source
}
pub const fn target(&self) -> PalaceName {
self.target
}
pub const fn kind(&self) -> PalaceRelationKind {
self.kind
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct PalaceRelations {
target: PalaceName,
opposite: PalaceName,
triad: [PalaceName; 2],
adjacent: [PalaceName; 2],
}
impl PalaceRelations {
pub fn for_palace(target: PalaceName) -> Self {
Self {
target,
opposite: target.offset(6),
triad: [target.offset(4), target.offset(8)],
adjacent: [target.offset(-1), target.offset(1)],
}
}
pub const fn target(&self) -> PalaceName {
self.target
}
pub const fn opposite(&self) -> PalaceName {
self.opposite
}
pub const fn triad(&self) -> [PalaceName; 2] {
self.triad
}
pub const fn adjacent(&self) -> [PalaceName; 2] {
self.adjacent
}
pub const fn to_relations(&self) -> [PalaceRelation; 5] {
[
PalaceRelation::new(self.target, self.opposite, PalaceRelationKind::Opposite),
PalaceRelation::new(self.target, self.triad[0], PalaceRelationKind::Triad),
PalaceRelation::new(self.target, self.triad[1], PalaceRelationKind::Triad),
PalaceRelation::new(self.target, self.adjacent[0], PalaceRelationKind::Adjacent),
PalaceRelation::new(self.target, self.adjacent[1], PalaceRelationKind::Adjacent),
]
}
}
pub fn all_palace_relations() -> [PalaceRelations; 12] {
PALACE_NAMES.map(PalaceRelations::for_palace)
}