more work on level generators

This commit is contained in:
Joachim Lusiardi 2024-11-05 12:02:45 +01:00
parent 5311f56ca0
commit 72f7be2ed8
3 changed files with 58 additions and 11 deletions

View File

@ -19,7 +19,7 @@ pub const ROOM_MIN_WIDTH: usize = 4;
pub const ROOM_MIN_HEIGHT: usize = 4;
/// How many levels does the dungeon have?
pub const LEVELS: usize = 2;
pub const LEVELS: usize = 4;
/// length of a game frame in ms
pub const FRAME_LENGTH: u64 = 100;
@ -46,6 +46,12 @@ pub fn get_monsters_per_level() -> Vec<HashMap<MonsterTypes, std::ops::RangeIncl
(MonsterTypes::Skeleton, 33),
(MonsterTypes::Snake, 33),
],
// level 4
vec![
(MonsterTypes::Orc, 34),
(MonsterTypes::Skeleton, 33),
(MonsterTypes::Snake, 33),
],
];
if tmp.len() < LEVELS {
panic!(
@ -79,8 +85,8 @@ pub fn get_room_type_per_level() -> Vec<HashMap<RoomType, std::ops::RangeInclusi
// level 1
vec![
(RoomType::EmptyRoom, 50),
(RoomType::ArtifactRoom, 25),
(RoomType::MonsterRoom, 5),
(RoomType::ArtifactRoom, 10),
(RoomType::MonsterRoom, 20),
(RoomType::BasicRoom, 20),
],
// level 2
@ -91,7 +97,17 @@ pub fn get_room_type_per_level() -> Vec<HashMap<RoomType, std::ops::RangeInclusi
(RoomType::ArtifactRoom, 13),
],
// level 3
vec![(RoomType::EmptyRoom, 50), (RoomType::MonsterRoom, 50)],
vec![
(RoomType::EmptyRoom, 50),
(RoomType::BasicRoom, 25),
(RoomType::MonsterRoom, 25),
],
// level 4
vec![
(RoomType::BasicRoom, 33),
(RoomType::MonsterRoom, 33),
(RoomType::ArtifactRoom, 34),
],
];
if tmp.len() < LEVELS {
panic!(

View File

@ -57,7 +57,7 @@ impl Level {
return (None, None, None);
}
if !self.discovered[x][y] {
#[cfg(test)]
// #[cfg(test)]
return (Some(StructureElement::Unknown), None, None);
}
let search_pos = &Position::new(self.level, x, y);

View File

@ -1,5 +1,6 @@
use petgraph::algo::min_spanning_tree;
use petgraph::data::*;
use petgraph::graph::Edge;
use petgraph::graph::Graph;
use petgraph::graph::UnGraph;
@ -139,6 +140,11 @@ impl LevelGenerator {
rng: &mut ThreadRng,
rooms: &[[Room; ROOMS_VERTICAL]; ROOMS_HORIZONTAL],
) -> GeneratorGraph {
// calculate the weight of an edge
fn calc_edge_weight(delta: usize) -> usize {
delta * delta
}
let mut graph: GeneratorGraph = UnGraph::<(usize, usize), usize>::default();
for (col, tgt_col) in rooms.iter().enumerate().take(ROOMS_HORIZONTAL) {
for (row, room) in tgt_col.iter().enumerate().take(ROOMS_VERTICAL) {
@ -166,8 +172,7 @@ impl LevelGenerator {
graph.add_edge(
src_index,
tgt_index,
(rng.gen_range(0..5) as f32 / 5.0) as usize
* col.abs_diff(col_1),
calc_edge_weight(col.abs_diff(col_1)),
);
break;
}
@ -181,8 +186,7 @@ impl LevelGenerator {
graph.add_edge(
src_index,
tgt_index,
(rng.gen_range(0..5) as f32 / 5.0) as usize
* row.abs_diff(row_1),
calc_edge_weight(row.abs_diff(row_1)),
);
break;
}
@ -191,8 +195,35 @@ impl LevelGenerator {
}
}
}
Graph::from_elements(min_spanning_tree(&graph))
// graph
let mut mst: GeneratorGraph = Graph::from_elements(min_spanning_tree(&graph));
// readd some of the short edges that were remove (all between a weight of 1 to 10)
let initial_edges = graph.raw_edges();
let minimal_edges = mst.raw_edges();
let mut extra_edges: Vec<Edge<usize>> = vec![];
for init_edge in initial_edges {
let start_node = init_edge.source();
let end_node = init_edge.target();
let mut found = false;
for min_edge in minimal_edges {
if min_edge.source() == start_node && min_edge.target() == end_node {
found = true;
break;
}
}
if !found {
extra_edges.push(init_edge.clone());
}
}
extra_edges.sort_by(|a, b| a.weight.cmp(&b.weight));
for e in extra_edges
.iter()
.filter(|x| x.weight > 1)
.filter(|x| x.weight < 7)
{
mst.add_edge(e.source(), e.target(), e.weight);
}
mst
}
fn create_connections(