rust/landgen/src/wavefront_collapse/generator.rs
changeset 16109 2fc37552b587
parent 16108 65c017453e83
equal deleted inserted replaced
16108:65c017453e83 16109:2fc37552b587
    12 #[derive(Debug, Clone)]
    12 #[derive(Debug, Clone)]
    13 pub struct EdgeDescription {
    13 pub struct EdgeDescription {
    14     pub name: String,
    14     pub name: String,
    15     pub reversed: Option<bool>,
    15     pub reversed: Option<bool>,
    16     pub symmetrical: Option<bool>,
    16     pub symmetrical: Option<bool>,
       
    17     pub hard_match: Option<bool>,
    17 }
    18 }
    18 
    19 
    19 #[derive(Debug, Clone)]
    20 #[derive(Debug, Clone)]
    20 pub struct EdgesDescription {
    21 pub struct EdgesDescription {
    21     pub top: EdgeDescription,
    22     pub top: EdgeDescription,
   204         ]
   205         ]
   205         .map(|opt| opt.map(|d| [&d.begin, &d.fill, &d.end].map(|e| e.as_ref().map(Into::into))));
   206         .map(|opt| opt.map(|d| [&d.begin, &d.fill, &d.end].map(|e| e.as_ref().map(Into::into))));
   206 
   207 
   207         let mut rules = Vec::<CollapseRule>::new();
   208         let mut rules = Vec::<CollapseRule>::new();
   208 
   209 
   209         let default_connection = HashSet::from_iter(vec![Tile::Empty].into_iter());
       
   210         for (i, tile) in tiles.iter().enumerate() {
   210         for (i, tile) in tiles.iter().enumerate() {
   211             let mut right = default_connection.clone();
   211             let mut top = HashSet::new();
   212             let mut bottom = default_connection.clone();
   212             let mut right = HashSet::new();
   213             let mut left = default_connection.clone();
   213             let mut bottom = HashSet::new();
   214             let mut top = default_connection.clone();
   214             let mut left = HashSet::new();
   215 
   215 
   216             let iteration = [
   216             let iteration = [
   217                 (&grid_top_edge, tile.edge_set().top(), &mut top),
   217                 (&grid_top_edge, tile.edge_set().top(), &mut top),
   218                 (&grid_right_edge, tile.edge_set().right(), &mut right),
   218                 (&grid_right_edge, tile.edge_set().right(), &mut right),
   219                 (&grid_bottom_edge, tile.edge_set().bottom(), &mut bottom),
   219                 (&grid_bottom_edge, tile.edge_set().bottom(), &mut bottom),
   220                 (&grid_left_edge, tile.edge_set().left(), &mut left),
   220                 (&grid_left_edge, tile.edge_set().left(), &mut left),
   221             ];
   221             ];
   222 
   222 
   223             // compatibility with grid edges
   223             // compatibility with grid edges
   224             for (edge, tile_edge, set) in iteration {
   224             for (edge, tile_edge, set) in iteration {
       
   225                 if !tile_edge.hard_match() {
       
   226                     set.insert(Tile::Empty);
       
   227                 }
       
   228 
   225                 for (is_compatible, tile) in edge
   229                 for (is_compatible, tile) in edge
   226                     .as_ref()
   230                     .as_ref()
   227                     .map(|e| {
   231                     .map(|e| {
   228                         e.clone().map(|ed| {
   232                         e.clone().map(|ed| {
   229                             ed.as_ref()
   233                             ed.as_ref()
   397     }
   401     }
   398 }
   402 }
   399 
   403 
   400 impl From<&EdgeDescription> for Edge<String> {
   404 impl From<&EdgeDescription> for Edge<String> {
   401     fn from(val: &EdgeDescription) -> Self {
   405     fn from(val: &EdgeDescription) -> Self {
   402         let edge = Edge::new(val.name.clone(), val.symmetrical.unwrap_or_default());
   406         let edge = Edge::new(
       
   407             val.name.clone(),
       
   408             val.symmetrical.unwrap_or_default(),
       
   409             val.hard_match.unwrap_or_default(),
       
   410         );
   403 
   411 
   404         if val.reversed.unwrap_or_default() {
   412         if val.reversed.unwrap_or_default() {
   405             edge.reversed()
   413             edge.reversed()
   406         } else {
   414         } else {
   407             edge
   415             edge
   411 
   419 
   412 impl<T: AsRef<str>> From<T> for EdgeDescription {
   420 impl<T: AsRef<str>> From<T> for EdgeDescription {
   413     fn from(val: T) -> Self {
   421     fn from(val: T) -> Self {
   414         use std::cmp::Ordering;
   422         use std::cmp::Ordering;
   415 
   423 
   416         let reversed = val.as_ref().chars().rev().collect::<String>();
   424         let mut chars = val.as_ref().chars();
   417 
   425         let hard_match = chars.next() == Some('!');
   418         match val.as_ref().cmp(&reversed) {
   426 
       
   427         let (name, reversed): (String, String) = if hard_match {
       
   428             (chars.clone().collect(), chars.rev().collect())
       
   429         } else {
       
   430             (
       
   431                 val.as_ref().chars().collect(),
       
   432                 val.as_ref().chars().rev().collect(),
       
   433             )
       
   434         };
       
   435 
       
   436         match name.cmp(&reversed) {
   419             Ordering::Less => EdgeDescription {
   437             Ordering::Less => EdgeDescription {
   420                 name: val.as_ref().to_owned(),
   438                 name,
   421                 symmetrical: Some(false),
   439                 symmetrical: Some(false),
   422                 reversed: Some(false),
   440                 reversed: Some(false),
       
   441                 hard_match: Some(hard_match),
   423             },
   442             },
   424             Ordering::Equal => EdgeDescription {
   443             Ordering::Equal => EdgeDescription {
   425                 name: reversed,
   444                 name: reversed,
   426                 symmetrical: Some(true),
   445                 symmetrical: Some(true),
   427                 reversed: Some(false),
   446                 reversed: Some(false),
       
   447                 hard_match: Some(hard_match),
   428             },
   448             },
   429             Ordering::Greater => EdgeDescription {
   449             Ordering::Greater => EdgeDescription {
   430                 name: reversed,
   450                 name: reversed,
   431                 symmetrical: Some(false),
   451                 symmetrical: Some(false),
   432                 reversed: Some(true),
   452                 reversed: Some(true),
       
   453                 hard_match: Some(hard_match),
   433             },
   454             },
   434         }
   455         }
   435     }
   456     }
   436 }
   457 }