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.

67 lines
1.7 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  1. pub mod agent;
  2. pub mod view;
  3. pub mod world;
  4. use agent::{Agent, SimpleAgent};
  5. use std::error::Error;
  6. use std::io;
  7. use std::io::Read;
  8. use std::process::exit;
  9. use std::sync::{Arc, Mutex};
  10. use std::thread;
  11. use view::{RawTerminal, TerminalView, TermionBackend};
  12. use world::ActualWorld;
  13. pub fn get_world(width: isize, height: isize, spacing: usize, validating: bool) -> ActualWorld {
  14. let mut agents: Vec<(_, Box<dyn Agent>)> = vec![];
  15. for x in (0..width).step_by(spacing) {
  16. for y in (0..height).step_by(spacing) {
  17. agents.push(((x, y).into(), Box::new(SimpleAgent)));
  18. }
  19. }
  20. ActualWorld::new((width, height).into(), agents, validating)
  21. }
  22. pub type DefaultView = Arc<Mutex<Option<TerminalView<TermionBackend<RawTerminal<io::Stdout>>>>>>;
  23. pub fn get_view() -> DefaultView {
  24. let view = Arc::new(Mutex::new(Some(TerminalView::try_new().unwrap())));
  25. // Exit on q, ESC and Ctrl-C and reset terminal
  26. let view2 = view.clone();
  27. thread::spawn(move || {
  28. let stdin = io::stdin();
  29. for byte in stdin.bytes().flatten() {
  30. if byte == b'q' || byte == 0x1b || byte == 0x03 {
  31. if let Ok(mut view) = view2.lock() {
  32. *view = None; // drop view
  33. println!("\n");
  34. }
  35. exit(0);
  36. }
  37. }
  38. });
  39. view
  40. }
  41. pub fn draw_world(
  42. world: &ActualWorld,
  43. gen: usize,
  44. view: &DefaultView,
  45. ) -> Result<bool, Box<dyn Error>> {
  46. (*view.lock().unwrap()).as_mut().unwrap().draw(
  47. gen,
  48. world
  49. .state
  50. .agent_positions
  51. .get(&world.state.tagged)
  52. .map(|pos| (pos.x, pos.y))
  53. .unwrap(),
  54. world
  55. .state
  56. .agent_positions
  57. .iter()
  58. .map(|(_id, pos)| (pos.x, pos.y))
  59. .collect::<Vec<_>>()
  60. .as_ref(),
  61. )
  62. }