-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add binary space partition and random room placement algorithms for procedural generation #3
Conversation
src/binary_space_partition.rs
Outdated
if map_subsection_min_size < map_subsection_min_room_width || map_subsection_min_size < map_subsection_min_room_height{ | ||
map_subsection_min_size = cmp::max(map_subsection_min_room_width, map_subsection_min_room_height) + 1 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to understand this logic. So if the map_subsection_min_size
is less than map_subsection_min_room_width
or map_subsection_min_room_width
it'll be set to whatever is highest + 1.
From the sounds of it it seems like you want map_subsection_min_size
to always be atleast 1 more than map_subsection_min_room_width
and map_subsection_min_room_height
If that is the case then I think you might have a bug, you should be using <= not < or else you could end up in the scenario of map_subsection_min_size
being equal to map_subsection_min_size
and you could also simplify this to
if map_subsection_min_size < map_subsection_min_room_width || map_subsection_min_size < map_subsection_min_room_height{ | |
map_subsection_min_size = cmp::max(map_subsection_min_room_width, map_subsection_min_room_height) + 1 | |
} | |
let map_subsection_min_size = cmp::max( | |
map_subsection_min_size_as_str.parse::<i32>()?, | |
cmp::max(map_subsection_min_room_width, map_subsection_min_room_height) + 1 | |
) |
and avoid using a mutable variable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gotcha about the mut, and updated to use your double cmp method over the if then cmp 👍
src/binary_space_partition.rs
Outdated
let mut string = String::new(); | ||
for room in &level.all_rooms { | ||
let serialized = serde_json::to_string(&room).unwrap(); | ||
let _ = write!(string, "{}", serialized); | ||
//println!("serialized = {}", serialized); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this leftover debug code? I don't see where the string
value is used!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're right my b, got rid of it
src/binary_space_partition.rs
Outdated
//println!("serialized = {}", serialized); | ||
} | ||
|
||
Ok(format!("{}",serde_json::to_string(&level.all_rooms)?)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok(format!("{}",serde_json::to_string(&level.all_rooms)?)) | |
serde_json::to_string(&level.all_rooms) |
serde_json::to_string
already returns a Result<String>, maybe you can just return that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately just trying to return the serde_json::to_string gives me
mismatched types serde_json::Error and error::Error have similar names, but are actually distinct types
but wrapping it in an Ok()? converts the error into the appropriate error rust-g is expecting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mightt be worth reviewing all your commented code and either removing it or uncommenting it! Makes it a little confusing to know whats what.
src/random_room_placement.rs
Outdated
let max_rooms = desired_room_count as usize; | ||
let max_attempts = 15; | ||
let mut attempts = 0; | ||
while self.level.all_rooms.iter().filter(|&rm| rm.room_type == 3).count() <= max_rooms && attempts <= max_attempts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rm.room_type == 3
Could we maybe use some kind of enum for room_type? hard to know what 3
is supposed to mean!
} | ||
|
||
fn place_rooms_random(&mut self, desired_room_count: i32, rng: &mut StdRng) { | ||
let max_rooms = desired_room_count as usize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you not make place_rooms_Random take a usize
? or just use an i32
?
src/random_room_placement.rs
Outdated
map.level | ||
} | ||
|
||
fn place_rooms_random(&mut self, desired_room_count: i32, rng: &mut StdRng) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tbh is it worth just making place_rooms_random a function of Level
instead of creating an entirely different RandomRoomLevel
struct?
src/random_room_placement.rs
Outdated
board: Vec<Vec<i32>>, | ||
all_rooms: Vec<Room>, | ||
increment: i32, | ||
//hash: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still need this?
src/random_room_placement.rs
Outdated
for _ in 0..self.height { | ||
let space_tile = 0; | ||
//let wall_tile = 1; | ||
let floor_tile = 5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could have a TileType enum?
src/random_room_placement.rs
Outdated
let gen_floor_first = true; | ||
|
||
let mut row = vec![floor_tile; self.width as usize]; | ||
if !gen_floor_first { | ||
row = vec![space_tile; self.width as usize]; | ||
} | ||
// if gen_floor_first { | ||
// if index == 0 || index == self.height - 1 { | ||
// row = vec![wall_tile; self.width as usize]; | ||
// } | ||
|
||
// row[0] = wall_tile; | ||
// row[self.width as usize - 1] = wall_tile; | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you meant to do something with gen_floor_first here?
src/random_room_placement.rs
Outdated
let height: i32; | ||
match *self { | ||
RoomDimensions::Maint3x3 => height = 3, | ||
RoomDimensions::Maint3x5 => height = 5, | ||
RoomDimensions::Maint5x3 => height = 3, | ||
RoomDimensions::Maint5x4 => height = 4, | ||
RoomDimensions::Maint10x5 => height = 5, | ||
RoomDimensions::Maint10x10 => height = 10, | ||
} | ||
return height + 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let height: i32; | |
match *self { | |
RoomDimensions::Maint3x3 => height = 3, | |
RoomDimensions::Maint3x5 => height = 5, | |
RoomDimensions::Maint5x3 => height = 3, | |
RoomDimensions::Maint5x4 => height = 4, | |
RoomDimensions::Maint10x5 => height = 5, | |
RoomDimensions::Maint10x10 => height = 10, | |
} | |
return height + 2 | |
match *self { | |
RoomDimensions::Maint3x3 => 3, | |
RoomDimensions::Maint3x5 => 5, | |
RoomDimensions::Maint5x3 => 3, | |
RoomDimensions::Maint5x4 => 4, | |
RoomDimensions::Maint10x5 => 5, | |
RoomDimensions::Maint10x10 => 10, | |
} + 2 |
src/random_room_placement.rs
Outdated
let width: i32; | ||
match *self { | ||
RoomDimensions::Maint3x3 => width = 3, | ||
RoomDimensions::Maint3x5 => width = 3, | ||
RoomDimensions::Maint5x3 => width = 5, | ||
RoomDimensions::Maint5x4 => width = 5, | ||
RoomDimensions::Maint10x5 => width = 10, | ||
RoomDimensions::Maint10x10 => width = 10, | ||
} | ||
return width + 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let width: i32; | |
match *self { | |
RoomDimensions::Maint3x3 => width = 3, | |
RoomDimensions::Maint3x5 => width = 3, | |
RoomDimensions::Maint5x3 => width = 5, | |
RoomDimensions::Maint5x4 => width = 5, | |
RoomDimensions::Maint10x5 => width = 10, | |
RoomDimensions::Maint10x10 => width = 10, | |
} | |
return width + 2; | |
match *self { | |
RoomDimensions::Maint3x3 => width = 3, | |
RoomDimensions::Maint3x5 => width = 3, | |
RoomDimensions::Maint5x3 => width = 5, | |
RoomDimensions::Maint5x4 => width = 5, | |
RoomDimensions::Maint10x5 => width = 10, | |
RoomDimensions::Maint10x10 => width = 10, | |
} + 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might also want a comment for what the + 2
is for!
simplify is_leaf Co-authored-by: Ashleigh Carr <[email protected]>
I hope I'm doing this right. This is the code I've been testing with and it compiles using the default
cargo build --release --target i686-pc-windows-msvc
from the readme so I assume that means it will work and won't destroy the server
Adds rust functions for binary space partitioning and random room placement. Currently just for my procedural maintenance generation code, but can be applied to more than that in the future, should anyone else want to use it
Binary Space Partitioning:
Basically cutting a shape in half, then that half in half, recursively until all subsections are equal to a minimum given size, or further cuts would reduce the size beneath the desired minimum
Random Room Placement:
Given an area of specified dimensions, will create rooms of varying dimensions and place them randomly in the area. The only logic applied is that the rooms fit within the boundaries of the area and don't overlap one another
Credit to https://www.jamesbaum.co.uk/blether/procedural-level-generation-rust/ for getting me started with the code I needed to make this work