Abstract out board in predator and prey.
This commit is contained in:
parent
1a1129d343
commit
4393f700bc
@ 11,6 +11,7 @@ use rand::Rng;


use pixelfoo::color::Color;


use pixelfoo::point2d::Point2d;


use pixelfoo::rect2d::Rect2d;


use pixelfoo::v2;


use pixelfoo::vec2d::Vec2d;




#[derive(Clone, Copy, Debug, PartialEq, Eq)]


@ 21,10 +22,39 @@ enum Square {


Fox,


}




type Board = Vec<Vec<Square>>;


struct Board(Vec<Vec<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 size(&self) > Vec2d {


let x_size = self.0[0].len() as i32;


let y_size = self.0.len() as i32;


v2!(x_size, y_size)


}


pub fn rect(&self) > Rect2d {


Rect2d::new(0, self.size().x, 0, self.size().y)


}


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 send<T: Write>(w: &mut T, board: &Board) > std::io::Result<()> {


for line in board {


let Board(lines) = board;


for line in lines {


for square in line {


let c = match square {


Square::Empty => Color::blue(),


@ 41,12 +71,10 @@ fn send<T: Write>(w: &mut T, board: &Board) > std::io::Result<()> {


const DEFAULT_ARG: usize = 10;




fn grow(board: &Board, pos: Point2d, grow: Square, die: Square) > Square {


let x_size = board[0].len() as i32;


let y_size = board.len() as i32;


for dir in Vec2d::directions() {


let pos1 = pos + dir;


if 0 <= pos1.x && pos1.x < x_size && 0 <= pos1.y && pos1.y < y_size {


let neigh_sq = board[pos1.y as usize][pos1.x as usize];


if board.rect().contains(pos1) {


let neigh_sq = board.get(pos);


if neigh_sq == grow {


return grow;


}


@ 65,35 +93,28 @@ fn main() > std::io::Result<()> {


eprintln!("screen size {}x{}, arg {}", x_size, y_size, arg);




let mut rng = thread_rng();


let size = v2!(x_size as i32, y_size as i32);




let p_empty = 0.25;


let p_grass = 0.25;


let p_rabbit = 0.25;


// p_fox = 0.05


let mut board = repeat_with( {


repeat_with( {


let p = rng.gen::<f64>();


if p < p_empty {


Square::Empty


} else if p < p_empty + p_grass {


Square::Grass


} else if p < p_empty + p_grass + p_rabbit {


Square::Rabbit


} else {


Square::Fox


}


})


.take(x_size)


.collect::<Vec<_>>()


})


.take(y_size)


.collect::<Vec<_>>();


let mut board = Board::new(size,  {


let p = rng.gen::<f64>();


if p < p_empty {


Square::Empty


} else if p < p_empty + p_grass {


Square::Grass


} else if p < p_empty + p_grass + p_rabbit {


Square::Rabbit


} else {


Square::Fox


}


});




let t_frame = 0.040; // s


let delay = Duration::new(0, (1_000_000_000.0 * t_frame) as u32);




let board_rect = Rect2d::new(0, x_size as i32, 0, y_size as i32);




// 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;


@ 103,8 +124,8 @@ fn main() > std::io::Result<()> {




loop {


for _ in 0..arg {


let pos = board_rect.random_point(&mut rng);


let sq = board[pos.y as usize][pos.x as usize];


let pos = board.rect().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 p0 = (dx * dx + dy * dy).min(1.0);


@ 119,12 +140,15 @@ fn main() > std::io::Result<()> {


} else {


Square::Empty


};


board[pos.y as usize][pos.x as usize] = match sq {


Square::Empty => grow(&board, pos, Square::Grass, new_sq),


Square::Grass => grow(&board, pos, Square::Rabbit, new_sq),


Square::Rabbit => grow(&board, pos, Square::Fox, new_sq),


Square::Fox => new_sq,


};


board.set(


pos,


match sq {


Square::Empty => grow(&board, pos, Square::Grass, new_sq),


Square::Grass => grow(&board, pos, Square::Rabbit, new_sq),


Square::Rabbit => grow(&board, pos, Square::Fox, new_sq),


Square::Fox => new_sq,


},


);


}




let mut buf = Vec::with_capacity(x_size * y_size * 3);



Loading…
Reference in New Issue
Block a user