rust/mapgen/src/lib.rs
author alfadur
Mon, 05 Nov 2018 23:15:34 +0300
changeset 14158 3119d665d3c6
parent 14149 b04dac00e8e2
child 14172 3c8a33ba06ba
permissions -rw-r--r--
collapse rectangle types back together with consistent usage of size
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14148
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     1
use std::{
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     2
    collections::hash_map::HashMap,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     3
    borrow::Borrow,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     4
    mem::replace
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     5
};
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     6
use serde::{Deserialize};
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     7
use serde_derive::{Deserialize};
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     8
use serde_yaml;
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
     9
use integral_geometry::{Point, Size, Rect};
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    10
use landgen::{
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    11
    outline_template::OutlineTemplate
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    12
};
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    13
use rand::{thread_rng, Rng};
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    14
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    15
#[derive(Deserialize)]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    16
struct PointDesc {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    17
    x: u32,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    18
    y: u32
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    19
}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    20
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    21
#[derive(Deserialize)]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    22
struct RectDesc {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    23
    x: u32,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    24
    y: u32,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    25
    w: u32,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    26
    h: u32
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    27
}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    28
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    29
#[derive(Deserialize)]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    30
struct TemplateDesc {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    31
    width: usize,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    32
    height: usize,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    33
    can_flip: bool,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    34
    can_invert: bool,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    35
    can_mirror: bool,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    36
    is_negative: bool,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    37
    put_girders: bool,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    38
    max_hedgehogs: u8,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    39
    outline_points: Vec<Vec<RectDesc>>,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    40
    fill_points: Vec<PointDesc>
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    41
}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    42
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    43
#[derive(Deserialize)]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    44
struct TemplateCollectionDesc {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    45
    templates: Vec<TemplateDesc>,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    46
    template_types: HashMap<String, Vec<usize>>
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    47
}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    48
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    49
impl From<&TemplateDesc> for OutlineTemplate {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    50
    fn from(desc: &TemplateDesc) -> Self {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    51
        OutlineTemplate {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    52
            islands: desc.outline_points.iter()
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    53
                .map(|v| v.iter()
14158
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14149
diff changeset
    54
                    .map(|r| Rect::from_size(
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14149
diff changeset
    55
                        Point::new(r.x as i32, r.y as i32),
3119d665d3c6 collapse rectangle types back together with consistent usage of size
alfadur
parents: 14149
diff changeset
    56
                        Size::new(r.w as usize, r.h as usize)))
14148
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    57
                    .collect())
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    58
                .collect(),
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    59
            fill_points: desc.fill_points.iter()
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    60
                .map(|p| Point::new(p.x as i32, p.y as i32))
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    61
                .collect(),
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    62
            size: Size::new(desc.width, desc.height),
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    63
            can_flip: desc.can_flip,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    64
            can_invert: desc.can_invert,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    65
            can_mirror: desc.can_mirror,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    66
            is_negative: desc.is_negative
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    67
        }
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    68
    }
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    69
}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    70
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    71
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    72
struct TemplateType(String);
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    73
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    74
impl Borrow<str> for TemplateType {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    75
    fn borrow(&self) -> &str {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    76
        self.0.as_str()
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    77
    }
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    78
}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    79
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    80
#[derive(Debug)]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    81
pub struct MapGenerator {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    82
    pub(crate) templates: HashMap<TemplateType, Vec<OutlineTemplate>>
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    83
}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    84
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    85
impl MapGenerator {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    86
    pub fn new() -> Self {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    87
        Self { templates: HashMap::new() }
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    88
    }
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    89
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    90
    pub fn import_yaml_templates(&mut self, text: &str) {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    91
        let mut desc: TemplateCollectionDesc = serde_yaml::from_str(text).unwrap();
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    92
        let templates = replace(&mut desc.templates, vec![]);
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    93
        self.templates = desc.template_types.into_iter()
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    94
            .map(|(size, indices)|
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    95
                (TemplateType(size), indices.iter()
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    96
                    .map(|i| (&templates[*i]).into())
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    97
                    .collect()))
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    98
            .collect();
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
    99
    }
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   100
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   101
    pub fn get_template(&self, template_type: &str) -> Option<&OutlineTemplate> {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   102
        self.templates.get(template_type).and_then(|t| thread_rng().choose(t))
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   103
    }
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   104
}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   105
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   106
#[cfg(test)]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   107
mod tests {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   108
    use crate::{
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   109
        MapGenerator,
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   110
        TemplateType
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   111
    };
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   112
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   113
    #[test]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   114
    fn simple_load() {
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   115
        let text = r#"
14149
b04dac00e8e2 add command arguments to use a template from file into land_dump
alfadur
parents: 14148
diff changeset
   116
# comment
b04dac00e8e2 add command arguments to use a template from file into land_dump
alfadur
parents: 14148
diff changeset
   117
14148
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   118
templates:
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   119
  -
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   120
    width: 3072
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   121
    height: 1424
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   122
    can_flip: false
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   123
    can_invert: false
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   124
    can_mirror: true
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   125
    is_negative: false
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   126
    put_girders: true
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   127
    max_hedgehogs: 18
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   128
    outline_points:
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   129
      -
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   130
        - {x: 748, y: 1424, w: 1, h: 1}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   131
        - {x: 636, y: 1252, w: 208, h: 72}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   132
        - {x: 898, y: 1110, w: 308, h: 60}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   133
        - {x: 1128, y: 1252, w: 434, h: 40}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   134
        - {x: 1574, y: 1112, w: 332, h: 40}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   135
        - {x: 1802, y: 1238, w: 226, h: 36}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   136
        - {x: 1930, y: 1424, w: 1, h: 1}
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   137
    fill_points:
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   138
      - {x: 1023, y: 0}
14149
b04dac00e8e2 add command arguments to use a template from file into land_dump
alfadur
parents: 14148
diff changeset
   139
      - {x: 1023, y: 0}
14148
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   140
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   141
template_types:
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   142
    test: [0]
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   143
"#;
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   144
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   145
        let mut generator = MapGenerator::new();
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   146
        generator.import_yaml_templates(&text);
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   147
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   148
        assert!(generator.templates.contains_key(&TemplateType("test".to_string())));
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   149
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   150
        let template = generator.get_template("test").unwrap();
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   151
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   152
        assert_eq!(template.islands[0].len(), 7);
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   153
    }
0c5b9cfda9ab add a higher level map generation lib to load yaml templates into somewhere
alfadur
parents:
diff changeset
   154
}