diff --git a/src/level.rs b/src/level.rs index 7a64739..6ca116f 100644 --- a/src/level.rs +++ b/src/level.rs @@ -15,6 +15,8 @@ pub enum LevelElement { #[derive(Copy, Clone, Debug, PartialEq)] pub enum RoomType { + Start, + End, StairUp, StairDown, BasicRoom, @@ -69,7 +71,7 @@ impl Level { let mut rng = rand::thread_rng(); for _ in rooms.len()..Level::ROOMS_HORIZONTAL * Level::ROOMS_VERTICAL { match rng.gen_range(1..=6) { - 1 => { rooms.push(RoomType::EmptyRoom) } + 1..=3 => { rooms.push(RoomType::EmptyRoom) } _ => { rooms.push(RoomType::BasicRoom) } } } @@ -88,6 +90,8 @@ impl Level { RoomType::BasicRoom => { self.draw_room(&mut rng, row, col) } + RoomType::Start => {} + RoomType::End => {} }; } } diff --git a/src/level_generator.rs b/src/level_generator.rs new file mode 100644 index 0000000..9f8f81d --- /dev/null +++ b/src/level_generator.rs @@ -0,0 +1,120 @@ +use rand::prelude::SliceRandom; +use rand::Rng; + +use crate::level::RoomType; + +const ROOMS_VERTICAL: usize = 7; +const ROOMS_HORIZONTAL: usize = 4; +const ROOM_WIDTH: usize = 7; +const ROOM_HEIGHT: usize = 6; + +#[derive(Copy, Clone, Debug, PartialEq)] +struct Room { + pub kind: RoomType, + pub offset_x: usize, + pub offset_y: usize, + pub width: usize, + pub height: usize, + pub connection_down: bool, + pub connection_right: bool, + pub connected: bool, +} + +impl Room { + fn new() -> Self { + Self { + kind: RoomType::EmptyRoom, + offset_x: 0, + offset_y: 0, + width: 0, + height: 0, + connection_down: false, + connection_right: false, + connected: false, + } + } +} + +#[derive(Debug)] +struct Level { + rooms: [[Room; ROOMS_HORIZONTAL]; ROOMS_VERTICAL], +} + +impl Level { + fn generate(level: usize) -> Self { + let mut room_types: Vec = Vec::with_capacity(ROOMS_HORIZONTAL * ROOMS_VERTICAL); + if level > 0 { + room_types.push(RoomType::StairUp); + } else { + room_types.push(RoomType::Start); + } + if level < 24 { + room_types.push(RoomType::StairDown); + } else { + room_types.push(RoomType::End); + } + let mut rng = rand::thread_rng(); + for _ in room_types.len()..ROOMS_HORIZONTAL * ROOMS_VERTICAL { + match rng.gen_range(1..=6) { + 1..=3 => { room_types.push(RoomType::EmptyRoom) } + _ => { room_types.push(RoomType::BasicRoom) } + } + } + room_types.shuffle(&mut rng); + + let mut rooms = [[Room::new(); ROOMS_HORIZONTAL]; ROOMS_VERTICAL]; + for r in 0..ROOMS_VERTICAL { + for c in 0..ROOMS_HORIZONTAL { + rooms[r][c].kind = room_types.pop().unwrap(); + if rooms[r][c].kind != RoomType::EmptyRoom { + let width = rng.gen_range(3..6); + let height = rng.gen_range(3..5); + rooms[r][c].width = width; + rooms[r][c].height = height; + rooms[r][c].offset_x = rng.gen_range(0..(ROOM_WIDTH - width)); + rooms[r][c].offset_y = rng.gen_range(0..(ROOM_HEIGHT - height)); + } + if r == ROOMS_HORIZONTAL - 1 || c == ROOMS_HORIZONTAL - 1 { + continue; + } + match rng.gen_range(0..3) { + 0 => { rooms[r][c].connection_down = true } + 1 => { rooms[r][c].connection_right = true } + 2 => { + rooms[r][c].connection_down = true; + rooms[r][c].connection_down = true + } + _ => {} + } + } + } + + let mut unconnected_rooms = 0;//ROOMS_HORIZONTAL * ROOMS_VERTICAL - 1; + rooms[0][0].connected=true; + for r in 0..ROOMS_VERTICAL { + for c in 0..ROOMS_HORIZONTAL { + if !rooms[r][c].connected { + continue; + } + if rooms[r][c].connection_right { + rooms[r][c+1].connected=true; + } + if rooms[r][c].connection_down { + rooms[r+1][c].connected=true; + } + } + } + println!("Unconnected: {}", unconnected_rooms); + + Level { + rooms + } + } +} + +#[test] +fn test_level_gen() { + let level = Level::generate(0); + println!("{:?}", level); + assert_eq!(1, 2); +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e2281ef..b211656 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ mod player; mod level; mod position; mod level_widget; +mod level_generator; fn main() -> Result<()> { let mut levels: [Level; 25] = [Level::new(); 25];