Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions backend/src/calc/exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,14 @@ mod tests {
assert_eq!(
calc_exit(
&universe,
&universe.star_map[&1],
&universe.star_map[&SolarSystemId(1)],
Meters::from_light_years(10.0)
),
vec![
(universe.star_map[&1].clone(), universe.star_map[&2].clone()),
(
universe.star_map[&SolarSystemId(1)].clone(),
universe.star_map[&SolarSystemId(2)].clone()
),
// via SmartGate
// (universe.star_map[&3].clone(), universe.star_map[&2].clone()),
]
Expand Down
65 changes: 54 additions & 11 deletions backend/src/calc/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,17 @@ mod tests {
fn test_path_fuel_prefer_gate_over_jump() {
let universe = Universe::tiny_test();
assert_eq!(
call_calc_path(&universe, 1, 4, 25.0, PathOptimize::Fuel, true),
PathResult::Found(vec![universe.star_map[&1].connections[0].clone()])
call_calc_path(
&universe,
SolarSystemId(1),
SolarSystemId(4),
25.0,
PathOptimize::Fuel,
true
),
PathResult::Found(vec![
universe.star_map[&SolarSystemId(1)].connections[0].clone()
])
);
}

Expand All @@ -139,10 +148,17 @@ mod tests {
fn test_path_fuel_prefer_more_hops_over_more_fuel() {
let universe = Universe::tiny_test();
assert_eq!(
call_calc_path(&universe, 4, 2, 25.0, PathOptimize::Fuel, false),
call_calc_path(
&universe,
SolarSystemId(4),
SolarSystemId(2),
25.0,
PathOptimize::Fuel,
false
),
PathResult::Found(vec![
universe.star_map[&4].connections[0].clone(),
universe.star_map[&1].connections[1].clone(),
universe.star_map[&SolarSystemId(4)].connections[0].clone(),
universe.star_map[&SolarSystemId(1)].connections[1].clone(),
])
);
}
Expand All @@ -152,8 +168,17 @@ mod tests {
fn test_path_distance() {
let universe = Universe::tiny_test();
assert_eq!(
call_calc_path(&universe, 2, 4, 25.0, PathOptimize::Distance, false),
PathResult::Found(vec![universe.star_map[&2].connections[2].clone(),])
call_calc_path(
&universe,
SolarSystemId(2),
SolarSystemId(4),
25.0,
PathOptimize::Distance,
false
),
PathResult::Found(vec![
universe.star_map[&SolarSystemId(2)].connections[2].clone(),
])
);
}

Expand All @@ -162,8 +187,17 @@ mod tests {
fn test_path_hops_jump_if_smart_gate_disabled() {
let universe = Universe::tiny_test();
assert_eq!(
call_calc_path(&universe, 4, 3, 25.0, PathOptimize::Hops, false),
PathResult::Found(vec![universe.star_map[&4].connections[4].clone()])
call_calc_path(
&universe,
SolarSystemId(4),
SolarSystemId(3),
25.0,
PathOptimize::Hops,
false
),
PathResult::Found(vec![
universe.star_map[&SolarSystemId(4)].connections[4].clone()
])
);
}

Expand All @@ -172,8 +206,17 @@ mod tests {
fn test_path_hops_use_smart_gate_if_smart_gate_enabled() {
let universe = Universe::tiny_test();
assert_eq!(
call_calc_path(&universe, 4, 3, 25.0, PathOptimize::Hops, true),
PathResult::Found(vec![universe.star_map[&4].connections[1].clone()])
call_calc_path(
&universe,
SolarSystemId(4),
SolarSystemId(3),
25.0,
PathOptimize::Hops,
true
),
PathResult::Found(vec![
universe.star_map[&SolarSystemId(4)].connections[1].clone()
])
);
}
}
Expand Down
8 changes: 5 additions & 3 deletions backend/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,13 @@ fn main() -> anyhow::Result<()> {
let smart_gates: Vec<raw::RawSmartGate> =
serde_json::from_str(&std::fs::read_to_string("data/smartgates.json")?)?;
for gate in smart_gates.iter() {
let Some(to_star) = star_map.get(&gate.to).cloned() else {
let from_id = data::SolarSystemId::from(gate.from);
let to_id = data::SolarSystemId::from(gate.to);
let Some(to_star) = star_map.get(&to_id).cloned() else {
warn!("Smart gate has unknown target {}", gate.to);
continue;
};
let Some(from_star) = star_map.get_mut(&gate.from) else {
let Some(from_star) = star_map.get_mut(&from_id) else {
warn!("Smart gate has unknown source {}", gate.from);
continue;
};
Expand All @@ -141,7 +143,7 @@ fn main() -> anyhow::Result<()> {
id: conn_count,
conn_type: data::ConnType::SmartGate,
distance,
target: gate.to,
target: to_id,
});
conn_count += 1;
}
Expand Down
95 changes: 70 additions & 25 deletions backend/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,52 @@ use rkyv::{Archive, Deserialize, Serialize};
use crate::units::Meters;

pub type ConnectionId = u32;
pub type SolarSystemId = u32;

#[derive(
Debug,
Archive,
Deserialize,
Serialize,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Default,
serde::Serialize,
serde::Deserialize,
)]
#[archive(compare(PartialEq, PartialOrd))]
#[archive_attr(derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord))]
pub struct SolarSystemId(pub u32);

impl std::str::FromStr for SolarSystemId {
type Err = std::num::ParseIntError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(SolarSystemId::from(s.parse::<u32>()?))
}
}

impl std::fmt::Display for SolarSystemId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

impl From<u32> for SolarSystemId {
fn from(id: u32) -> Self {
SolarSystemId(id)
}
}

impl From<SolarSystemId> for u32 {
fn from(id: SolarSystemId) -> Self {
id.0
}
}

#[derive(Debug, Archive, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[rkyv(compare(PartialEq))]
Expand Down Expand Up @@ -107,11 +152,11 @@ impl Universe {
let json = star_map_json.solar_systems;
let star_id_to_name: HashMap<SolarSystemId, String> = json
.iter()
.map(|star| (star.solar_system_id, star.name.clone()))
.map(|star| (SolarSystemId(star.id), star.name.clone()))
.collect();
let star_name_to_id: HashMap<String, SolarSystemId> = json
.iter()
.map(|star| (star.name.clone(), star.solar_system_id))
.map(|star| (star.name.clone(), SolarSystemId(star.id)))
.collect();

Ok(Universe {
Expand Down Expand Up @@ -161,22 +206,22 @@ impl Universe {
*/
#[rustfmt::skip]
let stars = [
MockStar { id: 1, name: "A", x: 0.0, y: 0.0 },
MockStar { id: 2, name: "B", x: 10.0, y: 0.0 },
MockStar { id: 3, name: "C", x: 20.0, y: 0.0 },
MockStar { id: 4, name: "D", x: 10.0, y: 20.0 },
MockStar { id: SolarSystemId(1), name: "A", x: 0.0, y: 0.0 },
MockStar { id: SolarSystemId(2), name: "B", x: 10.0, y: 0.0 },
MockStar { id: SolarSystemId(3), name: "C", x: 20.0, y: 0.0 },
MockStar { id: SolarSystemId(4), name: "D", x: 10.0, y: 20.0 },
];

#[rustfmt::skip]
let conns = [
MockConn { conn_type: ConnType::NpcGate, s1: 1, s2: 4 },
MockConn { conn_type: ConnType::SmartGate, s1: 4, s2: 3 },
MockConn { conn_type: ConnType::Jump, s1: 1, s2: 2 },
MockConn { conn_type: ConnType::Jump, s1: 1, s2: 3 },
MockConn { conn_type: ConnType::Jump, s1: 1, s2: 4 },
MockConn { conn_type: ConnType::Jump, s1: 2, s2: 3 },
MockConn { conn_type: ConnType::Jump, s1: 2, s2: 4 },
MockConn { conn_type: ConnType::Jump, s1: 3, s2: 4 },
MockConn { conn_type: ConnType::NpcGate, s1: SolarSystemId(1), s2: SolarSystemId(4) },
MockConn { conn_type: ConnType::SmartGate, s1: SolarSystemId(4), s2: SolarSystemId(3) },
MockConn { conn_type: ConnType::Jump, s1: SolarSystemId(1), s2: SolarSystemId(2) },
MockConn { conn_type: ConnType::Jump, s1: SolarSystemId(1), s2: SolarSystemId(3) },
MockConn { conn_type: ConnType::Jump, s1: SolarSystemId(1), s2: SolarSystemId(4) },
MockConn { conn_type: ConnType::Jump, s1: SolarSystemId(2), s2: SolarSystemId(3) },
MockConn { conn_type: ConnType::Jump, s1: SolarSystemId(2), s2: SolarSystemId(4) },
MockConn { conn_type: ConnType::Jump, s1: SolarSystemId(3), s2: SolarSystemId(4) },
];

let mut star_map: HashMap<SolarSystemId, Star> = stars
Expand Down Expand Up @@ -245,14 +290,14 @@ mod tests {
#[test]
fn test_distance() {
let a = Star {
id: 1,
id: SolarSystemId(1),
x: 0.0,
y: 0.0,
z: 0.0,
..Default::default()
};
let b = Star {
id: 2,
id: SolarSystemId(2),
x: 1.0,
y: 0.0,
z: 0.0,
Expand All @@ -271,37 +316,37 @@ mod tests {
id: 1,
conn_type: ConnType::Jump,
distance: Meters::new(2.0),
target: 1,
target: SolarSystemId(2),
};
let b = Connection {
id: 2,
conn_type: ConnType::NpcGate,
distance: Meters::new(2.0),
target: 1,
target: SolarSystemId(1),
};
let c = Connection {
id: 3,
conn_type: ConnType::SmartGate,
distance: Meters::new(2.0),
target: 1,
target: SolarSystemId(1),
};
let d = Connection {
id: 4,
conn_type: ConnType::Jump,
distance: Meters::new(1.0),
target: 1,
target: SolarSystemId(1),
};
let e = Connection {
id: 5,
conn_type: ConnType::NpcGate,
distance: Meters::new(1.0),
target: 1,
target: SolarSystemId(1),
};
let f = Connection {
id: 6,
conn_type: ConnType::SmartGate,
distance: Meters::new(1.0),
target: 1,
target: SolarSystemId(1),
};
let mut conns = vec![
a.clone(),
Expand All @@ -318,11 +363,11 @@ mod tests {
#[test]
fn test_tiny_test_star1_sorting() {
let universe = Universe::tiny_test();
let star1 = &universe.star_map[&1];
let star1 = &universe.star_map[&SolarSystemId(1)];

// First connection should be the NPC gate to star 4
assert_eq!(star1.connections[0].conn_type, ConnType::NpcGate);
assert_eq!(star1.connections[0].target, 4);
assert_eq!(star1.connections[0].target, SolarSystemId(4));

// All NPC gates should come before all jumps
let mut seen_jump = false;
Expand Down