Created
April 26, 2019 16:58
-
-
Save IzioDev/ae985727e526829816113d62d2207ed2 to your computer and use it in GitHub Desktop.
I'm a dumbass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate rand; | |
use std::process; | |
use rand::Rng; | |
use world::World; | |
pub mod world; | |
pub fn create_world(n_col: usize, n_row: usize) -> World { | |
let mut _world = World::new(n_col, n_row).unwrap_or_else(|err| { | |
println!("ERROR: {:?}", err); | |
process::exit(1); | |
}); | |
_world.init_world(); | |
let mut rng = rand::thread_rng(); | |
let island_radius = rng.gen_range(4, 8); | |
let p: world::Point = world::Point { | |
x: rng.gen_range(island_radius, n_col - island_radius), | |
y: rng.gen_range(island_radius, n_row - island_radius), | |
}; | |
_world.create_island(p, island_radius).unwrap(); | |
_world | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MAIN.RS | |
extern crate rsurvive; | |
use rsurvive::{create_world}; | |
use rsurvive::world; | |
fn main() { | |
let mut _world = create_world(50, 50); | |
// println!("{}", _world); | |
_world.create_image(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate ansi_term; | |
mod heli; | |
use ansi_term::Colour::*; | |
use heli::Heli; | |
use std::path::Path; | |
#[derive(Debug)] | |
pub struct Point { | |
pub x: usize, | |
pub y: usize, | |
} | |
#[derive(Debug)] | |
pub struct PointVal { | |
pub x: usize, | |
pub y: usize, | |
pub val: usize, | |
} | |
#[derive(Debug)] | |
pub struct World { | |
pub grid: Grid, | |
pub init: bool, | |
} | |
#[derive(Debug)] | |
pub struct Grid { | |
pub get: Box<[usize]>, | |
pub width: usize, | |
pub height: usize, | |
pub heli: Heli, | |
} | |
impl PointVal { | |
/// Get distance to another `PointVal` | |
/// TODO: be human friendly | |
pub fn get_distance_to<'a>(&self, p: PointVal) -> f64 { | |
(((p.x - self.x).pow(2) + (p.y - self.y).pow(2)) as f64).sqrt() | |
} | |
} | |
impl Grid { | |
/// Get a `Point` at coords | |
/// # Arguments | |
/// | |
/// * `x` - length | |
/// * `y` - high | |
/// | |
/// # Returns | |
/// | |
/// * Point or Err(&str) | |
pub fn get<'a>(&self, x: usize, y: usize) -> Result<PointVal, &'a str> { | |
if x > self.width || y > self.height { | |
Err("Grid bound reached.") | |
} else { | |
Ok( | |
PointVal { | |
x, | |
y, | |
val: self.get[(self.height * y) + x], | |
} | |
) | |
} | |
} | |
/// Set a value at coords | |
/// # Arguments | |
/// | |
/// * `x` - length | |
/// * `y` - high | |
/// * `val` - value to set | |
/// | |
/// # Returns | |
/// | |
/// * () or Err(&str) | |
pub fn set<'a>(&mut self, x: isize, y: isize, val: usize) -> Result<(), &'a str> { | |
if x > self.width as isize || y > self.height as isize { | |
Err("Grid bound reached.") | |
} else { | |
let _i = (self.height as isize * y) + x; | |
self.get[_i as usize] = val; | |
Ok(()) | |
} | |
} | |
/// Set a value on line `x` from `a` to `b` with value `val` | |
/// # Arguments | |
/// | |
/// * `x` - line index (starts at 0) | |
/// * `a` - begining index of the column | |
/// * `b` - end index of the column | |
/// * `val` - value to fill with | |
/// | |
/// ### TODO: find a workaround or create an util function to do Error formating | |
/// | |
/// # Returns | |
/// | |
/// * () or Err(&str) | |
pub fn fill_line_with<'a>(&mut self, x: isize, a: isize, b: isize, val: usize) -> Result<(), &'a str> { | |
if a > self.width as isize || b > self.width as isize { | |
Err("Grid width bound reached.") | |
} else if x > self.height as isize { | |
Err("Grid heigth bound reached.") | |
} else { | |
if b < a { | |
// TODO: find a workaround or create an util function to do this | |
Err(Box::leak(format!("Expected a < b, got: a={} b={}.", a, b).into_boxed_str())) | |
} else { | |
for i in a..b + 1 { | |
self.set(i, x, val)?; | |
} | |
Ok(()) | |
} | |
} | |
} | |
} | |
impl World { | |
/// Create a World | |
/// # Arguments | |
/// | |
/// * `heigth` - heigth of the grid | |
/// * `width` - width of the grid | |
/// | |
/// # Returns | |
/// | |
/// * World or Err(&str) | |
pub fn new<'a>(height: usize, width: usize) -> Result<World, &'a str> { | |
if height == 0 || width == 0 { | |
return Err("Expecting positive values for width and heigth."); | |
} | |
let grid = Grid { | |
get: vec![0; height * width].into_boxed_slice(), | |
width, | |
height, | |
heli: Heli { | |
x: 0, | |
y: 0, | |
fuel: 0, | |
}, | |
}; | |
Ok(World { | |
grid, | |
init: false, | |
}) | |
} | |
/// initializes the `World` instance | |
pub fn init_world(&mut self) { | |
self.init = true; | |
} | |
/// Create an island on the grid | |
/// For instance, it creates a circle | |
/// ### TODO: create a random polygon shape | |
/// # Arguments | |
/// | |
/// * `center` - center taken to generate de island - __must be a valid point__ | |
/// * `radius` - radius wanted - __must be > 0__ | |
pub fn create_island<'a>(&mut self, center: Point, radius: usize) -> Result<(), &'a str> { | |
// ensure the grid is init | |
if !self.init { return Err("World is not initialized"); } | |
// ensure we are using a valid center point | |
if center.x > self.grid.width { return Err("Center is not in the grid"); } | |
if center.y > self.grid.height { return Err("Center is not in the grid"); } | |
// cast to signed | |
let _xi = center.x as isize; | |
let _yi = center.y as isize; | |
let _radiusi = radius as isize; | |
// ensure the circle will not "eat" the border | |
if (_xi - _radiusi < 0) || (center.x + radius >= self.grid.width) | |
|| | |
(_yi - _radiusi < 0) || (center.y + radius >= self.grid.height) | |
{ | |
return Err("Circle cannot cross the grid boundary"); | |
} | |
let mut width = _radiusi - 1; | |
let mut line_number = 2; | |
self.grid.fill_line_with(_yi, _xi - width - 1, _xi + width + 1, 1)?; | |
for line in _yi + 1.._yi + _radiusi + 1 { | |
self.grid.fill_line_with(line, _xi - width, _xi + width, 1)?; | |
self.grid.fill_line_with(line - line_number, _xi - width, _xi + width, 1)?; | |
width = width - 1; | |
line_number = line_number + 2; | |
} | |
Ok(()) | |
} | |
pub fn create_image<'a>(path: &Path) -> Result<(), &'a str> { | |
Ok(()) | |
} | |
} | |
impl std::fmt::Display for World { | |
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | |
let mut i = 0; | |
for item in self.grid.get.iter() { | |
if i % self.grid.width == 0 { | |
write!(f, "\n")?; | |
} | |
if *item == 1 { | |
write!(f, "{}", Red.bold().paint("1"))?; | |
} else { | |
write!(f, "{}", item)?; | |
} | |
i = i + 1; | |
} | |
Ok(()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment