+use common::Point2D;
+use core::render::Renderer;
+use rand::Rng;
+use sprites::SpriteManager;
+
+////////// LEVEL ///////////////////////////////////////////////////////////////
+
+#[derive(Default)]
+pub struct Level {
+ pub gravity: Point2D<f64>,
+ pub ground: f64, // just to have something
+ pub grid: Grid,
+ iterations: u8,
+}
+
+impl Level {
+ pub fn new(gravity: Point2D<f64>, ground: f64) -> Self {
+ Level { gravity, ground, grid: Grid::generate(10), iterations: 10 }
+ }
+
+ pub fn regenerate(&mut self) {
+ self.grid = Grid::generate(self.iterations);
+ }
+
+ pub fn increase_iteration(&mut self) {
+ self.iterations += 1;
+ self.regenerate();
+ println!("iterate {} time(s)", self.iterations);
+ }
+
+ pub fn decrease_iteration(&mut self) {
+ self.iterations -= 1;
+ self.regenerate();
+ println!("iterate {} time(s)", self.iterations);
+ }
+
+ pub fn render(&mut self, renderer: &mut Renderer, _sprites: &SpriteManager) {
+ let w = renderer.viewport().0 as i32;
+
+ renderer.canvas().set_draw_color((64, 64, 64));
+ let size = self.grid.cell_size;
+ for x in 0..self.grid.width {
+ for y in 0..self.grid.height {
+ if self.grid.cells[x][y] {
+ renderer.canvas().fill_rect(sdl2::rect::Rect::new(x as i32 * size as i32, y as i32 * size as i32, size as u32, size as u32)).unwrap();
+ }
+ }
+ }
+
+ for i in 1..11 {
+ let y = (i * i - 1) as i32 + self.ground as i32;
+ renderer.canvas().set_draw_color((255 - i * 20, 255 - i * 20, 0));
+ renderer.canvas().draw_line((0, y), (w, y)).unwrap();
+ }
+ }
+}
+
+////////// GRID ////////////////////////////////////////////////////////////////
+
+#[derive(Default)]
+pub struct Grid {
+ pub width: usize,
+ pub height: usize,
+ pub cell_size: usize,
+ pub cells: Vec<Vec<bool>>,
+}
+
+impl Grid {
+ fn generate(iterations: u8) -> Grid {
+ let cell_size = 10;
+ let (width, height) = (1280 / cell_size, 600 / cell_size);
+ let mut cells = vec!(vec!(true; height); width);
+
+ let mut rng = rand::thread_rng();
+
+ // randomize
+ for x in 1..(width - 1) {
+ for y in 1..(height - 1) {
+ cells[x][y] = rng.gen_range(0, 100) > 55;
+ }
+ }
+
+ // smooth
+ // let mut count = 0;
+ // loop {
+ // count += 1;
+ // println!("iteration {}", count);
+ for _i in 0..iterations {
+ let mut next = vec!(vec!(true; height); width);
+ for x in 1..(width - 1) {
+ for y in 1..(height - 1) {
+ match Grid::neighbours(&cells, x, y) {
+ n if n < 4 => next[x][y] = false,
+ n if n > 4 => next[x][y] = true,
+ _ => next[x][y] = cells[x][y]
+ };
+ }
+ }
+ if cells == next {
+ break;
+ } else {
+ cells = next;
+ }
+ }
+
+ Grid {
+ width,
+ height,
+ cell_size,
+ cells
+ }
+ }
+
+ fn neighbours(grid: &Vec<Vec<bool>>, px: usize, py: usize) -> u8 {
+ let mut count = 0;
+ for x in (px - 1)..=(px + 1) {
+ for y in (py - 1)..=(py + 1) {
+ if !(x == px && y == py) && grid[x][y] {
+ count += 1;
+ }
+ }
+ }
+ count
+ }
+}