summaryrefslogtreecommitdiff
path: root/dungeon/src/wfc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'dungeon/src/wfc.rs')
-rw-r--r--dungeon/src/wfc.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/dungeon/src/wfc.rs b/dungeon/src/wfc.rs
new file mode 100644
index 0000000..5968000
--- /dev/null
+++ b/dungeon/src/wfc.rs
@@ -0,0 +1,100 @@
+//! The `wfc` module contains the implementation of the
+//! Wave Function Collapse algorithm for procedural generation of the `Floor`.
+
+use crate::map::Tile;
+use crate::pos::Pos;
+
+/// The `State` struct represents each possible state of a tile in the WFC algorithm.
+pub(crate) struct State {
+ /// Position of the tile
+ pos: Pos,
+ /// Possible tiles for this state
+ possible_tiles: Vec<Tile>,
+ /// Entropy of the state
+ entropy: f32,
+}
+
+impl State {
+ /// Creates a new State instance
+ pub fn new(pos: Pos, possible_tiles: Vec<Tile>) -> Self {
+ let entropy = 0.0;
+ Self {
+ pos,
+ possible_tiles,
+ entropy,
+ }
+ }
+
+ /// Updates the possible tiles and recalculates entropy
+ pub fn update_possible_tiles(&mut self, possible_tiles: Vec<Tile>) {
+ self.possible_tiles = possible_tiles;
+ self.entropy = self.entropy();
+ }
+
+ /// Calculates the entropy of the state
+ /// TODO: Implement shannon entropy calculation
+ pub fn entropy(&self) -> f32 {
+ self.possible_tiles.len() as f32
+ }
+}
+
+/// The `Wfc` struct encapsulates the Wave Function Collapse algorithm.
+pub struct Wfc {
+ /// The seed used for randomness in the algorithm
+ seed: u64,
+ /// The size of the map to generate
+ mapsize: u16,
+ /// The current state of the WFC algorithm (smart pointer for interior mutability)
+ states: Vec<std::cell::RefCell<State>>,
+ /// The random number generator
+ rng: rand::rngs::StdRng,
+}
+
+impl Wfc {
+ /// Creates a new Wfc instance with the given seed and map size
+ pub fn new(seed: u64, mapsize: u16) -> Self {
+ let rng = rand::SeedableRng::seed_from_u64(seed);
+ Self {
+ seed,
+ mapsize,
+ states: Vec::with_capacity(mapsize as usize),
+ rng,
+ }
+ }
+
+ /// Initializes the states vector with default states
+ pub fn initialize_states(&mut self) {
+
+ for pos in Pos::values() {
+ let possible_tiles = Tile::all_tiles();
+ let state = State::new(pos, possible_tiles);
+ self.states.push(std::cell::RefCell::new(state));
+
+ }
+ }
+
+ /// Runs the Wave Function Collapse algorithm to generate the map
+ pub fn run(&mut self) {
+ // ----- Step 1: Read in input sample and define constraints -----
+ // TODO: add support for sample image input
+
+ // ----- Step 2: Initialize the grid of possible states -----
+
+ // Start with an empty box of tiles
+
+ // Store a superposition of all possible tiles for each position
+
+ // ----- Step 3: Collapse the superpositions -----
+ // Calculate the shannon entropy of all superpositions
+ // Collapse the tile with the lowest entropy
+ // (Assign a seeded random superposition)
+
+ // ----- Step 4: Propogate -----
+ // Update neighboring superpositions based on the collapsed tile
+ // (Remove any that violate constraints)
+
+ // ----- Step 5: Repeat until all superpositions are collapsed -----
+ // If any tiles are left with no possible states, restart
+ // TODO: backtrack
+ }
+}