Skip to content

Instantly share code, notes, and snippets.

@IzioDev
Created April 26, 2019 16:58
Show Gist options
  • Save IzioDev/ae985727e526829816113d62d2207ed2 to your computer and use it in GitHub Desktop.
Save IzioDev/ae985727e526829816113d62d2207ed2 to your computer and use it in GitHub Desktop.
I'm a dumbass
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
}
// 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();
}
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