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::color::Color;
|
||||||
use pixelfoo::point2d::Point2d;
|
use pixelfoo::point2d::Point2d;
|
||||||
use pixelfoo::rect2d::Rect2d;
|
use pixelfoo::rect2d::Rect2d;
|
||||||
|
use pixelfoo::v2;
|
||||||
use pixelfoo::vec2d::Vec2d;
|
use pixelfoo::vec2d::Vec2d;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
@ -21,10 +22,39 @@ enum Square {
|
|||||||
Fox,
|
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<()> {
|
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 {
|
for square in line {
|
||||||
let c = match square {
|
let c = match square {
|
||||||
Square::Empty => Color::blue(),
|
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;
|
const DEFAULT_ARG: usize = 10;
|
||||||
|
|
||||||
fn grow(board: &Board, pos: Point2d, grow: Square, die: Square) -> Square {
|
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() {
|
for dir in Vec2d::directions() {
|
||||||
let pos1 = pos + dir;
|
let pos1 = pos + dir;
|
||||||
if 0 <= pos1.x && pos1.x < x_size && 0 <= pos1.y && pos1.y < y_size {
|
if board.rect().contains(pos1) {
|
||||||
let neigh_sq = board[pos1.y as usize][pos1.x as usize];
|
let neigh_sq = board.get(pos);
|
||||||
if neigh_sq == grow {
|
if neigh_sq == grow {
|
||||||
return grow;
|
return grow;
|
||||||
}
|
}
|
||||||
@ -65,35 +93,28 @@ fn main() -> std::io::Result<()> {
|
|||||||
eprintln!("screen size {}x{}, arg {}", x_size, y_size, arg);
|
eprintln!("screen size {}x{}, arg {}", x_size, y_size, arg);
|
||||||
|
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
|
let size = v2!(x_size as i32, y_size as i32);
|
||||||
|
|
||||||
let p_empty = 0.25;
|
let p_empty = 0.25;
|
||||||
let p_grass = 0.25;
|
let p_grass = 0.25;
|
||||||
let p_rabbit = 0.25;
|
let p_rabbit = 0.25;
|
||||||
// p_fox = 0.05
|
// p_fox = 0.05
|
||||||
let mut board = repeat_with(|| {
|
let mut board = Board::new(size, || {
|
||||||
repeat_with(|| {
|
let p = rng.gen::<f64>();
|
||||||
let p = rng.gen::<f64>();
|
if p < p_empty {
|
||||||
if p < p_empty {
|
Square::Empty
|
||||||
Square::Empty
|
} else if p < p_empty + p_grass {
|
||||||
} else if p < p_empty + p_grass {
|
Square::Grass
|
||||||
Square::Grass
|
} else if p < p_empty + p_grass + p_rabbit {
|
||||||
} else if p < p_empty + p_grass + p_rabbit {
|
Square::Rabbit
|
||||||
Square::Rabbit
|
} else {
|
||||||
} else {
|
Square::Fox
|
||||||
Square::Fox
|
}
|
||||||
}
|
});
|
||||||
})
|
|
||||||
.take(x_size)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
})
|
|
||||||
.take(y_size)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let t_frame = 0.040; // s
|
let t_frame = 0.040; // s
|
||||||
let delay = Duration::new(0, (1_000_000_000.0 * t_frame) as u32);
|
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
|
// mid point of the board
|
||||||
let x_mid = (x_size - 1) as f64 / 2.0;
|
let x_mid = (x_size - 1) as f64 / 2.0;
|
||||||
let y_mid = (y_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 {
|
loop {
|
||||||
for _ in 0..arg {
|
for _ in 0..arg {
|
||||||
let pos = board_rect.random_point(&mut rng);
|
let pos = board.rect().random_point(&mut rng);
|
||||||
let sq = board[pos.y as usize][pos.x as usize];
|
let sq = board.get(pos);
|
||||||
let dx = (pos.x as f64 - x_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 dy = (pos.y as f64 - y_mid as f64) / r as f64;
|
||||||
let p0 = (dx * dx + dy * dy).min(1.0);
|
let p0 = (dx * dx + dy * dy).min(1.0);
|
||||||
@ -119,12 +140,15 @@ fn main() -> std::io::Result<()> {
|
|||||||
} else {
|
} else {
|
||||||
Square::Empty
|
Square::Empty
|
||||||
};
|
};
|
||||||
board[pos.y as usize][pos.x as usize] = match sq {
|
board.set(
|
||||||
Square::Empty => grow(&board, pos, Square::Grass, new_sq),
|
pos,
|
||||||
Square::Grass => grow(&board, pos, Square::Rabbit, new_sq),
|
match sq {
|
||||||
Square::Rabbit => grow(&board, pos, Square::Fox, new_sq),
|
Square::Empty => grow(&board, pos, Square::Grass, new_sq),
|
||||||
Square::Fox => 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);
|
let mut buf = Vec::with_capacity(x_size * y_size * 3);
|
||||||
|
Loading…
Reference in New Issue
Block a user