Replace the local implementation of 2d geometry by lowdim
This also forces an update of the rand dependency, so while we are at it we update all the dependencies.
This commit is contained in:
@ -1,18 +1,19 @@
|
||||
use std::env::args;
|
||||
use std::io::stdout;
|
||||
use std::io::Write;
|
||||
use std::iter::repeat_with;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use rand::thread_rng;
|
||||
use rand::Rng;
|
||||
|
||||
use lowdim::bb2d;
|
||||
use lowdim::p2d;
|
||||
use lowdim::Array2d;
|
||||
use lowdim::BBox2d;
|
||||
use lowdim::Point2d;
|
||||
|
||||
use pixelfoo::color::Color;
|
||||
use pixelfoo::point2d::Point2d;
|
||||
use pixelfoo::rect2d::Rect2d;
|
||||
use pixelfoo::vec2d::v2d;
|
||||
use pixelfoo::vec2d::Vec2d;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum Square {
|
||||
@ -22,40 +23,27 @@ enum Square {
|
||||
Fox,
|
||||
}
|
||||
|
||||
struct Board(Vec<Vec<Square>>);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Board(Array2d<i64, Square>);
|
||||
impl Board {
|
||||
pub fn new(size: Vec2d, mut f: impl FnMut() -> Square) -> Board {
|
||||
Board(
|
||||
repeat_with(|| {
|
||||
repeat_with(&mut f)
|
||||
.take(size.x as usize)
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.take(size.y as usize)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
pub fn new(bbox: BBox2d, mut f: impl FnMut() -> Square) -> Board {
|
||||
Board(Array2d::with(bbox, |_p| f()))
|
||||
}
|
||||
pub fn size(&self) -> Vec2d {
|
||||
let x_size = self.0[0].len() as i32;
|
||||
let y_size = self.0.len() as i32;
|
||||
v2d(x_size, y_size)
|
||||
fn bbox(&self) -> BBox2d {
|
||||
self.0.bbox()
|
||||
}
|
||||
pub fn rect(&self) -> Rect2d {
|
||||
Rect2d::new(0, self.size().x, 0, self.size().y)
|
||||
fn get(&self, pos: Point2d) -> Square {
|
||||
self.0[pos]
|
||||
}
|
||||
pub fn get(&self, pos: Point2d) -> Square {
|
||||
self.0[pos.y as usize][pos.x as usize]
|
||||
}
|
||||
pub fn set(&mut self, pos: Point2d, sq: Square) {
|
||||
self.0[pos.y as usize][pos.x as usize] = sq;
|
||||
fn set(&mut self, pos: Point2d, sq: Square) {
|
||||
self.0[pos] = sq;
|
||||
}
|
||||
}
|
||||
|
||||
fn send<T: Write>(w: &mut T, board: &Board) -> std::io::Result<()> {
|
||||
let Board(lines) = board;
|
||||
for line in lines {
|
||||
for square in line {
|
||||
for y in board.bbox().y_range() {
|
||||
for x in board.bbox().x_range() {
|
||||
let square = board.0[p2d(x, y)];
|
||||
let c = match square {
|
||||
Square::Empty => Color::blue(),
|
||||
Square::Grass => Color::green(),
|
||||
@ -68,11 +56,9 @@ fn send<T: Write>(w: &mut T, board: &Board) -> std::io::Result<()> {
|
||||
w.flush()
|
||||
}
|
||||
|
||||
const DEFAULT_ARG: usize = 10;
|
||||
|
||||
fn grow(board: &Board, pos: Point2d, grow: Square, die: Square) -> Square {
|
||||
for pos1 in pos.neighbours() {
|
||||
if board.rect().contains(pos1) {
|
||||
for pos1 in pos.neighbors_l1() {
|
||||
if board.bbox().contains(&pos1) {
|
||||
let neigh_sq = board.get(pos1);
|
||||
if neigh_sq == grow {
|
||||
return grow;
|
||||
@ -82,23 +68,24 @@ fn grow(board: &Board, pos: Point2d, grow: Square, die: Square) -> Square {
|
||||
die
|
||||
}
|
||||
|
||||
const DEFAULT_ARG: usize = 10;
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let args = args().collect::<Vec<_>>();
|
||||
eprintln!("executing {}", args[0]);
|
||||
|
||||
let x_size = args[1].parse::<usize>().unwrap();
|
||||
let y_size = args[2].parse::<usize>().unwrap();
|
||||
let x_size = args[1].parse::<i64>().unwrap();
|
||||
let y_size = args[2].parse::<i64>().unwrap();
|
||||
let arg = args[3].parse::<usize>().unwrap_or(DEFAULT_ARG);
|
||||
eprintln!("screen size {}x{}, arg {}", x_size, y_size, arg);
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let size = v2d(x_size as i32, y_size as i32);
|
||||
let bbox = bb2d(0..x_size, 0..y_size);
|
||||
|
||||
let p_empty = 0.25;
|
||||
let p_grass = 0.25;
|
||||
let p_rabbit = 0.25;
|
||||
// p_fox = 0.05
|
||||
let mut board = Board::new(size, || {
|
||||
let mut board = Board::new(bbox, || {
|
||||
let p = rng.gen::<f64>();
|
||||
if p < p_empty {
|
||||
Square::Empty
|
||||
@ -115,18 +102,18 @@ fn main() -> std::io::Result<()> {
|
||||
let delay = Duration::new(0, (1_000_000_000.0 * t_frame) as u32);
|
||||
|
||||
// mid point of the board
|
||||
let x_mid = (x_size - 1) as f64 / 2.0;
|
||||
let y_mid = (y_size - 1) as f64 / 2.0;
|
||||
let x_mid = (bbox.x_min() + bbox.x_max()) as f64 / 2.0;
|
||||
let y_mid = (bbox.y_min() + bbox.y_max()) as f64 / 2.0;
|
||||
|
||||
// radius of the death zone in the middle
|
||||
let r = (x_size.min(y_size) - 1) as f64 / 2.5;
|
||||
|
||||
loop {
|
||||
for _ in 0..arg {
|
||||
let pos = board.rect().random_point(&mut rng);
|
||||
let pos = bbox.random_point(&mut rng);
|
||||
let sq = board.get(pos);
|
||||
let dx = (pos.x as f64 - x_mid as f64) / r as f64;
|
||||
let dy = (pos.y as f64 - y_mid as f64) / r as f64;
|
||||
let dx = (pos.x() as f64 - x_mid as f64) / r as f64;
|
||||
let dy = (pos.y() as f64 - y_mid as f64) / r as f64;
|
||||
let p0 = (dx * dx + dy * dy).min(1.0);
|
||||
let p_survive = match sq {
|
||||
Square::Empty => 1.0,
|
||||
@ -150,7 +137,7 @@ fn main() -> std::io::Result<()> {
|
||||
);
|
||||
}
|
||||
|
||||
let mut buf = Vec::with_capacity(x_size * y_size * 3);
|
||||
let mut buf = Vec::with_capacity(bbox.area() * 3);
|
||||
send(&mut buf, &board)?;
|
||||
stdout().write_all(&buf)?;
|
||||
stdout().flush()?;
|
||||
|
Reference in New Issue
Block a user