Skip to content

Commit

Permalink
Add momentum and introduce Result returns
Browse files Browse the repository at this point in the history
  • Loading branch information
iMilchshake committed Apr 21, 2024
1 parent dfca940 commit 48482e9
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 58 deletions.
15 changes: 8 additions & 7 deletions configs/cringe4teero.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@
3
],
"inner_rad_mut_prob": 0.4,
"inner_size_mut_prob": 0.9,
"inner_size_mut_prob": 0.2,
"outer_rad_mut_prob": 0.25,
"outer_size_mut_prob": 0.5,
"outer_size_mut_prob": 1.0,
"step_weights": [
20,
13,
12,
3
15,
14,
6
],
"platform_distance_bounds": [
500,
750
200,
300
],
"momentum_prob": 0.5,
"waypoints": [
{
"x": 250,
Expand Down
7 changes: 4 additions & 3 deletions configs/cringe4teero2.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@
"inner_rad_mut_prob": 0.45,
"inner_size_mut_prob": 1.0,
"outer_rad_mut_prob": 0.45,
"outer_size_mut_prob": 1.0,
"outer_size_mut_prob": 0.9,
"step_weights": [
20,
9,
8,
4
],
"platform_distance_bounds": [
500,
750
200,
300
],
"momentum_prob": 0.5,
"waypoints": [
{
"x": 250,
Expand Down
1 change: 1 addition & 0 deletions configs/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
500,
750
],
"momentum_prob": 0.3,
"waypoints": [
{
"x": 250,
Expand Down
49 changes: 49 additions & 0 deletions configs/main_new.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "main_new",
"description": null,
"inner_size_bounds": [
4,
4
],
"outer_size_bounds": [
3,
5
],
"inner_rad_mut_prob": 0.61,
"inner_size_mut_prob": 1.0,
"outer_rad_mut_prob": 0.87,
"outer_size_mut_prob": 0.8,
"step_weights": [
20,
9,
8,
6
],
"platform_distance_bounds": [
500,
750
],
"momentum_prob": 0.5,
"waypoints": [
{
"x": 250,
"y": 250
},
{
"x": 250,
"y": 150
},
{
"x": 50,
"y": 150
},
{
"x": 50,
"y": 50
},
{
"x": 250,
"y": 50
}
]
}
4 changes: 4 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub struct GenerationConfig {
/// (min, max) distance between platforms
pub platform_distance_bounds: (usize, usize),

/// probability for doing the last shift direction again
pub momentum_prob: f32,

// ------- TODO: these should go somewhere else -----
pub waypoints: Vec<Position>,
}
Expand Down Expand Up @@ -99,6 +102,7 @@ impl Default for GenerationConfig {
],
step_weights: vec![20, 11, 10, 9],
platform_distance_bounds: (500, 750),
momentum_prob: 0.01,
}
}
}
8 changes: 8 additions & 0 deletions src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,14 @@ impl Editor {
true,
);

field_edit_widget(
ui,
&mut self.config.momentum_prob,
edit_f32,
"momentum prob",
true,
);

// only show these in setup mode
ui.add_visible_ui(self.is_setup(), |ui| {
vec_edit_widget(
Expand Down
26 changes: 16 additions & 10 deletions src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,26 @@ impl Generator {

if !self.walker.finished {
// randomly mutate kernel
self.walker.mutate_kernel(config, &mut self.rnd);
self.walker.mutate_kernel(&config, &mut self.rnd);

// perform one step
self.walker
.probabilistic_step(&mut self.map, &mut self.rnd)?;
.probabilistic_step(&mut self.map, config, &mut self.rnd)?;

// handle platforms
self.walker.check_platform(
&mut self.map,
config.platform_distance_bounds.0,
config.platform_distance_bounds.1,
);
)?;
}

Ok(())
}

/// Post processing step to fix all existing edge-bugs, as certain inner/outer kernel
/// configurations do not ensure a min. 1-block freeze padding consistently.
fn fix_edge_bugs(&mut self) -> Array2<bool> {
fn fix_edge_bugs(&mut self) -> Result<Array2<bool>, &'static str> {
let mut edge_bug = Array2::from_elem((self.map.width, self.map.height), false);
let width = self.map.width;
let height = self.map.height;
Expand All @@ -71,8 +71,12 @@ impl Generator {
continue;
}

let neighbor_x = x + dx - 1; // TODO: deal with overflow?
let neighbor_y = y + dy - 1;
let neighbor_x = (x + dx)
.checked_sub(1)
.ok_or("fix edge bug out of bounds")?;
let neighbor_y = (y + dy)
.checked_sub(1)
.ok_or("fix edge bug out of bounds")?;
if neighbor_x < width && neighbor_y < height {
let neighbor_value = &self.map.grid[[neighbor_x, neighbor_y]];
if *neighbor_value == BlockType::Hookable {
Expand All @@ -90,15 +94,17 @@ impl Generator {
}
}

edge_bug
Ok(edge_bug)
}

pub fn post_processing(&mut self) {
self.fix_edge_bugs();
self.fix_edge_bugs().expect("fix edge bugs failed");
self.map
.generate_room(&self.map.spawn.clone(), 4, Some(&BlockType::Start));
.generate_room(&self.map.spawn.clone(), 4, Some(&BlockType::Start))
.expect("start room generation failed");
self.map
.generate_room(&self.walker.pos.clone(), 4, Some(&BlockType::Finish));
.generate_room(&self.walker.pos.clone(), 4, Some(&BlockType::Finish))
.expect("start finish room generation");
}

/// Generates an entire map with a single function call. This function is used by the CLI.
Expand Down
63 changes: 41 additions & 22 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,45 +130,59 @@ impl Map {
Ok(())
}

pub fn generate_room(&mut self, pos: &Position, margin: usize, zone_type: Option<&BlockType>) {
// TODO: ensure valid position?
pub fn generate_room(
&mut self,
pos: &Position,
margin: usize,
zone_type: Option<&BlockType>,
) -> Result<(), &'static str> {
// TODO: return an error?
if pos.x < (margin + 1)
|| pos.y < (margin + 1)
|| pos.x > self.width - (margin + 1)
|| pos.y > self.height - (margin + 1)
{
return Err("generate room out of bounds");
}

let margin: i32 = margin.to_i32().unwrap();

// carve room
self.set_area(
&pos.shifted_by(-margin, -margin),
&pos.shifted_by(margin, margin),
&pos.shifted_by(-margin, -margin)?,
&pos.shifted_by(margin, margin)?,
&BlockType::Empty,
true,
);

// set platform
self.set_area(
&pos.shifted_by(-(margin - 2), 1),
&pos.shifted_by(margin - 2, 1),
&pos.shifted_by(-(margin - 2), 1)?,
&pos.shifted_by(margin - 2, 1)?,
&BlockType::Platform,
true,
);

// set spawns
if zone_type == Some(&BlockType::Start) {
self.set_area(
&pos.shifted_by(-(margin - 2), 0),
&pos.shifted_by(margin - 2, 0),
&pos.shifted_by(-(margin - 2), 0)?,
&pos.shifted_by(margin - 2, 0)?,
&BlockType::Spawn,
true,
);
}
// set start/finish line
if let Some(zone_type) = zone_type {
self.set_area_border(
&pos.shifted_by(-margin - 1, -margin - 1),
&pos.shifted_by(margin + 1, margin + 1),
&pos.shifted_by(-margin - 1, -margin - 1)?,
&pos.shifted_by(margin + 1, margin + 1)?,
zone_type,
false,
);
}

Ok(())
}

fn pos_to_chunk_pos(&self, pos: Position) -> Position {
Expand Down Expand Up @@ -211,27 +225,32 @@ impl Map {
top_left: &Position,
bot_right: &Position,
value: &BlockType,
) -> bool {
let area = self.grid.slice(s![
top_left.x..=bot_right.x + 1,
top_left.y..=bot_right.y + 1
]);
) -> Result<bool, &'static str> {
if !self.pos_in_bounds(&top_left) || !self.pos_in_bounds(&bot_right) {
return Err("checking area out of bounds");
}

let area = self
.grid
.slice(s![top_left.x..=bot_right.x, top_left.y..=bot_right.y]);

area.iter().any(|block| block == value)
Ok(area.iter().any(|block| block == value))
}

pub fn check_area_all(
&self,
top_left: &Position,
bot_right: &Position,
value: &BlockType,
) -> bool {
let area = self.grid.slice(s![
top_left.x..=bot_right.x + 1,
top_left.y..=bot_right.y + 1
]);
) -> Result<bool, &'static str> {
if !self.pos_in_bounds(&top_left) || !self.pos_in_bounds(&bot_right) {
return Err("checking area out of bounds");
}
let area = self
.grid
.slice(s![top_left.x..=bot_right.x, top_left.y..=bot_right.y]);

area.iter().all(|block| block == value)
Ok(area.iter().all(|block| block == value))
}

// TODO: right now override is hardcoded to overide empty AND freeze. i might need some
Expand Down
8 changes: 4 additions & 4 deletions src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,24 @@ impl Position {
}

/// returns a new position shifted by some x and y value
pub fn shifted_by(&self, x_shift: i32, y_shift: i32) -> Position {
pub fn shifted_by(&self, x_shift: i32, y_shift: i32) -> Result<Position, &'static str> {
let new_x = match x_shift >= 0 {
true => self.x + (x_shift as usize),
false => self
.x
.checked_sub((-x_shift) as usize)
.expect("shift is out of bounds"),
.ok_or("invalid shift")?,
};

let new_y = match y_shift >= 0 {
true => self.y + y_shift as usize,
false => self
.y
.checked_sub((-y_shift) as usize)
.expect("shift is out of bounds"),
.ok_or("invalid shift")?,
};

Position::new(new_x, new_y)
Ok(Position::new(new_x, new_y))
}

pub fn shift_in_direction(
Expand Down
Loading

0 comments on commit 48482e9

Please sign in to comment.