mirror of
https://github.com/cccb/servicepoint.git
synced 2025-01-18 18:10:14 +01:00
92 lines
2.3 KiB
Rust
92 lines
2.3 KiB
Rust
//! A simple game of life implementation to show how to render graphics to the display.
|
|
|
|
use std::thread;
|
|
|
|
use clap::Parser;
|
|
use rand::{distributions, Rng};
|
|
|
|
use servicepoint::*;
|
|
|
|
#[derive(Parser, Debug)]
|
|
struct Cli {
|
|
#[arg(short, long, default_value = "localhost:2342")]
|
|
destination: String,
|
|
#[arg(short, long, default_value_t = 0.5f64)]
|
|
probability: f64,
|
|
}
|
|
|
|
fn main() {
|
|
let cli = Cli::parse();
|
|
|
|
let connection = Connection::open(&cli.destination)
|
|
.expect("could not connect to display");
|
|
let mut field = make_random_field(cli.probability);
|
|
|
|
loop {
|
|
let command = Command::BitmapLinearWin(
|
|
Origin::ZERO,
|
|
field.clone(),
|
|
CompressionCode::Lzma,
|
|
);
|
|
connection.send(command).expect("could not send");
|
|
thread::sleep(FRAME_PACING);
|
|
field = iteration(field);
|
|
}
|
|
}
|
|
|
|
fn iteration(field: Bitmap) -> Bitmap {
|
|
let mut next = field.clone();
|
|
for x in 0..field.width() {
|
|
for y in 0..field.height() {
|
|
let old_state = field.get(x, y);
|
|
let neighbors = count_neighbors(&field, x as i32, y as i32);
|
|
|
|
let new_state = matches!(
|
|
(old_state, neighbors),
|
|
(true, 2) | (true, 3) | (false, 3)
|
|
);
|
|
next.set(x, y, new_state);
|
|
}
|
|
}
|
|
next
|
|
}
|
|
|
|
fn count_neighbors(field: &Bitmap, x: i32, y: i32) -> i32 {
|
|
let mut count = 0;
|
|
for nx in x - 1..=x + 1 {
|
|
for ny in y - 1..=y + 1 {
|
|
if nx == x && ny == y {
|
|
continue; // the cell itself does not count
|
|
}
|
|
|
|
if nx < 0
|
|
|| ny < 0
|
|
|| nx >= field.width() as i32
|
|
|| ny >= field.height() as i32
|
|
{
|
|
continue; // pixels outside the grid do not count
|
|
}
|
|
|
|
if !field.get(nx as usize, ny as usize) {
|
|
continue; // dead cells do not count
|
|
}
|
|
|
|
count += 1;
|
|
}
|
|
}
|
|
|
|
count
|
|
}
|
|
|
|
fn make_random_field(probability: f64) -> Bitmap {
|
|
let mut field = Bitmap::max_sized();
|
|
let mut rng = rand::thread_rng();
|
|
let d = distributions::Bernoulli::new(probability).unwrap();
|
|
for x in 0..field.width() {
|
|
for y in 0..field.height() {
|
|
field.set(x, y, rng.sample(d));
|
|
}
|
|
}
|
|
field
|
|
}
|