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.6 KiB

3 years ago
3 years ago
  1. use gntag::agent::{Agent, SimpleAgent};
  2. use gntag::view::TerminalView;
  3. use gntag::world::ActualWorld;
  4. use std::io;
  5. use std::io::Read;
  6. use std::process::exit;
  7. use std::sync::{Arc, Mutex};
  8. use std::thread;
  9. fn main() {
  10. let view = Arc::new(Mutex::new(Some(TerminalView::try_new().unwrap())));
  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. let (width, height) = (*view.lock().unwrap())
  26. .as_mut()
  27. .unwrap()
  28. .content_size()
  29. .unwrap();
  30. let mut agents: Vec<(_, Box<dyn Agent>)> = vec![];
  31. for x in (0..width).step_by(10) {
  32. for y in (0..height).step_by(10) {
  33. agents.push(((x, y).into(), Box::new(SimpleAgent)));
  34. }
  35. }
  36. let mut world = ActualWorld::new((width, height).into(), agents);
  37. let mut gen = 0;
  38. loop {
  39. let resized = (*view.lock().unwrap())
  40. .as_mut()
  41. .unwrap()
  42. .draw(
  43. gen,
  44. world
  45. .state
  46. .agent_positions
  47. .get(&world.state.tagged)
  48. .map(|pos| (pos.x, pos.y))
  49. .unwrap(),
  50. world
  51. .state
  52. .agent_positions
  53. .iter()
  54. .map(|(_id, pos)| (pos.x, pos.y))
  55. .collect::<Vec<_>>()
  56. .as_ref(),
  57. )
  58. .unwrap();
  59. if resized {
  60. break;
  61. };
  62. world.do_step();
  63. gen += 1;
  64. }
  65. }
  66. }