|  | @@ -24,21 +24,55 @@ impl TileType {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  pub struct Map {
 | 
	
		
			
				|  |  |      tiles: carpet::Board<TileType>,
 | 
	
		
			
				|  |  | +    rooms: Vec<carpet::Rect>,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  impl Map {
 | 
	
		
			
				|  |  |      fn new() -> Map {
 | 
	
		
			
				|  |  |          let mut rng = rand::thread_rng();
 | 
	
		
			
				|  |  | -        let tiles = carpet::Board::new_from(80, 50, |x, y| {
 | 
	
		
			
				|  |  | -            if x == 0 || x == 79 || y == 0 || y == 49 {
 | 
	
		
			
				|  |  | -                TileType::Wall
 | 
	
		
			
				|  |  | -            } else if rng.gen::<u8>() % 8 == 0 {
 | 
	
		
			
				|  |  | -                TileType::Wall
 | 
	
		
			
				|  |  | -            } else {
 | 
	
		
			
				|  |  | -                TileType::Floor
 | 
	
		
			
				|  |  | +        let mut map = Map {
 | 
	
		
			
				|  |  | +            tiles: carpet::Board::new_with_default(80, 50, TileType::Wall),
 | 
	
		
			
				|  |  | +            rooms: Vec::new(),
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const MAX_ROOMS: usize = 30;
 | 
	
		
			
				|  |  | +        const MIN_SIZE: usize = 6;
 | 
	
		
			
				|  |  | +        const MAX_SIZE: usize = 10;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for _ in 0..MAX_ROOMS {
 | 
	
		
			
				|  |  | +            let w = rng.gen_range(MIN_SIZE, MAX_SIZE);
 | 
	
		
			
				|  |  | +            let h = rng.gen_range(MIN_SIZE, MAX_SIZE);
 | 
	
		
			
				|  |  | +            let x = rng.gen_range(1, 80 - w);
 | 
	
		
			
				|  |  | +            let y = rng.gen_range(1, 50 - h);
 | 
	
		
			
				|  |  | +            let room = carpet::Rect::new([x, y], [w, h]);
 | 
	
		
			
				|  |  | +            if map.rooms.iter().any(|r| r.overlaps(room)) {
 | 
	
		
			
				|  |  | +                continue;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -        });
 | 
	
		
			
				|  |  | -        Map { tiles }
 | 
	
		
			
				|  |  | +            map.carve(room);
 | 
	
		
			
				|  |  | +            if let Some(prev) = map.rooms.first() {
 | 
	
		
			
				|  |  | +                let c1 = room.center();
 | 
	
		
			
				|  |  | +                let c2 = prev.center();
 | 
	
		
			
				|  |  | +                let join = if rng.gen() {
 | 
	
		
			
				|  |  | +                    carpet::Coord { x: c1.x, y: c2.y }
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    carpet::Coord { x: c2.x, y: c1.y }
 | 
	
		
			
				|  |  | +                };
 | 
	
		
			
				|  |  | +                map.carve(carpet::Rect::from_points(c1, join));
 | 
	
		
			
				|  |  | +                map.carve(carpet::Rect::from_points(join, c2));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            map.rooms.push(room);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        map
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    fn carve(&mut self, rect: carpet::Rect) {
 | 
	
		
			
				|  |  | +        let iter = self.tiles.window_iter_mut(rect)
 | 
	
		
			
				|  |  | +            .expect(&format!("Rect {:?} of map bounds", rect));
 | 
	
		
			
				|  |  | +        for (_, _, t) in iter {
 | 
	
		
			
				|  |  | +            *t = TileType::Floor;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      fn passable(&self, (x, y): (usize, usize)) -> bool {
 | 
	
	
		
			
				|  | @@ -136,13 +170,15 @@ fn main() -> Result<(), GameError> {
 | 
	
		
			
				|  |  |      game.register::<Motion>();
 | 
	
		
			
				|  |  |      game.register::<Player>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    game.insert(Map::new());
 | 
	
		
			
				|  |  | +    let map = Map::new();
 | 
	
		
			
				|  |  | +    let player_start = map.rooms.first().map(|r| r.center()).unwrap_or([40, 25].into());
 | 
	
		
			
				|  |  | +    game.insert(map);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      game.create_entity()
 | 
	
		
			
				|  |  | -        .with(Pos { x: 40, y: 25 })
 | 
	
		
			
				|  |  | +        .with(Pos { x: player_start.x, y: player_start.y })
 | 
	
		
			
				|  |  |          .with(Player)
 | 
	
		
			
				|  |  |          .with(Renderable {
 | 
	
		
			
				|  |  | -            glyph: carpet::CP437::from_char('A'),
 | 
	
		
			
				|  |  | +            glyph: carpet::CP437::from_char('@'),
 | 
	
		
			
				|  |  |              color: carpet::Color::Blue,
 | 
	
		
			
				|  |  |          })
 | 
	
		
			
				|  |  |          .build();
 |