diff --git a/README.md b/README.md index f4bcab8..e4944b1 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,3 @@ Trait for a struct that holds spatial data ### Ruleset Trait for a ruleset - -### Node - -Trait for any data that diff --git a/src/lib.rs b/src/lib.rs index e62c9aa..42d9e67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,13 +15,30 @@ pub trait GraphLike { fn iter_empty(&self) -> impl Iterator where NodeId: Copy { self.iter_ids().filter(|id| self.get_node(*id).is_none()) } - fn iter_neighbour_nodes(&self, id: NodeId) -> Vec<(NodeId, Option<&Node>)> where NodeId: Copy { self.iter_neighbor_ids(id).map(|id| (id, self.get_node(id))).collect() } + + /// TODO: Replace return type with a result that explains the reason for failure. This could + /// help with rollback to recover from impossible generation + fn collapse_one(&mut self, rules: &impl Ruleset) -> Option where NodeId: Copy, Self: Sized { + let id = rules.find_lowest_entropy(self)?; + rules.choose(self, id); + None + } } pub trait Ruleset { - fn entropy(&self, graph: &impl GraphLike, id: NodeId) -> f32 where NodeId: Copy; + fn entropy(&self, graph: &impl GraphLike, id: NodeId) -> Option where NodeId: Copy; fn choose(&self, graph: &impl GraphLike, id: NodeId) -> Node where NodeId: Copy; + + fn find_lowest_entropy(&self, graph: &impl GraphLike) -> Option where NodeId: Copy { + graph.iter_empty() + .map(|id| (id, self.entropy(graph, id))) + // Option apparently implements PartialOrd + // None is considered smaller than any Some value + // This works out, since we want to find impossible nodes (entropy returns None) + .min_by(|a, b| a.1.partial_cmp(&b.1).unwrap()) + .map(|(id, _)| id) + } }