use game_loop::game_loop;
fn main() {
let mut game = GameOfLife::new(12, 12);
game.set(5, 5);
game.set(5, 6);
game.set(5, 7);
game.set(6, 6);
let g = game_loop(game, 2, 1.0, |g| {
g.game.update();
}, |g| {
g.game.render(g.blending_factor());
if g.running_time() > 10.0 {
g.exit();
}
});
println!("Exiting after {} seconds", g.running_time());
println!("");
println!("Last frame time: {}", g.last_frame_time());
println!("Number of updates: {}", g.number_of_updates());
println!("Number of renders: {}", g.number_of_renders());
}
struct GameOfLife {
board: Board,
width: usize,
height: usize,
}
type Board = Vec<Vec<bool>>;
impl GameOfLife {
fn new(width: usize, height: usize) -> Self {
let board = vec![vec![false; width]; height];
Self { board, width, height }
}
fn set(&mut self, x: usize, y: usize) {
self.board[y][x] = true;
}
fn update(&mut self) {
self.board = self.next_board();
}
fn next_board(&self) -> Board {
(0..self.height).map(|y| {
(0..self.width).map(|x| {
self.next_cell(x, y)
}).collect()
}).collect()
}
fn next_cell(&self, x: usize, y: usize) -> bool {
let cell = self.board[y][x];
let count = self.alive_neighbors(x as isize, y as isize);
count == 3 || (cell && count == 2)
}
fn alive_neighbors(&self, x: isize, y: isize) -> usize {
self.neighbors(x, y).iter().filter(|b| **b).count()
}
fn neighbors(&self, x: isize, y: isize) -> [bool; 8] {
[
self.neighbor(x - 1, y - 1), self.neighbor(x , y - 1), self.neighbor(x + 1, y - 1), self.neighbor(x - 1, y ), self.neighbor(x + 1, y ), self.neighbor(x - 1, y + 1), self.neighbor(x , y + 1), self.neighbor(x + 1, y + 1), ]
}
fn neighbor(&self, x: isize, y: isize) -> bool {
if x < 0 { return false; }
if y < 0 { return false; }
*self.board
.get(y as usize).unwrap_or(&vec![])
.get(x as usize).unwrap_or(&false)
}
fn render(&self, _blending_factor: f64) {
print!("{}[2J", 27 as char); for row in self.board.iter() {
for cell in row {
if *cell {
print!("X");
} else {
print!("_");
}
}
println!();
}
println!();
std::thread::sleep(std::time::Duration::from_millis(100));
}
}