add fly options

This commit is contained in:
Edgar 2022-11-02 15:50:35 +01:00
parent ba7382e410
commit cd1714dac3
No known key found for this signature in database
5 changed files with 54 additions and 20 deletions

BIN
generated.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -32,18 +32,33 @@ struct Cli {
#[derive(Subcommand)]
enum Commands {
/// Generate a map for fly techniques.
Fly,
Fly {
#[arg(long, default_value_t = 3)]
max_fly_width: u16,
/// The output map file.
#[arg(long, default_value_t = 12)]
min_fly_width: u16,
},
/// Generate a maze-like map.
Maze,
}
impl Commands {
pub fn print(&self) {
let name = match self {
Self::Fly => "Fly",
Self::Maze => "Maze",
print!("Selected generator: ");
let data = match self {
Self::Fly {
max_fly_width,
min_fly_width,
} => format!(
"{}, parameters: max_fly_width={}, min_fly_width={}",
"Fly".purple().bold(),
max_fly_width.purple(),
min_fly_width.purple()
),
Self::Maze => format!("{}", "Maze".purple().bold()),
};
println!("Selected map generator: {}", name.purple().bold());
println!("{data}");
}
}
@ -70,10 +85,15 @@ pub fn run_cli() -> Result<()> {
match cli.command {
Commands::Maze => {
MazeGenerator::save_file(&mut rng, &cli.mapres, cli.width, cli.height, &cli.output)
MazeGenerator.save_file(&mut rng, &cli.mapres, cli.width, cli.height, &cli.output)
}
Commands::Fly => {
FlyGenerator::save_file(&mut rng, &cli.mapres, cli.width, cli.height, &cli.output)
Commands::Fly {
max_fly_width,
min_fly_width,
} => FlyGenerator {
max_fly_width,
min_fly_width,
}
.save_file(&mut rng, &cli.mapres, cli.width, cli.height, &cli.output),
}
}

View file

@ -2,11 +2,16 @@ use super::*;
use eyre::Result;
use ndarray::Array2;
use rand::Rng;
use rand_distr::{Uniform, Distribution};
pub struct FlyGenerator;
pub struct FlyGenerator {
pub max_fly_width: u16,
pub min_fly_width: u16,
}
impl MapGenerator for FlyGenerator {
fn generate<R: Rng + ?Sized>(
&self,
rng: &mut R,
mapres: &Path,
width: usize,
@ -14,7 +19,7 @@ impl MapGenerator for FlyGenerator {
) -> Result<TwMap> {
let mut map = create_initial_map(mapres)?;
let mut tiles = Array2::from_shape_simple_fn((height, width), || {
let mut game_tiles = Array2::from_shape_simple_fn((height, width), || {
GameTile::new(TILE_EMPTY, TileFlags::empty())
});
let mut front_tiles = Array2::from_shape_simple_fn((height, width), || {
@ -26,7 +31,8 @@ impl MapGenerator for FlyGenerator {
let mut freeze_tiles =
Array2::from_shape_simple_fn((height, width), || Tile::new(0, TileFlags::empty()));
tiles
// Create the ceiling and spawn.
game_tiles
.row_mut(height - 2)
.iter_mut()
.for_each(|tile| tile.id = TILE_UNHOOKABLE);
@ -35,8 +41,9 @@ impl MapGenerator for FlyGenerator {
.iter_mut()
.for_each(|tile| tile.id = 2);
tiles[(height - 3, width / 2)].id = TILE_SPAWN;
game_tiles[(height - 3, width / 2)].id = TILE_SPAWN;
// Place the start and finish tiles.
for x in 0..width {
front_tiles[(height - 6, x)].id = TILE_START;
front_tiles[(10, x)].id = TILE_FINISH;
@ -50,25 +57,29 @@ impl MapGenerator for FlyGenerator {
let mut direction_steps: i64 = rng.gen_range((max_steps / 2)..=max_steps);
let mut direction: i64 = rng.gen_range(-1..=1);
let direction_steps_sampler = Uniform::from(1..=10);
let direction_sampler = Uniform::from(-1..=1);
let width_sampler = Uniform::from(-1..=1);
for y in (0..=(height - 3)).rev() {
if direction_steps == 0 {
direction_steps = rng.gen_range(1..=10);
direction = rng.gen_range(-1..=1);
direction_steps = direction_steps_sampler.sample(rng);
direction = direction_sampler.sample(rng);
}
let width_change: i64 = rng.gen_range(-1..=1);
let width_change: i64 = width_sampler.sample(rng);
center += direction;
fly_width += width_change;
fly_width = fly_width.clamp(3, 12);
fly_width = fly_width.clamp(self.min_fly_width as i64, self.max_fly_width as i64);
center = center.clamp(fly_width, width as i64 - fly_width - 1);
for x in ((center + fly_width) as usize)..width {
tiles[(y, x)].id = TILE_FREEZE;
game_tiles[(y, x)].id = TILE_FREEZE;
freeze_tiles[(y, x)].id = 4;
}
for x in 0..=((center - fly_width) as usize) {
tiles[(y, x)].id = TILE_FREEZE;
game_tiles[(y, x)].id = TILE_FREEZE;
freeze_tiles[(y, x)].id = 4;
}
@ -76,7 +87,7 @@ impl MapGenerator for FlyGenerator {
}
let game_layer = GameLayer {
tiles: CompressedData::Loaded(tiles),
tiles: CompressedData::Loaded(game_tiles),
};
let front_layer = FrontLayer {

View file

@ -7,6 +7,7 @@ pub struct MazeGenerator;
impl MapGenerator for MazeGenerator {
fn generate<R: Rng + ?Sized>(
&self,
rng: &mut R,
mapres: &Path,
width: usize,

View file

@ -20,6 +20,7 @@ pub const TILE_SPAWN: u8 = 192;
pub trait MapGenerator {
fn generate<R: Rng + ?Sized>(
&self,
rng: &mut R,
mapres: &Path,
width: usize,
@ -27,13 +28,14 @@ pub trait MapGenerator {
) -> Result<TwMap>;
fn save_file<R: Rng + ?Sized>(
&self,
rng: &mut R,
mapres: &Path,
width: usize,
height: usize,
path: &Path,
) -> Result<()> {
let mut map = Self::generate(rng, mapres, width, height)?;
let mut map = self.generate(rng, mapres, width, height)?;
map.save_file(path)?;
Ok(())
}