A simple actor-based simulation of tag, implemented in rust.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
1.4 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  1. use gntag::get_world;
  2. use gntag::view::{Backend, TerminalView};
  3. use std::io;
  4. use std::io::Read;
  5. use std::process::exit;
  6. use std::sync::{Arc, Mutex};
  7. use std::thread;
  8. fn main() {
  9. let view = Arc::new(Mutex::new(Some(TerminalView::try_new().unwrap())));
  10. // Exit on q, ESC and Ctrl-C and reset terminal
  11. let view2 = view.clone();
  12. thread::spawn(move || {
  13. let stdin = io::stdin();
  14. for byte in stdin.bytes().flatten() {
  15. if byte == b'q' || byte == 0x1b || byte == 0x03 {
  16. if let Ok(mut view) = view2.lock() {
  17. *view = None; // drop view
  18. println!("\n");
  19. }
  20. exit(0);
  21. }
  22. }
  23. });
  24. loop {
  25. run_simulation(&view);
  26. }
  27. }
  28. fn run_simulation(view: &Arc<Mutex<Option<TerminalView<impl Backend>>>>) {
  29. let (width, height) = (*view.lock().unwrap())
  30. .as_mut()
  31. .unwrap()
  32. .content_size()
  33. .unwrap();
  34. let mut world = get_world(width, height, 10, true);
  35. let mut gen = 0;
  36. loop {
  37. let resized = (*view.lock().unwrap())
  38. .as_mut()
  39. .unwrap()
  40. .draw(
  41. gen,
  42. world
  43. .state
  44. .agent_positions
  45. .get(&world.state.tagged)
  46. .map(|pos| (pos.x, pos.y))
  47. .unwrap(),
  48. world
  49. .state
  50. .agent_positions
  51. .iter()
  52. .map(|(_id, pos)| (pos.x, pos.y))
  53. .collect::<Vec<_>>()
  54. .as_ref(),
  55. )
  56. .unwrap();
  57. if resized {
  58. return;
  59. };
  60. world.do_step();
  61. gen += 1;
  62. }
  63. }