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.
		
		
		
		
		
			
		
			
				
					
					
						
							122 lines
						
					
					
						
							2.2 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							122 lines
						
					
					
						
							2.2 KiB
						
					
					
				
								pub type Distance = isize;
							 | 
						|
								
							 | 
						|
								pub struct Position {
							 | 
						|
								  pub x: Distance,
							 | 
						|
								  pub y: Distance,
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								impl From<(Distance, Distance)> for Position {
							 | 
						|
								  fn from((x, y): (Distance, Distance)) -> Self {
							 | 
						|
								    Self { x, y }
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								#[derive(Debug)]
							 | 
						|
								pub struct Direction {
							 | 
						|
								  pub x: Distance,
							 | 
						|
								  pub y: Distance,
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								impl From<(Distance, Distance)> for Direction {
							 | 
						|
								  fn from((x, y): (Distance, Distance)) -> Self {
							 | 
						|
								    Self { x, y }
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								pub type AgentId = usize;
							 | 
						|
								
							 | 
						|
								pub struct WorldView {
							 | 
						|
								  pub self_id: AgentId,
							 | 
						|
								  pub tagged: AgentId,
							 | 
						|
								  pub tagged_by: Option<AgentId>,
							 | 
						|
								  pub bounds_distance: (Distance, Distance, Distance, Distance),
							 | 
						|
								  pub other_agents: Vec<(Direction, AgentId)>,
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								#[derive(Debug)]
							 | 
						|
								pub enum Move {
							 | 
						|
								  Noop, // Why not an Option?
							 | 
						|
								  TryTag(AgentId),
							 | 
						|
								  TryMove(Direction),
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								pub trait Agent {
							 | 
						|
								  fn next_move(&self, view: WorldView) -> Move;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								pub struct NullAgent;
							 | 
						|
								
							 | 
						|
								impl Agent for NullAgent {
							 | 
						|
								  fn next_move(&self, _view: WorldView) -> Move {
							 | 
						|
								    Move::Noop
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								use std::cell::RefCell;
							 | 
						|
								
							 | 
						|
								pub struct ScriptedAgent {
							 | 
						|
								  moves: RefCell<Vec<Move>>,
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								impl ScriptedAgent {
							 | 
						|
								  pub fn new(mut moves: Vec<Move>) -> Self {
							 | 
						|
								    moves.reverse();
							 | 
						|
								    Self {
							 | 
						|
								      moves: RefCell::new(moves),
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								impl Agent for ScriptedAgent {
							 | 
						|
								  fn next_move(&self, _view: WorldView) -> Move {
							 | 
						|
								    self
							 | 
						|
								      .moves
							 | 
						|
								      .borrow_mut()
							 | 
						|
								      .pop()
							 | 
						|
								      .expect("ScriptedAgent has no moves left to make")
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								pub struct SimpleAgent;
							 | 
						|
								
							 | 
						|
								fn rand(exclusive_upper_bound: u32) -> u32 {
							 | 
						|
								  std::time::SystemTime::now()
							 | 
						|
								    .duration_since(std::time::UNIX_EPOCH)
							 | 
						|
								    .unwrap()
							 | 
						|
								    .subsec_micros()
							 | 
						|
								    % exclusive_upper_bound
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								fn random_move() -> Move {
							 | 
						|
								  Move::TryMove(
							 | 
						|
								    match rand(8) {
							 | 
						|
								      0 => (-1, -1),
							 | 
						|
								      1 => (0, -1),
							 | 
						|
								      2 => (1, -1),
							 | 
						|
								      3 => (1, 0),
							 | 
						|
								      4 => (1, 1),
							 | 
						|
								      5 => (0, 1),
							 | 
						|
								      6 => (-1, 1),
							 | 
						|
								      7 => (-1, 0),
							 | 
						|
								      _ => unreachable!(),
							 | 
						|
								    }
							 | 
						|
								    .into(),
							 | 
						|
								  )
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								impl Agent for SimpleAgent {
							 | 
						|
								  fn next_move(&self, view: WorldView) -> Move {
							 | 
						|
								    if view.self_id == view.tagged {
							 | 
						|
								      match view
							 | 
						|
								        .other_agents
							 | 
						|
								        .iter()
							 | 
						|
								        .find(|(dist, id)| dist.x.abs() <= 1 && dist.y.abs() <= 1 && Some(*id) != view.tagged_by)
							 | 
						|
								      {
							 | 
						|
								        Some((_, other)) => Move::TryTag(*other),
							 | 
						|
								        None => random_move(),
							 | 
						|
								      }
							 | 
						|
								    } else {
							 | 
						|
								      random_move()
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								}
							 |