use gntag::agent::{Agent, SimpleAgent}; use gntag::view::{Backend, TerminalView}; use gntag::world::ActualWorld; use std::io; use std::io::Read; use std::process::exit; use std::sync::{Arc, Mutex}; use std::thread; fn main() { let view = Arc::new(Mutex::new(Some(TerminalView::try_new().unwrap()))); // Exit on q, ESC and Ctrl-C and reset terminal let view2 = view.clone(); thread::spawn(move || { let stdin = io::stdin(); for byte in stdin.bytes().flatten() { if byte == b'q' || byte == 0x1b || byte == 0x03 { if let Ok(mut view) = view2.lock() { *view = None; // drop view println!("\n"); } exit(0); } } }); loop { run_simulation(&view); } } fn run_simulation(view: &Arc>>>) { let (width, height) = (*view.lock().unwrap()) .as_mut() .unwrap() .content_size() .unwrap(); let mut agents: Vec<(_, Box)> = vec![]; for x in (0..width).step_by(10) { for y in (0..height).step_by(10) { agents.push(((x, y).into(), Box::new(SimpleAgent))); } } let mut world = ActualWorld::new((width, height).into(), agents, true); let mut gen = 0; loop { let resized = (*view.lock().unwrap()) .as_mut() .unwrap() .draw( gen, world .state .agent_positions .get(&world.state.tagged) .map(|pos| (pos.x, pos.y)) .unwrap(), world .state .agent_positions .iter() .map(|(_id, pos)| (pos.x, pos.y)) .collect::>() .as_ref(), ) .unwrap(); if resized { return; }; world.do_step(); gen += 1; } }