|
|
@@ -7,7 +7,7 @@ use std::io::BufReader;
|
|
|
use std::io::BufWriter;
|
|
|
// use std::ops::{Add, Sub, Div};
|
|
|
use std::collections::HashMap;
|
|
|
-use std::ops::{Add, Mul};
|
|
|
+use std::ops::{Add, Mul, Neg};
|
|
|
#[macro_use]
|
|
|
extern crate log;
|
|
|
extern crate simplelog;
|
|
|
@@ -53,7 +53,7 @@ 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)
|
|
|
+ write!(f, "V[{},{},{}]", self.x*8, self.y*8, self.z*8)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -90,6 +90,17 @@ impl Mul<i32> for V3 {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl Neg<> for V3 {
|
|
|
+ type Output = V3;
|
|
|
+ fn neg(self) -> V3 {
|
|
|
+ V3 {
|
|
|
+ x: -self.x,
|
|
|
+ y: -self.y,
|
|
|
+ z: -self.z,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
impl<'a, 'b> Add<&'b V3> for &'a V3 {
|
|
|
type Output = V3;
|
|
|
|
|
|
@@ -114,6 +125,19 @@ impl<'a> Mul<i32> for &'a V3 {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+impl<'a> Neg<> for &'a V3 {
|
|
|
+ type Output = V3;
|
|
|
+
|
|
|
+ fn neg(self) -> V3 {
|
|
|
+ V3 {
|
|
|
+ x: -self.x,
|
|
|
+ y: -self.y,
|
|
|
+ z: -self.z,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// impl Sub<V3> for V3 {
|
|
|
// type Output = V3;
|
|
|
// fn sub(self, other: V3) -> V3 {
|
|
|
@@ -243,37 +267,115 @@ fn get_unsolved_neighbors(cell: &V3, grid: &HashMap<V3, String>) -> Vec<V3> {
|
|
|
neighbors
|
|
|
}
|
|
|
|
|
|
+fn template_meets_constraints(constraint: &HashMap<V3, String>, template: &HashMap<V3, Vec<String>>) -> bool {
|
|
|
+
|
|
|
+
|
|
|
+ for (c_pos, c_name) in constraint {
|
|
|
+ // let _x = template.get(&c_pos).map(|x| x.contains(c_name));
|
|
|
+ if let Some(possible_tiles) = template.get(&c_pos) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ true
|
|
|
+}
|
|
|
+
|
|
|
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;
|
|
|
+ // let gridsize = 8;
|
|
|
|
|
|
for (pos, _name) in new_grid.clone() {
|
|
|
for unsolved_neighbor in get_unsolved_neighbors(&pos, &new_grid) {
|
|
|
println!("Unsolved {:?}", unsolved_neighbor);
|
|
|
+ let mut contraint_map: HashMap<V3, String> = HashMap::new();
|
|
|
+
|
|
|
for tile_neighbor in &unsolved_neighbor.offsets() {
|
|
|
let abs_neighbor_pos = &unsolved_neighbor + tile_neighbor;
|
|
|
|
|
|
if let Some(tn) = new_grid.get(&abs_neighbor_pos) {
|
|
|
println!("\tNeighbor {:?} exists, is {}", abs_neighbor_pos, tn);
|
|
|
// println!("\tTraining data for {} = {:?}", tn, training_data.get(tn).unwrap());
|
|
|
- let mut contraint_map: HashMap<V3, String> = HashMap::new();
|
|
|
-
|
|
|
- if let Some(constraints) = training_data.get(tn).unwrap().get(tile_neighbor) {
|
|
|
- // println!("\t{} points to me, accepts {:?}", tn, constraints);
|
|
|
- println!(
|
|
|
- "\t\tSolving {:?} - looking into neighbors",
|
|
|
- unsolved_neighbor
|
|
|
- );
|
|
|
- let cs = constraints.choose(&mut rand::thread_rng()).unwrap();
|
|
|
- println!("\t\tchose {:?}", cs);
|
|
|
- new_grid.insert(unsolved_neighbor, cs.to_string());
|
|
|
- } else {
|
|
|
- println!("\t\tNo training data in tile {} at offset {:?}", tn, tile_neighbor);
|
|
|
- }
|
|
|
+
|
|
|
+ contraint_map.insert(tile_neighbor.clone(), tn.to_string());
|
|
|
+ // if let Some(constraints) = training_data.get(tn).unwrap().get(&-tile_neighbor) {
|
|
|
+ // // println!("\t{} points to me, accepts {:?}", tn, constraints);
|
|
|
+ // println!(
|
|
|
+ // "\t\tlooking up in {} {:?}",
|
|
|
+ // tn, tile_neighbor
|
|
|
+ // );
|
|
|
+ // let cs = constraints.choose(&mut rand::thread_rng()).unwrap();
|
|
|
+ // println!("\t\tAdded a randomly chosen constraint: {:?}", cs);
|
|
|
+ // // new_grid.insert(unsolved_neighbor, cs.to_string());
|
|
|
+ // contraint_map.insert(tile_neighbor.clone(), cs.to_string());
|
|
|
+
|
|
|
+ // } else {
|
|
|
+ // // println!("\t\tNo training data in tile {} at offset {:?}", tn, tile_neighbor);
|
|
|
+ // }
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
+ // Constraint map is ready here
|
|
|
+ // println!("All constraints: {:?}", contraint_map);
|
|
|
+ let num_constraints = contraint_map.len();
|
|
|
+
|
|
|
+ println!("\tSolving {} contraints in {:?}", num_constraints, contraint_map );
|
|
|
+
|
|
|
+
|
|
|
+ //let mut compatible = 0;
|
|
|
+ for (template_name, compatible_tiles) in training_data {
|
|
|
+
|
|
|
+ //if compatible == num_constraints {break;}
|
|
|
+ println!("\t\tProbing template {:?}", template_name );
|
|
|
+ let _compat = template_meets_constraints(&contraint_map, compatible_tiles);
|
|
|
+
|
|
|
+
|
|
|
+ //new_grid.insert(unsolved_neighbor, template_tile.to_string());
|
|
|
+
|
|
|
+ // // TODO: iterate through all combos at all the constraint positions
|
|
|
+ // for (p, constraint) in &contraint_map {
|
|
|
+ // println!("\t\t\tWill {:?} {} fit?", p, constraint );
|
|
|
+ // if let Some(tiles_for_this_pos) = compatible_tiles.get(&p) {
|
|
|
+ // println!("\t\t\tAt the above pos, this is what the template offers: {:?}", tiles_for_this_pos );
|
|
|
+ // if tiles_for_this_pos.contains(&constraint) {
|
|
|
+ // compatible += 1;
|
|
|
+ // if compatible == num_constraints {
|
|
|
+ // println!("\tSolved with {}.", template_tile);
|
|
|
+ // new_grid.insert(unsolved_neighbor, template_tile.to_string());
|
|
|
+ // break;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+
|
|
|
+ // println!("{}", compatible);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // for (pos, tilename) in contraint_map {
|
|
|
+ // println!("\tSolving {} constraint", tilename );
|
|
|
+ // // Now find a suitable tile in training data
|
|
|
+ // let mut compatible = 0;
|
|
|
+ // for (template_tile, compatible_tiles) in training_data {
|
|
|
+ // if let Some(tiles_for_this_pos) = compatible_tiles.get(&pos) {
|
|
|
+ // if tiles_for_this_pos.contains(&tilename) {
|
|
|
+ // println!("\t{} template supports {} @{:?}", template_tile, tilename, pos, );
|
|
|
+ // compatible += 1;
|
|
|
+ // if compatible == num_constraints {
|
|
|
+ // println!("\t{} fits all criteria. Locking in at {:?}", template_tile, unsolved_neighbor*8);
|
|
|
+ // new_grid.insert(unsolved_neighbor, template_tile.to_string());
|
|
|
+
|
|
|
+ // break;
|
|
|
+
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ // }
|
|
|
|
|
|
// println!("Training data: {:?}", trained_data_for_this_tile);
|
|
|
}
|
|
|
@@ -310,7 +412,7 @@ fn main() {
|
|
|
// 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.insert(V3::new(0, 0, 0), String::from("grass"));
|
|
|
|
|
|
for i in 1..3 {
|
|
|
info!(
|