use std::collections::BTreeSet;
use n18map::HexAddress;
use n18tile::Connection;
use crate::conflict::RouteConflicts;
use crate::Conflict;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Step {
pub addr: HexAddress,
pub conn: Connection,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum StopLocation {
City { ix: usize },
Dit { ix: usize },
}
impl StopLocation {
pub fn is_city(&self) -> bool {
matches!(self, StopLocation::City { .. })
}
pub fn is_dit(&self) -> bool {
matches!(self, StopLocation::Dit { .. })
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Visit {
pub addr: HexAddress,
pub revenue: usize,
pub visits: StopLocation,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Path {
pub steps: Vec<Step>,
pub conflicts: BTreeSet<Conflict>,
pub route_conflicts: RouteConflicts,
pub visits: Vec<Visit>,
pub num_visits: usize,
pub num_cities: usize,
pub num_dits: usize,
pub num_hexes: usize,
pub revenue: usize,
}
impl Path {
pub fn start(&self) -> &Visit {
self.visits.first().unwrap()
}
pub fn end(&self) -> &Visit {
self.visits.last().unwrap()
}
pub(crate) fn append(&self, other: &Path) -> Path {
if self.steps[0] != other.steps[0] {
panic!(
"Paths don't start from the same location: {:?} and {:?}",
self.steps[0], other.steps[0]
);
}
let mut steps = self.steps.clone();
let mut other_steps: Vec<_> =
other.steps[1..].iter().copied().collect();
steps.append(&mut other_steps);
let mut visits = self.visits.clone();
let mut other_visits: Vec<_> =
other.visits[1..].iter().copied().collect();
visits.reverse();
visits.append(&mut other_visits);
let conflicts: BTreeSet<_> =
self.conflicts.union(&other.conflicts).copied().collect();
let route_conflicts =
self.route_conflicts.merge(&other.route_conflicts);
let start_revenue = self.visits[0].revenue;
let revenue = self.revenue + other.revenue - start_revenue;
let num_visits = visits.len();
let num_cities = self.num_cities + other.num_cities - 1;
let num_dits = self.num_dits + other.num_dits;
let num_hexes = self.num_hexes + other.num_hexes - 1;
Path {
steps,
conflicts,
route_conflicts,
visits,
num_visits,
num_cities,
num_dits,
num_hexes,
revenue,
}
}
}