|
|
@@ -5,15 +5,17 @@ extern crate serde_json;
|
|
|
use std::io::BufWriter;
|
|
|
use std::io::BufReader;
|
|
|
use std::fs::File;
|
|
|
-use std::ops::{Add, Sub, Div};
|
|
|
+// use std::ops::{Add, Sub, Div};
|
|
|
+use std::ops::{Add, Mul};
|
|
|
use std::collections::HashMap;
|
|
|
-// use nalgebra::Vector3;
|
|
|
#[macro_use] extern crate log;
|
|
|
extern crate simplelog;
|
|
|
use simplelog::*;
|
|
|
+use std::fmt;
|
|
|
+use rand::seq::SliceRandom;
|
|
|
|
|
|
|
|
|
-#[derive(Clone, Debug, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)]
|
|
|
+#[derive(Clone, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)]
|
|
|
struct V3 {
|
|
|
x: i32,
|
|
|
y: i32,
|
|
|
@@ -50,6 +52,14 @@ impl V3 {
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+impl fmt::Debug for V3 {
|
|
|
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
+ write!(f, "V[{},{},{}]", self.x, self.y, self.z)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl Add<V3> for V3 {
|
|
|
type Output = V3;
|
|
|
fn add(self, other: V3) -> V3 {
|
|
|
@@ -72,6 +82,17 @@ impl Add<i32> for V3 {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl Mul<i32> for V3 {
|
|
|
+ type Output = V3;
|
|
|
+ fn mul(self, other: i32) -> V3 {
|
|
|
+ V3 {
|
|
|
+ x: self.x * other,
|
|
|
+ y: self.y * other,
|
|
|
+ z: self.z * other,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl<'a, 'b> Add<&'b V3> for &'a V3 {
|
|
|
type Output = V3;
|
|
|
|
|
|
@@ -84,6 +105,18 @@ impl<'a, 'b> Add<&'b V3> for &'a V3 {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl<'a> Mul<i32> for &'a V3 {
|
|
|
+ type Output = V3;
|
|
|
+
|
|
|
+ fn mul(self, other: i32) -> V3 {
|
|
|
+ V3 {
|
|
|
+ x: self.x * other,
|
|
|
+ y: self.y * other,
|
|
|
+ z: self.z * other,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// impl Sub<V3> for V3 {
|
|
|
// type Output = V3;
|
|
|
// fn sub(self, other: V3) -> V3 {
|
|
|
@@ -121,9 +154,12 @@ fn unitized_grid(vol: &HashMap<V3, String>, divisor: i32) -> HashMap<V3, String>
|
|
|
|
|
|
|
|
|
fn guess_gridsize(vol: &HashMap<V3, String>) -> i32{
|
|
|
- let mut x_positions: Vec<i32> = vol.iter().map(|(k,v)| k.x).collect();
|
|
|
+ let mut x_positions: Vec<i32> = vol.iter().map(|(k, _v)| k.x).collect();
|
|
|
+ let mut y_positions: Vec<i32> = vol.iter().map(|(k, _v)| k.y).collect();
|
|
|
x_positions.sort();
|
|
|
x_positions.dedup();
|
|
|
+ y_positions.sort();
|
|
|
+ y_positions.dedup();
|
|
|
let mut dist_count: HashMap<i32, i32> = HashMap::new();
|
|
|
let mut last: Option<i32> = None;
|
|
|
for px in x_positions {
|
|
|
@@ -187,14 +223,14 @@ fn load_export(path: &'static str) -> HashMap<V3, String> {
|
|
|
}
|
|
|
|
|
|
|
|
|
-fn get_adjacent_tiles(grid: &HashMap<V3, String>, training_data: &HashMap<String, HashMap<V3, Vec<String>>>) -> HashMap<V3, String> {
|
|
|
- let mut adjacents: HashMap<V3, String> = HashMap::new();
|
|
|
+// fn get_adjacent_tiles(grid: &HashMap<V3, String>, training_data: &HashMap<String, HashMap<V3, Vec<String>>>) -> HashMap<V3, String> {
|
|
|
+// let mut adjacents: HashMap<V3, String> = HashMap::new();
|
|
|
|
|
|
- for (pos, tile) in grid {
|
|
|
+// for (pos, tile) in grid {
|
|
|
|
|
|
- }
|
|
|
- adjacents
|
|
|
-}
|
|
|
+// }
|
|
|
+// adjacents
|
|
|
+// }
|
|
|
|
|
|
fn get_unsolved_neighbors(cell: &V3, grid: &HashMap<V3, String>) -> Vec<V3> {
|
|
|
let mut neighbors = vec![];
|
|
|
@@ -209,21 +245,35 @@ fn get_unsolved_neighbors(cell: &V3, grid: &HashMap<V3, String>) -> Vec<V3> {
|
|
|
|
|
|
|
|
|
|
|
|
-fn wfc_solver(training_data: HashMap<String, HashMap<V3, Vec<String>>>) -> HashMap<V3, String> {
|
|
|
- let mut new_grid: HashMap<V3, String> = HashMap::new();
|
|
|
+fn wfc_solver(training_data: &HashMap<String, HashMap<V3, Vec<String>>>, base_map: HashMap<V3, String>) -> HashMap<V3, String> {
|
|
|
+ let mut new_grid = base_map;
|
|
|
|
|
|
- // init start conditions
|
|
|
- new_grid.insert(V3::new(10, 0, 0), String::from("grass"));
|
|
|
|
|
|
- for (pos, name) in &new_grid {
|
|
|
- for unsolved_neighbor in get_unsolved_neighbors(pos, &new_grid) {
|
|
|
- println!("Solving {:?} (next to {})", unsolved_neighbor, name);
|
|
|
- let trained_data_for_this_tile = training_data.get(name).unwrap();
|
|
|
+
|
|
|
+ for (pos, name) in new_grid.clone() {
|
|
|
+ for unsolved_neighbor in get_unsolved_neighbors(&pos, &new_grid) {
|
|
|
+ for tile_neighbor in &unsolved_neighbor.offsets() {
|
|
|
+ if let Some(tn) = new_grid.get(&(&unsolved_neighbor+tile_neighbor)) {
|
|
|
+ if let Some(constraints) = training_data.get(tn).unwrap().get(tile_neighbor) {
|
|
|
+ // println!("\t{} points to me, accepts {:?}", tn, constraints);
|
|
|
+ println!("Solving {:?} - looking into neighbors", unsolved_neighbor);
|
|
|
+ let cs = constraints.choose(&mut rand::thread_rng()).unwrap();
|
|
|
+ println!("\tchose {:?}", cs);
|
|
|
+ new_grid.insert(unsolved_neighbor, cs.to_string());
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // println!("Training data: {:?}", trained_data_for_this_tile);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
+ println!("grid: {:?}", new_grid);
|
|
|
|
|
|
new_grid
|
|
|
}
|
|
|
@@ -255,13 +305,25 @@ fn main() {
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
- let new_grid: HashMap<V3, String> = HashMap::new();
|
|
|
-
|
|
|
- wfc_solver(training_data);
|
|
|
+ // let new_grid: HashMap<V3, String> = HashMap::new();
|
|
|
+ let mut base_map: HashMap<V3, String> = HashMap::new();
|
|
|
+ // init start conditions
|
|
|
+ base_map.insert(V3::new(10, 0, 0), String::from("grass"));
|
|
|
+
|
|
|
+ base_map = wfc_solver(&training_data, base_map);
|
|
|
+ base_map = wfc_solver(&training_data, base_map);
|
|
|
+ base_map = wfc_solver(&training_data, base_map);
|
|
|
|
|
|
// dbg!(&vol);
|
|
|
// let mut adj_map: HashMap<String, Adjacency> = HashMap::new();
|
|
|
|
|
|
+ let mut export = vec![];
|
|
|
+ for (p, n) in &base_map {
|
|
|
+ export.push((p*gridsize,n));
|
|
|
+ }
|
|
|
+ let writer = BufWriter::new(File::create("map.json").unwrap());
|
|
|
+ serde_json::to_writer_pretty(writer, &export).unwrap();
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|